mysql分库分表方案浅析

来源:互联网 发布:更新ios6的软件 编辑:程序博客网 时间:2024/06/05 23:54

分库分表(这里不讨论中间件)

分库:原因:单机负载高,优点:降低单机负载
分表:原因:单表读写压力大或者数据增长快,优点:使用多个表,提高读写效率
1、(代码)分表,即把一个很大的表达数据分到几个表中,这样每个表数据都不多。
                 优点:提高并发量,减小锁的粒度
                 缺点:代码维护成本高,相关sql都需要改动

2、(mysql)分区,所有的数据还在一个表中,但物理存储数据根据一定的规则存放在不同的文件中,文件也可以放到另外磁盘上
                    优点:代码维护量小,基本不用改动,提高IO吞吐量
                    缺点:表的并发程度没有增加



分表
在一个库中进行进行分表,有两种方法
1、mysql表分区(推荐)
使用表分区时,分区字段。需要根据业务来定,这里所说的业务,指的就是需要做分表的表会和哪些业务相关,
比如订单表,主键是订单ID,分表时,需要结合业务综合看待。
单纯就技术看:
如果按订单ID进行hash,操作分布多个表,但是在拓展时,就很麻烦
如果按订单ID进行范围range,操作集中某几个表,拓展时,很方便
综合结合看:
a,当业务需要根据时间来查询
如果按订单ID进行表分区,那么会造成查询无法走索引,导致全表扫描,效率低下,
如果按时间ID进行表分区,查询会走索引,但是时间都是按范围range,操作会集中几个表,读写压力就很明显
b,当业务需要查询用户某一时间段的订单
c,当业务需要.....
需要把所有业务都考虑进去

2、分表
分表的做法和表分区相同,不同的是需要在代码中实现这个功能。做法是先建立分表,然后在程序中写分表代码逻辑。
比如需要对订单表分表,代码中就会按订单ID(也可以任何字段)进行范围、或者hash取余计算该订单ID所处于的表,如果使用hash,可以使用一致性hash分表,避免hash取模方式在表增删时迁移全部数据。
同样,分表也需要集合业务,而且更加麻烦
单纯就技术看:
如果按订单ID进行hash,操作分布多个表,但是在拓展时,就很麻烦,需要把原来的数据再重新导入所有节点,这里很消耗时间,关键是导致系统很长的不可用时间
如果按订单ID进行范围range,操作集中某几个表,拓展时,很方便
这里和表分区的技术优缺点相同。
综合结合看:
a,当业务需要根据时间来查询
如果按订单ID进行表分区,无论是范围,还是Hash,都无法根据时间进行查询,只有全表扫描
如果按时间ID进行表分区,基本是按范围分表,可以定位时间范围。但是业务肯定会用订单ID来查询,而代码是根据时间ID做范围分表,等于说根据订单ID查询的业务就不可用了。
b,当业务需要查询用户某一时间段的订单
c,当业务需要.....
需要把所有业务都考虑进去


从这里可以看到,单纯做库内的分表,mysql自带的表分区适应度更高,分表的做法只适合于没有复杂的业务、多维度的查询。
一定要和业务结合起来,不然会遇到分了表后,业务无法运行的尴尬场面。

分库
在数据库中进行进行分库,有两个办法
1、代码分库
在代码中进行范围、或者hash取余计算该订单ID所处于的库,如果使用hash,最好是一致性hash分库,避免hash取模方式在节点增删时迁移全部数据。
单纯就技术看:
优点:计算简单,
缺点:增删库时,需要修改代码,并且需要迁移数据
2、单独建库建表,存放数据对应位置
单纯就技术看:
优点:可拓展性强
缺点:多次查询,效率低下,数据是否迁移看业务

综合结合看:
无论代码分库还是表存放位置,都存在跨库查询,已经分布式事务的问题,这里一定要综合业务,梳理流程,避免分布式事务。

分库分表
在数据库中进行进行分库分表,有两个办法
1、代码分库
a、代码分库+表分区
像这种组合的分库,一定要考虑到后期拓展的问题,如果是按范围,就没问题,直接增库,如果是按hash,就需要把所有的数据全部导出,再导入,时间代价很大。
优点:只需一层计算数据位置,表分区管理简单
缺点:需要迁移数据时,表分区较麻烦
这里没有写一致性hash分库+表分区,因为组合不能起到应有的效果。例如,分库使用一致性Hash,而表分区是hash,两边的算法不一致,数据无法对应, 就只能全部迁移了。
b、代码分库+分表
一种是hash分库 + hash分表,这个方法和上面的a方法相比,拓展时的都存在数据迁移时间过长,不同的是,a方法的表分区管理起来更简单。
一种是一致性hash分库 + 一致性hash分表,相比较,一致性Hash不易理解,有难度,迁移需要玩完备的方案,很繁琐,但是拓展时,只需要迁移部分数据即可。
优点:自由度高
缺点:多层计算,维护难度大
这里没有写一致性hash和hash分表的组合,因为一致性hash要求算法一致。如果算法不同,在数据迁移时,很可能就会迁移全部数据,甚至数据混乱。
2、建库建表,存放数据对应的DB位置和表位置
注意:
分库分表中可能遇到跨库查询或者分布式事务的问题,比如用户ID为1的数据在库A,用户1的订单数据在库B,可以将用户1的关联订单数据在插入时选择用户1所在的库A,这样就能避免分布式查询和事务的问题。

来源:http://blog.csdn.net/stubborn_cow/article/details/50781310

原创粉丝点击