1. 程式人生 > >codis擴容報錯:[error] READONLY You can't write against a read only slave

codis擴容報錯:[error] READONLY You can't write against a read only slave

現象:最近在做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