整理常见的千万级数据分表的迁移方案
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
在互联网业务中我们会遇到千万级别数据量的表需要拆分成多表存储,或者底层的数据存储介质的变更等原因都需要做数据的迁移,今天我们来聊聊数据的迁移方案。 1、数据的迁移策略 假设现在又一张千万级别的订单明细表,我们需要拆分成多张子表存储,那么我们按照什么规则来将订单的明细放入子表中呢? (1)哈希取模方式 订单明细中可以选择订单id作为key进行哈希取模来确定数据应该存储在哪个子表中,如下所示: 在具体选择哪个字段为key的时候,我们能需要根据实际的业务中哪个字段的查询最为频繁,目的是尽量减少跨表查询。常见的key可以选择如订单id、用户id等等字段,采用这些字段作为分表的key,可以避免跨表查询的问题。 (2)基于范围分表 首先需要确定一个合适的范围来进行数据迁移,常见的方案又基于时间范围或基于id范围进行分表迁移。 基于时间分表迁移是根据时间范围(如同一年的数据放在一个表)将数据划分出来,如下所示: 基于id范围进行数据迁移的方案是维护一张id访问表,然后将指定的id范围放入某张表中,如下所示: 具体要用哪种迁移数据的策略要根据具体的业务场景,主要是基于性能、可维护性等方面考虑,最后再确定迁移的策略。 2、数据的迁移方案 2.1 停机迁移 停机迁移是一种直接且粗暴的方法,停机迁移会影响用户的正常访问,所以通常会提前给用户一个友好的通知,如下是停机迁移的图: 为了降低迁移过程中带来的影响,一般都是选在凌晨进行数据的迁移,这样尽量将风险降到最小。许多游戏公司的服务器升级,游戏分区与合区,都可能会采用类似的方案。 2.2 双写策略 双写策略是继续向老表写入数据,同时再根据分表策略把数据写入到新的分表中,并记录开始同步新表数据的时间,如下图所示: 为了保证数据双写一致性,我们需要使用定时任务对新旧表中的数据进行对比,确保数据写入无错误。经过一段时间的双写之后,如果没有任何的问题,基于最早同步的时间点把原始表之前的数据迁移到新表。
2.3 MQ+Redis实现数据的迁移 使用MQ+Redis做数据迁移是一种比较平滑迁移方案,方案的流程图如下所示: (1)制定迁移方案 对于千万级别的数据量迁移,首先根据id范围划分的策略,如每一万个数据划分成一组,然后对迁移的原始表和目标都使用Redis的bitmap记录每条数据的迁移情况,数据分成多少组,就使用多个Redis的key,key的命名含义如下: redis_source_key:表示迁移表中Redis的key source_tb_s1e10:表示迁移表中开始的id从1开始,结束的id是10000,这样就表示id在1-10000范围的数据。 redis_target_key:表示目标表的Redis的key target_tb_s1e10:表示目标表中开始的id从1开始,结束的id是10000,这样就表示id在1-10000范围的数据在目标表中的保存情况(主要是记录是否保存到目标表)。 同时在Redis中也需要记录每个分组(如1-10000)中本次迁移的开始时间,使用key单独记录(如source_tb_s1e10_startTime);记录每个分组中迁移的状态(如迁移完成、正在迁移),使用key单独记录(如source_tb_s1e10_status)。 记录分组开始的时间和分组的迁移状态的目的是为了定时任务做数据的补偿。 (2)执行迁移方案 执行迁移方案就是将源表中的数据分组后使用MQ的方式发送到消息队列中,然后在Redis的bitmap中记录每条数据的迁移情况,如下所示: 对应的bit位上为1就表示数据已经发送MQ中等待消费。 在消费端来消费队列中的消息,然后按照迁移数据的策略将数据落目标表中保存下来,保存成功之后在Redis的目标key中并记录消费情况,如下所示: 对应的bit位上为1就表示数据已经消费成功。 (3)数据补偿 为了保存数据迁移中不被遗漏,我们可以采用定时做补偿机制,原理是通过扫描Redis中分组迁移状态是key(如source_tb_s1e10_status)是成功状态,如下所示: 然后把迁移状态是成功为key的生产端和消费端的bitmap做异或处理,将异或结果为1的数据拿出来,如下所示: 通过比对发现bit位的3和4位置上数据不一致(也就是生产端生成成功,但是消费端消费失败),那么根据这个分组的开始迁移的时间与当前的时间做比对,如过大于设置的时间(如1小时),那么我们就需要手动的补偿数据。 总结: (1)数据的迁移策略有哈希取模、基于时间、基于id范围等常见的方案。 (2)常见的数据迁移的方案有停机迁移、双写迁移以及MQ+Redis方案迁移。 阅读原文:原文链接 该文章在 2024/12/30 15:23:24 编辑过 |
关键字查询
相关文章
正在查询... |