分库分表问题
分库分表-数据库瓶颈
分库分表,首先得知道瓶颈在哪里,然后才能合理地拆分(分库还是分表?水平还是垂直?分几个?)。
IO瓶颈、CPU瓶颈,都会导致数据库活跃连接数增加。
对于服务层,数据库连接少、甚至无连接可用,会产生大量超时报错
IO瓶颈
磁盘读IO瓶颈,热点数据太多,数据库缓存buffer pool 放不下,每次查询时产生大量io,降低查询速度 -> 分库 和 垂直分表。
网络IO瓶颈,请求的数据太多,网络带宽不够 -> 分库。
CPU瓶颈
SQL问题,如SQL包含join,group by,order by,非索引字段条件查询等,增加CPU运算的操作
- SQL优化,建立合适的索引
- 在业务Service层进行业务计算
单表数据量太大,查询时扫描的行太多,SQL效率低,CPU率先出现瓶颈。水平分表
分库分表
水平切分-分片架构
分库还是分表?
建议分库,而不是分表:
- 分表,公用一个数据库文件,仍然有磁盘IO 竞争
- 分库,将数据迁移到不同数据库实例,甚至数据库机器上,扩展性更好
水平切分算法:范围法、哈希法
1、水平分库-分片架构
数据量很大,单库容量成为瓶颈。线性提升数据库写性能,降低单库数据容量。
系统绝对并发量上来了,分表难以根本上解决问题,还没有明显的业务归属来垂直分库。
库多了,io、cpu 压力自然成倍缓解。
分片特点
以字段为依据,按照一定策略(hash、range等),将一个库中的数据拆分到多个库。
- 每个库 之间 不直接产生联系,不像主从间有binlog同步
- 每个库的结构一样;
- 每个库的数据都不一样,没有交集;所有库的并集是全量数据;
2、水平分表
以字段为依据,按照一定策略(hash、range等),将一个表中的数据拆分到多个表。
- 每个表的结构都一样;
- 每个表的数据都不一样,没有交集;所有表的并集是全量数据;
场景
系统绝对并发量没有上来
单表的数据量太多,影响了SQL效率,加重了CPU负担。
分析
表的数据量少了,单次SQL执行效率高,自然减轻了CPU的负担。
垂直切分
和业务结合比较紧密。
垂直分库
数据量、请求量,系统绝对并发量上来了,可以抽象出单独的业务模块。
以表为依据,按照业务归属不同,将不同的表拆分到不同的库。
- 每个库的结构都不一样;
- 每个库的数据也不一样,没有交集;所有库的并集是全量数据;
垂直分表
场景
系统绝对并发量没有上来
表的记录不多,但是字段多,热点数据、非热点数据在一起,单行数据所需的存储空间较大。
导致,buffer pool 缓存的数据行减少,查询时会去读磁盘数据,产生大量的随机读IO,产生IO瓶颈。
解决
以字段为依据,根据业务对数据进行垂直切分。
考虑属性 长度、访问频率 两个因素,将表中字段拆到不同的表(主表、扩展表)。
- 长度短,访问频率高,热点数据放一起,主表
- 长度长,访问频率低,非热点数据放一起,扩展表
长度短、访问频度高的属性,buffer pool能缓存更多的热点数据,命中率会更高,减少了随机读IO。
关联数据
拆了之后,要想获得全部数据就需要关联两个表来取数据。
千万别用join
join增加CPU负担
将两个表耦合在一起(必须在一个数据库实例上)。
在业务Service层做关联,分别获取主表、扩展表数据,然后用关联字段关联得到全部数据。
分库分表步骤
一、容量估算评估分库、分表个数
- 容量估算依据2点:现有数据、增长趋势,照着业务规划预估容量
二、选key(均匀)
- 数据量均匀
- 请求量均匀
三、分表规则(分库分表分片键的设计)
- range、hash、一致性hash、snowflake分片
四、执行(一般双写)
五、扩容问题(尽量减少数据移动)
分库分表问题
一、非partition key查询
基于水平分库分表,拆分策略为常用的hash法。
除了partition key,只有一个非partition key 作为条件查询
- 映射法
- 基因法
- 冗余法
二、非partition key跨库跨表分页查询问题
用NoSQL法解决(ES等)
三、跨节点聚合
四、跨节点join
五、扩容问题
六、分布式事务
2pc、3pc 对性能损耗大,可改用事务补偿机制。
水平扩容库,升级从库法
双倍扩容策略,减少数据迁移。无需停止应用服务器
有 2 个节点 A、B,双倍扩容至4 个节点
1)新增两个数据库 A2、B2 作为从库,设置主从同步关系:A=>A2、B=>B2,主从数据同步
2)调整分片规则
- 原 id%2=0 => A 改为 id %4=0 => A,id%4=2 => A2
- 原 id%2=1 => B 改为 id %4=1 => B, id%4=3 => B2
3)解除主从同步关系
四个节点的数据都已完整,只是有冗余(多存了和自己配对的节点的那部分数据),择机清除。
2的幂和数据迁移
容量规划按照2的幂来规划的,扩容的时候,也按照2的幂进行的
基本扩容都选择容量翻倍
2的特性,哈希取余,可以使用位运算来计算余数,高效。
扩容为原来的2倍,只需要迁移一半的数据。
100亿数据迁移执行流程
大概有10个步骤:
1、 环境准备:线上库配置完成
2、 全量同步:数据迁移工具上新建2张表(积分表、明细表)的全量任务
3、 增量同步:全量迁移完成后开启增量(自动回溯全量开始时间,消息多次消费会进行幂等)
4、 数据校验:全量数据校验,查看数据是否一致
5、 切流测试:改造代码预发测试(采集线上流量进行回放,多种case跑一下,切流开关等校验),没问题发布上线
6、 二次校验:再次全量进行校验&订正(数据追平)
7、 开启双写:打开双写(保证数据实时性)既写老库,又写新库
8、 开启读灰度:低峰时段,进行灰度切流userId%x,进行验证,逐步流量打开,持续观察
9、 只写新库:写流量切到新库,只写新库,不写老库。完成数据迁移方案
10、 迁移完成:系统稳定运行一段时间,迁移&双写代码下线,老库进行资源释放
浙公网安备 33010602011771号