分库分表
随着互联网业务的快速发展,传统单体数据库面临以下挑战:
-
数据量爆炸
- 单表存储能力有限(如MySQL单表建议不超过2000万行)。
- 大表导致索引膨胀,查询性能急剧下降(B+树深度增加)。
-
高并发压力:数据库往往是系统的性能瓶颈;
- 单库的读写能力成为瓶颈(如MySQL QPS通常不超过5k);
- 单表内锁竞争加剧(如行锁、表锁、页锁);
- 单库的数据库连接数有限;
-
可用性风险
- 单点故障可能导致整个系统不可用。
- 备份与恢复时间随数据量增长而增加。
-
成本优化:对于流水表,随着时间增长,旧数据的读写需求几乎没有,那么冷热数据就可以降低成本压力;
典型场景:电商订单表、支付流水表、社交网络动态等高频写入与海量数据场景。
拆分方案
1. 垂直拆分
垂直拆分:按照业务拆分,不同的业务字段,拆分到不同的表;
通常在微服务的架构中,不同的业务之间本身就是相对比较独立的,天然就是业务数据的垂直拆分;通常需要垂直拆分,也就意味着服务的拆分;
2. 水平拆分
垂直拆分:同样的业务由于数据增量大,单表容量有限,此时需要水平拆分,不同的表的数据结构是一致的;
当下的互联网业务体量大,一般在业务初期就需要对数据量有一个预估,提前规划好库表数量、分片键规则;
分片策略
1. 范围分片
Range-based sharding divides data according to a certain range of data. For example, in a database that stores user order information, range sharding can be done according to the order date. Orders within a certain date range are stored in a shard.
范围分片根据数据特定的范围进行分片 比如,一个存储用户订单的数据库,可以根据订单日期进行范围分片,在一个特定范围内的订单存储在特定的分区
2. 哈希分片
Hash sharding determines the shard where the data is stored by performing a hash operation on a certain key attribute of the data (such as user id, order id, etc.)
Hash sharding can make the data distribution relatively even and reduce the problem of hot-spot data, because hash function tries to ensure that the amount of data received by each shard is similar.
哈希分片通过对一个特定的属性进行hash操作,确定数据所处的分片 哈希算法可以使数据分布均匀,减少热点问题,因为hash函数可以尽量保证每个分片的数据相近
3. 业务属性分片
对于ToB业务,可以直接按照企业属性分片,比如企业Id;(钉钉、飞书等)
对于ToC业务,可以按照用户属性userId分片;
基因分片:分片键关联多个业务属性,根据某一个id的基因片段,生成另一个id;如根据userId的某8位,生成该用户的订单id,那么同一个用户的订单就可以路由到同一个分片;
分片技术方案
- 客户端方案;在JDBC驱动层完成分片逻辑,轻量级;一般需要接入客户端SDK;
- 代理模式:在服务和数据库间加一层代理,由代理路由,执行;业务无侵入;
- 云原生方案;
分库分表的设计思路
1. 业务预期数据量
如果是在分库分表的设计初期,需要考虑2件事:
- 数据量:首先是需要对业务的大致增量有一个预期,对于MySQL单表通常小于2000w的数据量;
- 并发量:通常数据库往往会成为业务性能的瓶颈,所以还需要对业务的并发量有一个预估;
比如1天500w增量数据,1年就有
每张表按照1000w数据量,那么只需要500张表,按照500w的数据量,则需要1000张表;
表的数量又会影响:数据库的并发性能;如果按照1000张表规划,可以取1024张表,分为
2. 数据路由
对于订单业务,最方便就是根据订单orderId进行
但是在订单业务中,按照用户id进行搜索的场景也需要考虑;那么有什么设计方案:
- 基因算法,每个订单的创建都通过userId中的基因片段拼接到订单id中,保证同一个用户的订单都能够路由到同一张表;
- 订单ID = 时间戳(41bit) + 用户ID基因(4位) + 自增序列(19bit)
- 分片键 = 订单ID中的用户基因片段+订单ID
- 搜索引擎:数据冗余到搜索引擎,来获取用户的所有订单;
3. 数据的冷热分离
随着业务发展,数据并不都是热点数据,比如订单数据,2年以上的订单几乎没有访问量,可以进行冷热分离;
热数据保留1年~2年,之后数据迁移到冷库(历史库),冷库数据再超过2年,可以归档到更便宜的存储,甚至是文件;
订单这类业务通常是按照时间查询,那么业务上需要根据这个特性来指定不同的存储来查询;
为什么还需要分布式数据库
企业数据存量大、增量大的解决方案:分库分表和分布式数据库;
分库分表优缺点: