Cetus中间件通过将数据分片,将数据分散到多个主机和实例上,突破单主机和单MySQL实例的限制,以面对不断增加的业务负载和数据,提供了数据库无限扩展的可能性。业务上线初期,根据两个因素决定分片节点的初始数量:业务的发展趋势、资源成本与性能的均衡。随着业务的发展,初期规划的分片数量如不能支撑业务请求的负载或者现有主机资源不足,就要提前规划扩容。
中间件集群扩容指的是增加后端节点,数据重新分布到新的后端节点,以达到扩容的目的。
建议成倍扩容,例如2节点扩容成4节点,4节点扩容成8节点。
选取扩容方案有几个考虑:
1)方案的复杂度
2)对线上环境影响程度
3)扩容过程可控性
4)扩容回退方案
综合考虑,选取了一个可行的扩容方案。下面用2节点的hash分片环境扩容到4节点为例详细介绍扩容方案。
tip:用hash算法将分片字段的值转换为一个极大的整数,把这个整数对另外一个整数x取余,得到余数y。x就是数据桶的总数,y是这条记录落到的桶数,桶的值范围是[0..x-1]
扩容前架构
集群有groupA和groupB分片。分片一共有8个桶:0,1,2,3桶对应数据在groupA,4,5,6,7桶的数据在groupB。分片的sharding.json配置如下:
{
"id": 1,
"type": "str",
"method": "hash",
"num": 8,
"partitions": {"groupA": [0,1,2,3], "groupB": [4,5,6,7]}
}
]
从2节点扩容成4节点,进行数据库水平扩容。
扩容后架构
将groupA节点数据放到groupA1和groupA2节点,将groupB节点数据放到groupB1和groupB2节点。扩容后分片的sharding.json配置如下:
{
"id": 1,
"type": "str",
"method": "hash",
"num": 8,
"partitions": {"groupA1": [0,1], "groupA2": [2,3],"groupB1": [4,5], "groupB2": [6,7]}
}
]
注意:扩容前后的数据桶数量均为8,不能改变,桶的数量需要在初期确定好。如果改变桶的数据,数据要重新聚合并以逻辑sql的方式导入。
扩容流程的详细步骤:
1、 线上业务低峰期,用xtrabackup备份groupA和groupB节点的数据库,并且记下groupA和groupB节点备份的gtid值,后面追数会用到。
2、 用groupA的备份恢复两个实例:groupA1和groupA2,此时groupA1和groupA2数据是一样的;同理,使用groupB备份恢复groupB1和groupB2。
3、 删除groupA1中桶号为2和3的记录,删除groupA2中桶号为0和1的记录;同理,删除groupB1中桶号为6和7的记录,删除groupB2中桶号为4和5的记录。
4、 从备份时的gtid值开始,实时解析groupA节点的增量binlog,生成sql语句并发到扩容后的cetus,由扩容后cetus根据新分片规则把增量数据发到groupA1和groupA2节点;同理,实时解析groupB节点增量binlog,将解析后的sql发到扩容后cetus。
注:解析binlog时,对全局表和DDL操作要特殊处理。这类操作在groupA和groupB节点binlog都有记录,如果不特殊处理,会导致sql在扩容后的环境执行两次。
针对这种情况,追数脚本要有一个参数,用于是否忽略全节点操作。脚本解析groupA节点binlog时不忽略全节点操作,脚本解析其他节点(这里只有groupB)binlog时,都要忽略全节点操作。
5、 第3步删除多余数据和第4步追增量数据可以同时进行;这两步耗时最长,要实时监控是否有报错,及时处理报错。
6、 扩容后groupA1、groupA2、groupB1和groupB2无限接近线上grouA和groupB数据时,做数据校验,确认追数过程没问题。
7、 通知线上停止业务。检查groupA和groupB节点是否有未提交事务,是否有悬挂事务。将groupA和groupB节点设置为super_read_only状态。检查groupA1、groupA2、groupB1和groupB2节点数据是否一致。上述操作通过自动化脚本操作,期望耗时在分钟级别。
8、 应用将流量切到扩容后cetus,检查应用是否运行正常。扩容完成。
简单分析一下cetus扩容方案:
1)方案的复杂度:整套方案并不复杂,只需额外的追数脚本和删数脚本,其他xtrabackup和cetus都是现有工具;扩容过程需要线上两倍的硬件资源进行过度,扩容完成后下线当前线上的主机资源,进行资源回收。
cetus追数脚本具有断点续传和并行复制功能。
2)对线上环境影响程度:扩容过程几乎不需要连接线上数据库,只有消费增量binlog会消耗一些io资源,对线上影响不大。
如果主库资源够用,优先从主库消费增量binlog,避免主从bug等导致的数据不一致
3)扩容过程可控性:随时停止追数和删数任务,重启追数和删数任务不需要额外配置,保证扩容的灵活性。
4)扩容回退方案:扩容方案没有侵入原线上环境,如果扩容失败,启用原线上中间件和后端MySQL节点即可。
用脚本实现cetus扩容方案涉及的所有步骤,rds平台按照扩容步骤调用脚本,线上业务只需停服很短的时间(期望是分钟级别),可以实现扩容自动化。
Cetus开源地址
欢迎提供宝贵意见
github地址:https://github.com/Lede-Inc/cetus/blob/master/doc/cetus-quick-try.md
原文发布时间为:2018-05-30
本文作者:黄荣