对于分库分表,可能很多人比较熟悉了,因为,一般来说,在很多时候,系统中某一模块数据量很大的情况下,对应表单就特别需要做分表操作,当然也包括分库操作。
在进入到本次主要内容之前,现简单介绍下分库分表的中间件:
目前市面上MySQL分库分表中间件还是很多的,主要分为两大类:应用层依赖类中间件(比如shardingsphere-jdbc)、中间层代理类中间件(比如shardingsphere-proxy)。
应用层依赖类中间件
即中间件在数据库连接库基础之上,增加了一层封装。我们使用时,以shardingsphere-jdbc为例,需要先引入一个jar包。中间件接收持久层产生的sql,同样对sql进行分析等操作,然后才落实到具体的库上。
优点:性能损耗低(直连数据库),去中心化(每个Application使用各自的分库分表库)。
缺点:异构语言不是很友好,连接数高(每个Application都要与数据库建立连接)。
中间层代理类中间件
即把中间件作为一个独立的服务,它将接收到的SQL 语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此 SQL 发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
优点:异构语言友好,连接数低(只需proxy与数据库建立连接)。
优点:性能损耗略高(需要proxy转发去连数据库),中心化(proxy需要集群部署,运维难度增加)。
现在常见的分库分表中间件很多,但是国内主要是mycat和shardingsphere,相较而言,shardingsphere已经是Apache顶级项目,维护稳定,功能齐全,支持云原生,更值得学习。
如上基本是当前国内主流的处理分库分表的中间件。
我们言归正传,那么,在实际情况中分表的数量都会选择2的幂,比如16、64、128、512、1024等,那么,这么做有什么好处吗或者有哪些特别的考虑?本篇文章,我们就好好说一下这个问题。
首先,如果你看过 HashMap 的 hash 算法的话,应该知道,HashMap 的容量其实也是2的幂,这么做的好处在下面的文章中讲过,那就是可以讲取模操作改为更加高效的位运算。
因为,hash % 8 相当于 hash & (8-1),所以对于分8个表,可以使用哈希值与7进行按位与操作,这不仅简化了计算,还提升了性能。
所以,使用2的幂作为分表数量的第一个好处,就是可以将取模算法优化成位运算算法。
除了这个好处以外,我们通常分表都是伴随着分库的,比如我们分16个库128张表, 这样如果我们的分表数量和分库数量都是2的幂,那么就可以实现均匀分布。128张表就可以均匀的分到16个库中,每个库中有8张表。
所以,使用2的幂作为分表数量的第二个好处,就是可以使得多张分表在多个库中均匀分配。
当我们在做分库分表的时候,必然要考虑的一个问题那就是二次分表的问题,比如我们根据当前的业务发展,计算出可能需要分4张表就够了,但是随着业务增长,可能认为需要更多表才行,这时候如果我们把新的分表数量定位8张表,那么在做数据迁移的时候,就可以只迁移部分数据。
假设我们最开始将订单表分成了4张表,分别是 order_00、order_01、order_02、order_03,这时候假设我们的分表算法是根据 userId取模。即 userId % 4
order_00:userId % 4 == 0
order_01:userId % 4 == 1
order_02:userId % 4 == 2
order_03:userId % 4 == 3
当数据量增长,需要将表扩展到8个时,需要将算法改为userId % 8 :
新的哈希值计算:
order_00:userId % 8 == 0
order_01:userId % 8 == 1
order_02:userId % 8 == 2
order_03:userId % 8 == 3
order_04:userId % 8 == 4
order_05:userId % 8 == 5
order_06:userId % 8 == 6
order_07:userId % 8 == 7
而在做储量数据迁移的时候,我们只需要重新分配那些原来在表0、1、2、3中,且哈希值满足 userId % 8 >= 4 的数据进行迁移就好了,userId % 8 的结果在0-3范围内的数据其实是不用动的。
从表0迁移到表4:如果 hash % 8 == 4
从表1迁移到表5:如果 hash % 8 == 5
从表2迁移到表6:如果 hash % 8 == 6
从表3迁移到表7:如果 hash % 8 == 7
也就是说,从4张表扩容到8张表其实只需要迁移一半的数据。而如果不是2的幂,比如说从5张表扩容成9张表,那每个原数据都需要重新计算哈希值并重新分配到新的表中。因为扩展后的表数量不是2的幂次,大多数数据都会被重新分配到不同的表中。
所以,使用2的幂作为分表数量的第三个好处,也是最重要的一个好处,那就是在做数据迁移时只需重新计算和迁移一半数据。这种方法不仅降低了系统扩展的复杂性,还减少了扩展过程中对系统性能的影响。
还没有评论,来说两句吧...