官方參考:https://redis.io/commands/cluster-setslot。示例:將值為8的slot從源節點A遷移到目標節點B。
1) 在目標節點B上執行,從節點A導入slot到節點B:
| CLUSTER SETSLOT 8 IMPORTING src-A-node-id |
對於遷移的slot,正常訪問返回MOVED;但如果在正常訪問之前先執行ASKING,則能正常處理該slot。
2) 在源節點A上執行,將節點A上的slot遷移到節點B
| CLUSTER SETSLOT 8 MIGRATING dst-B-node-id |
命令“SETSLOT slot MIGRATING”將slot標記為正在遷移(MIGRATING)狀態。如果訪問的key在源節點上存在,則正常訪問;如果訪問的key在源節點上不存在,則返回ASK重定向到目標節點。
如果是操作多個keys,則情況有些復雜。如果全不存在或者全存在,則和操作單key相同。但如果是部分存在,部分不存在,則返回錯誤“TRYAGAIN”。
注意,上列步驟1和2的執行順序不能顛倒,目的是讓目標節點先准備好接受ASK重定向命令(The order of step 1 and 2 is important. We want the destination node to be ready to accept ASK redirections when the source node is configured to redirect.)。
3) 遷移數據/數據遷移
如果是一個空集群,則這一步可以跳過省去,因為此時還沒有任何需要遷移的數據。前面的步驟1和步驟2只影響新的keys,並不會自動遷移已有的keys。
已有的keys需用命令MIGRATE遷移,借助命令“CLUSTER GETKEYSINSLOT”可知道slot有哪些keys。
在源節點上執行獲得需要遷移的keys(參數“count”指標一次返回多少個keys):
| CLUSTER GETKEYSINSLOT slot count |
在源節點上執行命令MIGRATE遷移keys:
| MIGRATE dest-host dest-port key|"" destination-db timeout [COPY] [REPLACE] [AUTH password] [KEYS key [key ...]] |
命令“MIGRATE”的參數dest-host和dest-port為目標節點的IP和端口號,參數“REPLACE”表示覆蓋目標節點相同的keys,而“COPY”不會刪除源節點上的keys。
遷移單個key格式:
| MIGRATE dest-host dest-port key destination-db timeout [COPY] [REPLACE] [AUTH password] |
或者:
| MIGRATE dest-host dest-port "" destination-db timeout [COPY] [REPLACE] [AUTH password] KEYS key |
遷移多個keys格式:
| MIGRATE dest-host dest-port "" destination-db timeout [COPY] [REPLACE] [AUTH password] [KEYS key [key ...]] |
AUTH用於指定訪問密碼,從Redis-6.0開始,新增支持AUTH2。參數timeout用於指定超時時長,單位毫秒。
如果是一個集群對另一個集群,必須保證保證目標節點是key對應的節點。對於集群間遷移,如果多keys需保證對應的slots都在目標節點上,否則報錯“CROSSSLOT Keys in request don't hash to the same slot”。
如果版本號不同,則還會遇到錯誤“ERR Target instance replied with error: ERR DUMP payload version or checksum are wrong”。
4) 完成遷移
上述操作只是將slot標記為遷移狀態,完成遷移還需要執行(在源node和目標node上執行),將slot指派給dst-node-id指定的節點:
| CLUSTER SETSLOT <slot> NODE <dst-node-id> |
執行“NODE”會產生新的配置,實際上可在所有master節點上執行“NODE”,這樣避免了新的配置在集群中傳播,加快了配置的更新,官方說明可參見“Cluster live reconfiguration”一節。
重復執行“NODE”,會報錯“ERR I'm already the owner of hash slot 1703”。
“NODE”命令中的dst-node-id為目標節點的Node ID,取消遷移和導入使用“CLUSTER SETSLOT <slot> STABLE”。
手動完成上列4步操作繁瑣且容易出錯,如有需要可直接使用現在的遷移工具https://github.com/eyjian/redis-tools/blob/master/move_redis_slot.sh。
附:跨集群的數據遷移可使用命令“redis-cli --cluster import”。
