Skip to content

redis‐shake 2.x 常见问题

suxb201 edited this page Sep 21, 2022 · 1 revision

如果你的问题没有出现在下面列表,请提在github issue上面。第一部分是常见问题咨询,第二部分是出错问题处理。 关于如何进行配置,请参考第一次使用,如何进行配置?

1. 常见问题

Q: 是否支持跨版本同步?

A: 支持,比如2.8到4.0,2.8到5.0。从高版本向低版本的同步理论上也是支持的,但是如果用户使用了高版本的特性,同步到低版本就会失败;此外,如果高版本对协议进行了修改,比如key的封装格式,那么也可能会失败。

Q: 是否支持跨形态同步?比如主从到集群,集群到主从?

A: 支持,目前主从到集群,集群到主从,主从到主从,集群到集群,包括sentinel模式在内都是支持的。

Q: 是否支持断点续传?

A: 目前支持主从版和部分集群版,具体请查看wiki上相应的文档。

Q: 对于某些云上redis,比如部分云厂商不支持sync/psync权限,如何进行迁移?

A: 从v1.4版本开始,我们支持了rump模式进行扫描迁移,可以应对sync/psync权限没有开放的场景。该种模式只支持全量,不支持增量。具体请参考wiki上的使用文档。

Q: 为什么我的源端主从有0-15,一共16个逻辑db,而同步到目的端的集群版就只有db0了?

A: 因为集群版只支持db0,所以db1-15的数据都不会同步到目的端。

Q: 如何过滤lua脚本?

A: 从v1.6.9版本开始,用户可以设置filter.lua参数进行过滤,具体请参考配置文件的说明。而在5.0的redis版本中,所有的lua都会转换为事务操作,就不能被过滤了。

Q: 如果启用过滤db的功能?

A: 用户可以设定filter.db.whitelist让指定的db通过,也可以指定filter.db.blacklist让指定的db不通过,其余的通过。注意这2个参数只能最多指定其中一个。例如,filter.db.whitelist = 0;5;10表示db0,db5,db10通过,其余的db都不会同步。

Q: 如果启用过滤key的功能?

A: 用户可以设定filter.key.whitelist让指定前缀的key通过,也可以指定filter.key.blacklist让指定前缀的key不通过,其余的通过。注意这2个参数只能最多指定其中一个。例如,filter.key.whitelist = abc;xxx;efg会让abc,abc1,xxxyyyy通过,而kkk,mmm都不会通过。

Q: RedisShake是否支持codis和twemproxy?

A: 支持。不过请设置big_key_threshold = 1,以及启用filter.lua = true

Q: 如何控制同步的并发数?

A: 用户可以通过source.rdb.parallel参数控制同步的并发数,比如source.rdb.parallel = 4表示一次只会通过4个全量,只有当其中一个全量同步完成以后,才会开启新的一个全量同步。举个例子,比如源端有8个分片,设置4的话表示同一时刻只会同步4个,假如第1个全量完成了(restore模式完成或者sync模式进入增量),那么会开启第5个全量同步,以此类推直到所有的都完成或者进入增量同步。

Q: 是否支持db映射,比如源端的db2同步到目的端的db10?

A: 不支持,目前只支持所有源端db同步到目的端一个db,比如设置target.db = 10,那么所有源端的逻辑db都会同步到目的端的db10。

Q: 没有密码或者配置的免密,如何设置配置文件中密码?

A: 留空不用配置即可。

Q: 源端是主从,目的端是开源cluster,逻辑db对不上如何同步?

A: 默认情况,只会同步源端的db0,用户如果希望把源端所有的db都同步到目的端的db0,请设置target.db = 0


2. 报错问题解决

Q: decode Redis resp failed. [error]: EOF

A: 如果用户源端从slave上进行拉取的,而源端master跟slave的连接断开了,那么从slave拉取就会失败。

Q: [PANIC] read sync response = ''. EOF"

A: 用户需要检查源端redis节点的日志,通常来说,是源端已经save rdb期间,拒绝掉新来的psync请求,可能发生在某些redis版本。用户需要等待一段时间再重试。

Q: -ERR Can't SYNC while not connected with my master

A: 参见上面这个EOF的问题。

Q: target key name is busy

A: 目的端对应的key已经存在。解决方法有如下三种,可任选其一:

  1. 删除目的端报错的key。
  2. 启用key_exists = rewrite(源端Key覆盖目的端,v1.6.27版本开始支持,在v1.6.27之前是rewrite = true)
  3. 启用key_exists = ignore(忽略报错的key,v1.6.27版本开始支持)

Q: -ERR Unable to perform background save

A: 请检查源端redis日志,源端bgsave失败,通常是内存不够了,或者磁盘写入失败。

Q: OOM command not allowed when used memory > 'maxmemory'

A: 写入到目的端的时候,内存超过原来规格。

Q: [PANIC] parse rdb entry error, if the err is :EOF, please check that if the src db log has client outout buffer oom, if so set output buffer larger

A: 请检查源端redis日志,通常是全量同步过久或者增量过大,导致output buffer打满。通常解决办法有如下几种:

  1. 增大shake全量同步的并发度,调高parallel。
  2. 修改增大源端output buffer的大小, 通过修改output-buffer-limit参数。(建议采用这种方式)
  3. 在业务低峰期再进行同步。

Q: restore command error key:xxx err:-ERR server closed connection

A: 意味着目的端把连接给关闭了,如果是写的key过大导致的,可以降低big_key_threshold对key进行拆分。

Q: [PANIC] auth failed[-ERR unknown command '']

A: 设置source.auth_type = authtarget.auth_type = auth。这个问题在v2.6.26版本已经修复掉了,参加:https://github.com/alibaba/RedisShake/issues/237

Q: ERR redis tempory failure

A: 对于某些集群版,比如阿里云,如果后台db节点发生过主从切换,会报错这个。

Q: Error: NOSCRIPT No matching script. Please use EVAL

A: 这个通常发生在目的端。这个错误表示对应的lua脚本已经丢失了。在redis版本v4.0.4以后这个问题不会出现,在4.0.4以前,源端连接的是slave节点,是可能会出现这个问题的。解决方法如下选一:

  1. 源端升级到4.0.4以后的版本
  2. 源端连接master。
  3. 手动在目的端添加缺失的lua脚本
  4. 源端启用redis.replicate_commands()

Q: checksum validation failed

A: 源端redis禁用了checksum选项,可以通过config set rdbchecksum进行开启。

Q: ERR 'EVAL' command keys must in the same slot

A: lua脚本操作的key不位于同一个slot,通常出现在目的端为集群版的情况。用户可以自己修改Lua脚本,或者将涉及到的key通过hashtag等手段划到一个slot内部。

Q: Conf.Options check failed: get target redis version failed[EOF]

A: 对于某些版本比如twemproxy,不支持获取目的端的redis版本。用户可以通过设置target.version强制设定目的端版本。

Q: ERR syntax error

A: 通常出现在目的端redis版本小于源端redis的版本,所以部分数据格式不兼容。

Q: [xxx] redis address should be all masters or all slaves, master:[xxx], slave[xxx]

A: 如果用户输入的是集群版,需要只输入master或者只slave,指定的角色不能既有master又有slave。参加issue#149

Q: do dump with failed[EOF]

A: 源端redis断开连接,用户需要检查源端redis的日志情况。通常是某个key过大,比如超过了512M(没有办法解决),或者output buffer打满导致的。

Q: Error: CROSSSLOT Keys in request don't hash to the same slot

A: 这个表示后用户的单次请求里面的key没有分发到一个slot,而这个是redis集群本身的强约束。在redis-shakev1.6.27开始,放开了部分命令的约束,从一个slot放开到一个分片db。

Q: ERR DUMP payload version or checksum are wrong

A: 通常出现在rump模式,源端版本大于目的端版本,比如源端是4.0,目的端2.8,某些数据结构格式已经修改导致无法同步。用户可以设置big_key_threshold = 1绕过这个限制。

Q: [PANIC] restore command response = 'ECONNTIMEOUT: dial tcp xxx:1000: connect: cannot assign requested address', should be 'OK'

A: 本机端口耗尽了,需要排查一下原因。

Q: ERR syntax error

A: 同样出现在源端版本大于目的端版本的情况,比如源端是4.0,目的端2.8。

Q: run ChooseNodeWithCmd failed[transaction command[xxxx] key[yyyyy] not hashed in the same slot]

A: 事务中的key需要分发到一个slot里面,通常出现在源端形态和目的端不一致(比如源端是主从,目的端是集群),或者源端集群版的slot分布和目的端不一致。

Q: return error[ERR Bad data format], ignore it and try to split the value

A: 同样出现在源端版本大于目的端版本的情况,比如源端是4.0,目的端2.8。用户可以设置big_key_threshold = 1绕过这个限制。

Q: lua同步报错?

A: 常见报错如下:

  • ERR bad lua script for redis cluster, first parameter of redis.call/redis.pcall must be a single literal string
  • "-ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS array\r\n"`
  • "-ERR for redis cluster, eval/evalsha number of keys can't be negative or zero\r\n"
  • "-ERR eval/evalsha command keys must in same slot\r\n"

出现在目的端为阿里云集群版的情况。基本上的问题都是用户没有按照集群版的规范编写lua脚本,通常发生在主从变配到集群的时候,目前redis-shake版本已经支持对导入出错的lua进行过滤

  • 云上redis-shake版本请在配置文件中设置"filter.lua = 2"再重启redis-shake即可,通常还需要再加上"rewrite = true"。
  • 开源redis-shake版本请设置filter.lua = true,通常还需要加上rewrite = true(1.6.27以前的版本),或者key_exists = rewrite(1.6.27及以后的版本)。

Q: ERR unknown command 'ISCAN'

A: 这个是用户配置项里面添加了scan.special_cloud = aliyun_cloud选项,这个选项是只针对阿里云的集群版的,如果源端是主从版,请去掉该选项。

Q: ERR command replconf not support for your account

A: 源端如果是阿里云的版本会报错这个,对于主从版需要在控制台申请复制权限,用申请到的密码贴到source.password_raw里面;对于集群版,目前还不支持复制权限,所以用户只能使用rump模式进行全量的扫描迁移,不支持增量。

Q:

A:

Clone this wiki locally