阿里云DTS作为数据世界高速传输通道的建造者,每周为您分享一个避坑技巧,助力数据之旅更加快捷、便利、安全。
DTS Redis链路能力介绍与常见问题
单向迁移、同步
DTS对于社区版Redis使用PSYNC/SYNC或Tair binlog协议对源库数据持续抽取,支持单节点、主从版、集群版之间的互相同步。当使用PSYNC/SYNC方式迁移、同步时,会使源端的内存上涨,建议客户在源库内存负载低于50%并在业务低峰期使用DTS。当用户暂停后重启DTS,DTS尝试使用断点续传能力,对于社区版本Redis,断点续传成功与否取决于位点是否在repl_backlog中有关,如果为位点不在repl_backlog中了,DTS就会重新同步RDB全量数据。为保障同步链路稳定性,建议将配置文件redis.conf中repl-backlog-size
参数的值适当调大。
仅全量迁移
使用Redis scan、dump和restore命令进行读取和迁移,只能进行全量数据迁移,建议当不具备源库Redis复制权限时使用,支持不同云厂商间redis版本的迁移。对于大key,DTS会分批次完成迁移。在迁移大key时,对源库的出口带宽会有较大影响,建议在低峰期使用,或者限制DTS迁移速度,避免影响源库业务。当源和目标的Redis版本相差较大时,从源库dump出来的数据restore到目标时可能会报错ERR DUMP payload version or checksum are wrong,建议源库和目标库选择相同版本的Redis。
仅增量
如果您仅需要同步增量数据,不需要全量数据,您可以使用DTS同步仅选择增量。源数据库必须是阿里云Tair数据库,利用Tair的binlog实现仅增量的同步。如果暂停DTS任务超过6h,源端binlog会清理,无法恢复。
双向同步
源和目标数据库必须是阿里云Tair数据库,利用Tair引擎的能力实现防循环能力,同时支持exactly once,确保被同步的Binlog仅会被执行1次。如果暂停DTS任务超过6h,源端binlog可能会清理,无法恢复。如果希望重复迁移,客户必须要以flushall清理目标库后重建DTS任务,否则部分数据可能无法迁移至目标库。
前缀Key过滤
DTS提供前缀key同步和过滤的能力,客户可以按需配置,过滤的优先级更高。
DTS Redis链路冲突逻辑
DTS全量阶段对于key,例如列表list,集合set,有序集合sorted set,stream,哈希hash等,DTS在全量时默认会先删除目标库的key,然后再插入。对于字符串string,也是覆盖写。全量迁移的Restore命令也会加上replace选项。总体来说DTS全量阶段以覆盖Overwrite作为冲突策略。
对于DTS增量阶段,如果暂停重启,如果断点续传成功,就会继续同步,也是覆盖写,但如果断点续传失败,DTS就会重新全量。注意的是,当目标库的某些key还未通过增量删除,就发生了再一次的全量,目标库的这些key就不会被删除。
常见问题解答
"Read xxxxxx bytes , but only xxxxxx already read"/"Cannot read anything"/Redis任务延迟
原因:
1)源库复制输出缓冲区溢出
目标端写入阻塞、源端RPS高造成无法及时ack源库位点,导致源库复制输出缓冲区溢出。
2) repl-timeout参数过小
slave和master之间的复制超时时间,默认为60s, 推荐设置为600s;
对于内存数据集比较大的系统,可以增大repl-timeout参数。
3) 源端有proxy限制output buffer主动断开了dts的连接
4)其他源Redis断开DTS slave连接导致日志解析中断的原因
对于自建Redis,用户可以查询源Redis日志和/var/log/messages
Lua相关
- 云Redis集群架构Lua脚本的使用限制
- Redis4.0.4之前RDB中没有Lua信息,所以DTS不会同步Lua脚本
现象
-ERR bad lua script for redis cluster, first parameter of redis.call/redis.pcall must be a single literal string
-ERR for redis cluster, eval/evalsha number of keys can't be negative or zero
-ERR eval/evalsha command keys must be in same slot
-ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS array, and KEYS should not be in expression
原因
https://help.aliyun.com/document_detail/145968.html#title-sx3-bjk-1sf
https://help.aliyun.com/zh/tair/support/usage-of-lua-scripts?spm=a2c4g.11186623.0.i17
一般是云Redis集群架构的限制。请按照文档要求修改Lua脚本再进行同步。
DTS同步后,源和目标通过info keyspace获得Redis数据不一致,内存大小不一致
keys:表示所有key的数据量
expires:表示带有过期key的数量
expires表示的数据量不仅包含未过期key的数量,也包含已经过期的key的数量。也就是说那些逻辑上已经过期的key,实际上还没有被redis删除,仍然被统计到这里了。
使用info keyspace获取到的key数量仅供参考,可以使用DTS全量校验进行数据校验。
带有过期时间的key导致的数据不一致
如果源库有带过期时间的key,DTS在迁移时默认会延长1800s,目的是防止DTS在迁移过程中,源端续期的操作还没有同步到目标端,目标端的key就过期了。例如源库有一个demo_key过期时间为10s,源库在过期前5s对demo_key重新续期10s(expire demo_key 10),当DTS在迁移全量RDB假设需要60s,那么当迁移为demo_key至目标后,demo_key在10s后过期了,等到DTS回放增量阶段收到了expire demo_key 10命令,但目标库的demo_key已经过期了,续期失败,从而源库存在demo_key,目标库没有demo_key。
如果客户强依赖过期时间,可以在控制台配置任务时自行选择延长时间。
双向同步任务清理目标库后重新迁移(目标库少数据)
若清理目标库使用的不是flushall,而是flushdb,阿里云Tair侧的位点没有清理,重新使用DTS迁移,某些key会被引擎判断为已重复而导致目标库少数据。
建议用户使用flushall清理数据库后,重新使用DTS迁移。
CROSSSLOT Keys in request don't hash to the same slot
源库单机版Redis同步到目标库集群版Redis的操作限制:由于集群cluster只允许单个命令操作单个slot,若在源库执行多Key操作时,Key不在同一个slot或涉及多个slot,则会出现以上报错,建议在DTS同步过程中仅执行单Key操作,以免导致链路中断。
源库和目标库更改配置
同步期间,如源、目标Redis发生扩缩容(如增加或者减少分片)、规格变配(如扩大内存),您需密切关注DTS任务,您可以考虑暂停、重启DTS,如果DTS任务没有恢复,您需要重新配置任务,我们建议您在变配操作后,重新配置DTS任务。且为保障数据一致性,建议重新配置任务前,先清空已同步至目标Redis的数据。
高版本迁移至低版本导致命令执行失败
我们强烈建议源和目标库版本保持一致,或者从低版本同步到高版本以保障兼容性。
如为高版本同步至低版本,可能存在数据库兼容性问题,例如SET PXAT命令仅在6.2及以上版本支持。
目标库OOM:OOM command not allowed when used memory > 'maxmemory'.
在迁移时如果源库内存使用率达到50%,我们建议目标库的内存要至少和源库保持一致或者更高。当目标库为集群版本,DTS迁移时将源库的key根据其所在SLOT写入到对应的分片上。如果源库和目标库均为集群版,请勿直接根据两者的分片数量或者规格一致而认为经迁移后目标库一定不会OOM。因为两者的SLOT在分配时可能有差异,所以两者的数据倾斜程度也会不同。
同时我们建议将目标库的数据逐出策略设置为noeviction,当目标库内存不足时,数据会写入失败,同时DTS任务也会失败,但目标库不会因为数据逐出而丢失数据。请注意云数据库Redis版的默认数据逐出策略(maxmemory-policy)为volatile-lru,会导致目标库与源库数据不一致的情况,但不会影响DTS任务的正常运行。
快来关注
- 数据传输服务(Data Transmission Service,简称DTS)支持关系型数据库、NoSQL、大数据(OLAP)等数据源,集数据迁移、订阅、实时同步、校验功能于一体,能够解决公共云、混合云场景下,远距离、秒级异步数据传输难题。其底层基础设施采用阿里双11异地多活架构,为数千下游应用提供实时数据流,已在线上稳定运行7年之久,是一款沉淀了丰富实践经验的可靠产品。点击了解更多DTS相关信息
- 欢迎加入钉群讨论交流: