分库分表
基本概念
- 分库分表就是按照一定的规则,对原有的数据库和表进行拆分,把原本存储于一个库的数据分块存储到多个库上,把原本存储于一个表的数据分块存储到多个表上。
- 随着时间和业务的发展,数据库中的数据量增长是不可控的,库和表的数据会越来越大,随之带来的是更高的磁盘IO、系统开销,甚至性能上的瓶颈,而一台服务的资源终究是有限的,因此需要对数据库和表进行拆分,从而更好的提供数据服务。
切分类型
垂直(纵向)切分
垂直分库
- 根据业务耦合性,将关联度低的不同表存储在不同的数据库。
- 做法与大系统拆分为多个小系统类似,按业务分类进行独立划分。
- 与”微服务治理”的做法相似,每个微服务使用单独的一个数据库。
垂直分表
- 基于数据库中的”列”进行,某个表字段较多,可以新建一张扩展表,将不经常用或字段长度较大的字段拆分出去到扩展表中。
- 在字段很多的情况下(例如一个大表有100多个字段),通过”大表拆小表”,更便于开发与维护,也能避免跨页问题。
- MySQL底层是通过数据页存储的,一条记录占用空间过大会导致跨页,造成额外的性能开销。
- 另外数据库以行为单位将数据加载到内存中,这样表中字段长度较短且访问频率较高,内存能加载更多的数据,命中率更高,减少了磁盘IO,从而提升了数据库性能。
优点
- 解决业务系统层面的耦合,使业务清晰。
- 与微服务的治理类似,也能对不同业务的数据进行分级管理、维护、监控、扩展等。
- 高并发场景下,垂直切分能一定程度的提升IO、数据库连接数、单机硬件资源的瓶颈。
水平(横向)切分
将某张访问非常频繁的表,按照某个特定的规则(通常是某个字段进行hash),然后将数据分散到多个表,甚至是多个数据库中,这样每张表或者每张库都含有一部分数据。
优点
- 不存在单库数据量过大、高并发的性能瓶颈,提升系统稳定性和负载能力。
- 应用端改造较小,不需要拆分业务模块。
缺点
- 跨分片的事务一致性难以保证。
- 跨库的join关联查询性能较差。
- 数据多次扩展难度和维护量极大。
数据分片规则
中间件
分片方法
范围切分
- 比如说按照时间范围和ID的范围来进行切分。
- 按日期将不同月甚至是日的数据分散到不同的库中;将userId为1 ~ 9999的记录分到第一个库,10000 ~ 20000的分到第二个库,以此类推。
优点
- 单表大小可控
- 天然便于水平扩展,后期如果想对整个分片集群扩容时,只需要添加节点即可,无需对其他分片的数据进行迁移
- 使用分片字段进行范围查找时,连续分片可快速定位分片进行快速查询,有效避免跨分片查询的问题。
缺点
- 热点数据成为性能瓶颈。连续分片可能存在数据热点,例如按时间字段分片,有些分片存储最近时间段内的数据,可能会被频繁的读写,而有些分片存储的历史数据,则很少被查询。
Hash划分
一般使用取模运算来进行切分,也就是Mod切分
- 基本取模
- 直接Mod 4,分配到4个库/表
- 扩容有比较大的问题
- 取模+范围
- Mod 1024,每256分配一个库/表
- 扩容只迁移部分分片数据,可以做大小区划分
- 一致性Hash
上面的方案是其中的一个特例
优点
- 数据分片相对比较均匀,不容易出现热点和并发访问的瓶颈。
缺点
- 后期分片集群扩容时,需要迁移旧的数据(使用一致性hash算法能较好的避免这个问题)。
- 容易面临跨分片查询的复杂问题。 如果频繁用到的查询条件中不带sharding key时,将会导致无法定位数据库,从而需要同时向多个库发起查询,再在内存中合并数据,取最小集返回给应用,分库反而成为拖累。
范围+Hash
- 先按范围分片,再按Hash
- 兼顾扩容+数据均衡
查询划分
增加映射表
分区字段选择
- 采用多字段分区
评估原则
- 是否要分片?
- 数据容量是否均匀,是否有数据倾斜?
- 数据访问是否均匀,是否有热点数据?
- 扩容是否方便,是否需要数据迁移?
- 业务改造是否工作量大,是否较大业务侵入性?
- 范围查找/统计是否跨分片?
- 关联查找是否跨分片?
潜在问题
事务问题
当更新内容同时分布在不同库中,不可避免会带来跨库事务问题.
方案
- 分布式事务
- 由应用程序和数据库共同控制
- 事务补偿
跨节点Join问题
只要是进行切分,跨节点Join的问题是不可避免的。
方案
- 全局表,每个库都存储一份
- 字段冗余
- 多次查询,数据组装
- ER分片(有关联的数据分配到用同一个分片)
数据迁移,容量规划,扩容等问题
主键ID问题
- 一旦数据库被切分到多个物理结点上,我们将不能再依赖数据库自身的主键生成机制
- 方案参考分布式ID
跨分片的排序分页
方案
- 如果是在前台应用提供分页,则限定用户只能看前面n页,这个限制在业务上也是合理的,一般看后面的分页意义不大(如果一定要看,可以要求用户缩小范围重新查询)。
- 分库设计时,一般还有配套大数据平台汇总所有分库的记录,有些分页查询可以考虑走大数据平台。