codis扩容报错:[error] READONLY You can't write against a read only slave

时间:2021-01-29 21:07:50

现象:最近在做codis在线扩容时,添加多组group,每个group添加一个redis作为master,当进行auto balance或手动迁移slot时,发现要迁移的slot的状态处于error状态,并且一直阻塞后面要迁移的slot,最终导致proxy挂掉,无法对外提供服务。

查看dashboard日志报错“[error] READONLY You can't write against a read only slave.”

从日志来看,是由于redis被认为是一个从,而从是无法写的;但我直连到这个redis从info信息来看,此redis的确为主,并且可以手动写,肯定不是这个问题。

解决:重新读了下codis的迁移过程“http://0xffff.me/blog/2014/11/11/codis-de-she-ji-yu-shi-xian-part-2/”

对于 codis-server 来说,没有任何分布式逻辑在其中, 只是实现了几个关于数据传输的指令: slotsmgrtone, slotsmgrt…. 其主要的作用是:随机选取特定 slot 中的一个 key-value pair, 传输给另外一个 codis-server, 传输成功后,把本地的这个 key-value pair 删除, 注意, 这个整个操作是原子的

  结合全文对这句话理解:当slot从fromgroup将key-value成功传输到togroup后,会将fromgroup的key-value删除,也就是要求fromgroup的redis也必须是可写的或为master。

因此立马确认fromgroup中redis的info信息,发现role为slave且设置成slave-read-only yes(只读);由于fromgroup是slave从而导致codis报错为“[error] READONLY You can't write against a read only slave”。

将fromgroup的redis的主从重新更改后,可以auto rebalance或手动迁移了。

要点:1.autobalance必须保证:

所有的codis-server都必须设置maxmemory

所有的slot都应该处于online状态,即没有迁移任务在执行

所有的group都必须有master

   2.迁移过程汇总slot的状态已经变味migrate,意味着新旧group都会有这个slot的数据,必须迁移完才行否则会丢失数据,因此会不断重试slot迁移,即使出现报错或将dashboard重启。

  3.对于新添加的组建议在迁移slot之前,现确认fromgroup和togroup的redis状态及是否可写。


githua中关于此问题的issue:https://github.com/wandoulabs/codis/issues/438