业务从0到1后,就需要做量迸发技术储备。最近研究了大众点评的订单系统分库分表实践,做下笔记深入理解,以备后用。
分库分表主要分两大类:
垂直切分
垂直切分是最好理解的,可以简单理解为把所有的表按照模块划分(或者将表的字段拆分),然后将不同的模块放到不同的数据库中,从而减轻重要表的数据库压力。
借鉴图水平切分
水平拆分主要解决单表的数据量过大,从导致DDL吃力。水平拆分可以理解为将单表的数据分开放到多个表中,从而减少单表的数据量。水平拆分需要根据不同的业务来设计,举例来说,计费系统可能一般通过时间切分,因为用户数据跟时间关联紧密;再比如Saas应用,一般使用用户维度进行切分,因为用户之间是隔离的。水平切分后一定要注意join问题。
切分策略
1. 查询切分
将ID和库的关系记录单独放到一个库中,优点是ID和库的关系可以随意更改,缺点就是存在单点问题。
借鉴图2.范围切分
将ID根据时间区间划分,优点是单表大小可控,缺点是存在集中写入瓶颈。
3.Hash切分
一般采用mod方式切分:mod 2^n 方式切分,易于拓展。
每个集群4个库大众点评中订单库切分采用了32*32的方式,通过用户UserId的后四位mod 32 分到32个数据库中,然后再DIV 32 再 mod 32 分到32个表中,从而有32*32=1024个表,从而将数据分发到1024个表中。原设计为8个集群,每个集群4个数据库,共计32个数据库。
这里用后四位做运算也有考究,大众点评订单表的UserId 生成方式是:
时间戳 + 用户标志码+4位随机数
时间戳是方便按照时间排序,后四位随机就方便将数据随机的分到不同的数据库表中,从而达到数据量的均匀。所以数据库key的设计也非常重要。
提供两个场景:
数据库性能达到瓶颈
方法一: 还是按照mod 切分方式,但是不再是1个集群4个数据库,而是使用1个集群1个数据库。这样就是32个集群,性能自然会高很多。
上方是旧的,下方是新的,即每个集群一个库方法二:同样按照mod 切分方式,将每个库的32个表拆分出来,每个表做一个集群,从而达到32*32 共计1024个集群。
将每个库的表单独拆成库数据库单表的量达到瓶颈
这种比较少见,毕竟1024个集群的量已经很高了。这种情况采用的是32*(32*2^n)方式,比如在最终的分库中对单表再进行一次切分,根据Userid 来DIV 32 Mod 32 后再进行Mod 2,即将数据表再一分为二。
1024库中的表再进行切分
网友评论