一.概述
数据库数据分片,分垂直分片和水平分片。由于大部分公司按照业务拆分事业部门和小组,所以天然就是垂直分片。
数据库数据垂直分片,单实例有性能瓶颈,后期只能通过水平分片提高数据处理能力。
数据库水平分片采用分库分表形式。分库还能够用于有效的分散对数据库单点的访问量。分库和分表均可以有效的避免由数据量超过可承受阈值而产生的查询瓶颈。
数据库水平分片,会增加数据实例数,减少单个实例单个库的压力,增加数据TPS操作能力,也能增加QPS操作能力,但QPS有NoSql等更好解决方案。且多库表复杂查询,排序,最后要做归并计算,归并计算节点性能不高,有可能一次查询比单库表慢。
数据库分库分表数量,一般都是2的倍数,阿里云RDS一个实例建议分库小于等于8个,一个分库的分表数量建议一百以内。具体实例数,分库分表数量,每个分表500万以内,预估2年内总数据量。
分库分表拆分函数(算法)和拆分键选择比较重要,一般根据应用对数据频繁操作情况决定。最好拆分键就是应用查询数据的条件,这样可根据拆分函数(算法)快速定位数据所在库表,不用路由全库表。如C端业务根据业务Code的查询比较多,做分库分表键比较好。如物联网数据根据时间查询比较对,那么选择时间分库分表就能提高操作效率。
分库分表后会产生一些问题,不是本文重点关注。
| 阿里云PolarDB-X | 京东ShardingSphere |
兼容SQL | 高度兼容MySQL协议和语法,但由于分布式数据库和单机数据库存在较大的架构差异,存在SQL使用限制。 | 全面支持DML、DDL、DCL、TCL和部分DAL。支持分页、去重、排序、分组、聚合、关联查询(不支持跨库关联)。 |
分布式事务 | 兼容Seata | 支持Seata柔性事务 |
读写分离(写及时读) | 支持,提供写及时读解决方案 | 支持,提供写及时读解决方案Hint读主库。 |
弹性伸缩(平滑扩容,热点问题) | 提供平滑扩容和热点问题工具。 | 临时地使用两个数据库集群,伸缩完成后切换的方式实现 |
二.分库分表策略,实例数,每个实例物理分库数,每物理分库物理分表数
- 计算前提
- 一个实例建议最多8个物理分库数
- 单个物理分表的容量不超过500万行
- 单一数据库实例的数据的阈值在 1TB 之内
- 预估1~2年内的数据增长量,得到总数据量
(二)计算物理分表数
物理分库上的物理分表数=向上取整(估算的总数据量/(实例数 x 物理分库数)/ 5,000,000)
若计算出的物理分表数等于1时,当前分库即可满足需求
若计算结果大于1,则建议既分库又分表,即每个物理分库上再创建多个物理分表
三.分库分表策略,拆分键和拆分函数(算法)选择
- 拆分键
拆分键选择决定数据路由效率。如查询条件带拆分键,可通过拆分函数(算法)快速定位数据所在库表,读取数据。如查询条件与拆分键无关,则需全库表扫描,性能比未分库分表前低。
所以拆分键选择要根据业务操作,选择大部分查询所使用关键字,比如主键ID,或者业务Code。其余频繁查询,或是转化成带拆分键索引条件查询,或者通过其他方式处理。
非拆分键查询处理
情况 | 处理方法 | 备注 |
可以转化成拆分键 |
|
|
转低峰时运行 | 某些操作可以转到低峰时操作 |
|
OLAP全表 | DTS数据到其他NoSql引擎处理 |
|
低频率查询 | 调用频率低,全实例全库全表扫描,也无太大影响,无需处理 |
|
- 分库和分表拆分函数(算法)
- 分库,分表函数(算法)将数据分片,支持通过 =、>=、<=、>、<、BETWEEN 和 IN 分片。
- 分库,分表可选择不同拆分键,不同函数(算法)。
- 分库和分表拆分函数
取模:根据数据量计算的表数和数据库数,确定模几。
哈希:
范围:日期。
不建议分库分表策略过于复杂(如多拆分键等)
四.分布式主键生成策略
自增ID(最常用),UUID,雪花算法。
建议使用自增ID
五.支持SQL情况
具体看你使用的中间件和数据库
六.分布式事务
支持XA,Seata。
七.读写分离
支持读写分离,支持写及时读。
八.弹性伸缩
- 普通伸缩
使用两个数据库集群,伸缩完成后切换的方式实现。
- 平滑扩容
- 判断是否需要平滑扩容
通过观察实例的三个指标进行判断:IOPS、CPU、磁盘空间。
- 扩容方法
一个实例变成两个实例,实例物理数据库减半。自动扩容需要专业工具。扩容需要在低峰期,业务有暂短停止。
- 热点问题
数据多存在热点问题,某些用户的数据被频繁操作,某些用户数据长时间不被访问。数据分片多为均匀分布,这就造成某个实例某个数据库某几张表承担大部分的压力,容易出现热点节点性能问题。
一般解决热点问题都是增加实例,进行二次分库分表。
九.不建议分库分表情况
- 数据量不大。
- TPS不高。
- 大量join查询,大量全表扫描,OLAP型业务。
十.TiDB