你好,欢迎进入江苏优软数字科技有限公司官网!

诚信、勤奋、创新、卓越

友好定价、专业客服支持、正版软件一站式服务提供

13262879759

工作日:9:00-22:00

水平分库分表的关键问题及解决思路

发布时间:2023-07-03

浏览次数:0

上一篇文章介绍了分库分表的几种表达方式和玩法,也重点介绍了垂直分库带来的问题和解决技巧。 本篇我们就来说说水平分库分表的一些技巧。

1、分片技术的由来 关系型数据库本身就比较容易成为系统性能的困境。 单机的存储容量、连接数、处理能力都非常有限。 数据库本身的“有状态性”使得它不同于Web和应用服务器那么容易扩展。 在互联网行业海量数据、高并发访问的考验下,聪明的技术人员提出了分库分表技术(有的地方称之为分片)。 同时,流行的分布式系统中间件(如等)都是自己友好且支持的,其原理和思想都与邯郸不同。 2、分布式全局唯一ID 在很多中小型项目中,我们经常直接利用数据库自​​增功能来生成字段ID,确实比较简单。 但在分库分表的环境下,数据分布在不同的分片上,不能利用数据库的自减特性直接生成数据,否则不同分片上的数据表字段会重复。 简单介绍一下使用和理解的几种ID生成算法。 1.(也称为“雪花算法”)

2. UUID/GUID(通常应用程序和数据库都支持)

3.(类似于UUID)

4.(数据库生存方法,这些方法都用到)

3. 如何选择常用分片规则和策略分片数组

在开始分片之前,我们首先需要确定分片数组(也称为“分片键”)。 在很多常见的情况和场景中,都会使用ID或者时间数组来进行分割。 这并不是绝对的。 我的建议是结合实际业务,通过对系统中执行的sql语句进行统计分析,选择表中最常用或者最重要的需要分片的数组作为分片数组。

常见的分片规则

常见的分片策略有随机分片和连续分片,如右图所示:

分治法解决凸包问题_intellij idea 数据库关系图_语数英学业水平分数线

当需要使用分片数组进行范围搜索时,连续分片可以快速定位分片进行高效查询,并且大多数情况下可以有效防止跨分片查询的问题。 以后如果要扩展整个分片集群,只需要增加节点即可,不需要迁移其他分片的数据。 而且intellij idea 数据库关系图,连续分片还可能存在数据热点的问题。 例如图中按时间字段分片的情况,部分节点可能会被频繁查询和压力,热点数据节点就会陷入困境。 并且有些节点可能会存储历史数据,很少需要查询。

随机分片虽然不是随机的,但也遵循一定的规则。 一般我们会采用Hash取模的方法进行分片和分裂,所以有时也称为离散分片。 随机分片的数据比较均匀,不易出现热点和并发访问。 而且后期分片集群的扩容需要旧数据的迁移。 只有使用一致性Hash算法才能很大程度上避免这个问题,所以很多中间件分片集群都使用一致性Hash算法。 离散分片也容易出现跨分片查询的复杂问题。

数据迁移、容量规划、扩容等问题

很少有项目在早期就开始考虑分片设计,通常是在业务快速发展,面临性能和存储困难的时候,才会提早规划。 为此,不可避免地要考虑历史数据迁移的问题。 通常的做法是先通过程序读取历史数据,然后根据指定的分片规则将数据写入到各个分片节点。

据悉,我们需要根据当前的数据量和QPS进行容量规划,并根据成本因素估算出大概需要的分片数量(一般建议单个分片上单表的数据量应该是不超过1000W)。

如果采用随机分片,则需要考虑后期的扩容,相对来说会比较麻烦。 如果使用范围分片,则只需添加节点即可手动扩容。

4. 跨分片技术问题 跨分片排序与分页

一般来说,分页需要按照指定的数组进行排序。 当排序后的数组是切片数组时,我们可以很容易地通过切片规则定位到指定的切片,但是当排序后的数组不是切片数组时,情况会显得更加复杂。 为了最终结果的准确性,我们需要对不同分片节点上的数据进行排序返回,对不同分片返回的结果集进行汇总重新排序,最后返回给用户。 如右图所示:

语数英学业水平分数线_分治法解决凸包问题_intellij idea 数据库关系图

里面的图片描述的只是最简单的情况(取第一页的数据),看起来影响不大。 而且,如果要检索第10页的数据,情况就会复杂很多,如右图所示:

分治法解决凸包问题_语数英学业水平分数线_intellij idea 数据库关系图

有些读者可能不太明白为什么不能像获取第一页数据那样简单处理(排序并取出前10条后再进行合并排序)。 看起来也不难理解,由于每个分片节点中的数据可能是随机的,为了排序的准确性,必须对所有分片节点的前N页数据进行排序并合并,最后进行整体排序。 事实上,这样的操作是比较消耗资源的,而且用户翻页越远intellij idea 数据库关系图,系统性能就越差。

跨分片的函数处理

使用Max、Min、Sum、Count等函数进行统计和估算时,需要先对每个分片数据源进行相应的函数处理,然后对每个结果集进行二次处理,最后返回处理结果。 如右图所示:

语数英学业水平分数线_intellij idea 数据库关系图_分治法解决凸包问题

跨分片加入

Join是关系型数据库中最常用的功能,而在分片集群中,Join也非常复杂。 应尽可能避免跨分片联接查询(这些场景比之前的跨分片分页更复杂,但对性能影响很大)。 一般来说,有以下几种方法可以预防:

全局表

全局表的概念之前在“垂直分库”中提到过。 基本思想是一样的,就是在每个分片中放入一些类似于数据字典的、可能形成联接查询的表信息,从而防止跨分片联接。

内质网碎片化

在关系数据库中,表之间常常存在一些关联关系。 如果我们能够先确定关联关系,并将这些具有关联关系的表记录存储在同一个分片上,那么就可以防止跨分片连接的问题。 在一对多关系的情况下,我们一般选择按照数据较多的一侧进行拆分。 如右图所示:

intellij idea 数据库关系图_语数英学业水平分数线_分治法解决凸包问题

这样中的订单表和明细订单表就可以直接关联起来进行部分连接查询,上也是如此。 这些基于ER分片的方法可以有效防止大多数业务场景下的跨分片连接问题。

内存估计

随着Spark内存估算的盛行,理论上来说,很多跨数据源的操作问题似乎都能得到解决。 可以将数据丢给spark集群进行内存估算,最后返回估算结果。

5. 跨分片交易问题 跨分片交易也是分布式交易。 如果想了解分布式事务,就需要了解“XA套接字”和“两阶段提交”。 值得一提的是,.5x和5.6x中的xa支持是有问题的,会导致主从数据不一致。 直到 5.7x 版本才修复。 Java应用程序可以使用该框架来实现XA事务(J2EE中的JTA)。 有兴趣的读者可以参考《分布式事务一致性解决方案》,链接地址:

6、我们的系统真的需要分库分表吗?

虽然这一点没有明确的判断标准,但更多地取决于实际业务情况和经验判断。 根据笔者的个人经验,MySQL单表1000W左右的数据通常是没有问题的(前提是应用系统和数据库的设计和优化比较好)。 事实上,不仅是在考虑当前的数据量和性能时,作为架构师,我们需要提前考虑系统半年到一年左右的业务衰退情况,对QPS做出合理的评估和规划,连接数、数据库服务器的容量,提前做好准备。 如果单台机器很难满足,又很难从其他方面去优化,就意味着需要考虑碎片化。 在这种情况下,可以先删除数据库中的自增ID,以便及早做好分片和相邻数据迁移的计划。

很多人认为“分库分表”宜早不宜迟,因为担心公司业务发展得更快,系统变得越来越复杂,系统建设和扩展会更加困难……这样的说法听起来很有道理。 这是有道理的,但我的观点恰恰相反。 对于关系型数据库,我认为“不能分片就不分片”,除非系统确实需要,因为数据库分片并不是低成本或者免费的。

这里我推荐一种更靠谱的过渡技术——“表分区”。 主流关系数据库基本都支持。 逻辑上,不同的分区仍然是一张表,但在数学上是分开的,这可以在一定程度上提高查询性能,并且对应用程序是透明的,无需更改任何代码。 作者一开始负责优化一个系统。 主业务表有8000W左右的数据。 考虑到成本问题,通过“分表”的方式来完成。

7.总结 最后,很多读者想知道当前社区是否有开源免费的分库分表解决方案,虽然站在巨人的右臂可以省去不少力气。 目前解决方案主要有两类:

1、基于应用层的DDAL(分布式数据库访问层)

比较典型的有天猫的半开源TDDL,当当网的开源JDBC。 分布式数据访问层不需要硬件投入,技术能力较强的大公司一般选择自行开发或参考开源框架进行二次开发和定制。 通常对应用程序更具侵入性,从而降低技术成本和复杂性。 一般只支持特定的编程语言平台(多为Java平台),或者只支持特定的数据库和特定的数据访问框架技术(通常支持MySQL数据库、JDBC、.NET等框架技术)。

2、数据库中间件,典型的如mycat(在阿里开源cobar的基础上做了很多优化和改进,是后起之秀,也支持很多新特性),基于Go语言实现,相对来说老Atlas(360开源)等等​​。 这种中间件在互联网企业中应用广泛。 另外,MySQL 5.x企业版中官方提供的组件也可以说支持分片技术,但国外很少有公司使用。

中间件也可以称为“透明网段”,大名鼎鼎的大概就是这个领域的鼻祖了(MySQL官方提供,仅限于实现“读写分离”)。 中间件通常实现特定数据库的网络通信契约,模拟真实的数据库服务,屏蔽前端真实的服务。 一般情况下,应用程序可以直接连接中间件。 在执行SQL操作时,中间件会根据预定义的分片规则对SQL语句进行分析和路由,并对结果集进行重新评估,最后返回结果集。 引入数据库中间件的技术成本较低,而且对应用程序几乎没有侵入,可以满足大多数业务。 减少额外的硬件投资和运维成本。 同时,中间件本身也存在性能困难和单点故障问题。 需要保证中间件本身的高可用性和可扩展性。

事实上,无论是使用分布式数据访问层还是数据库中间件,都会带来一定的成本和复杂度,同时也会产生一定的性能影响。 因此,读者需要根据实际情况和业务发展需要仔细考虑和选择。

最近热门读物:

1、

2、

3.

4.

5.

6.

7.

8、

9、

10.

如有侵权请联系删除!

13262879759

微信二维码