D:\haojingkeji\flask-vue-crud\redisclear>python redisclear.py redis連接成功 Redis<ConnectionPool<Connection<host=192.168.50.162,port=8003,db=0>>> MOVED 15160 192.168.50.177:8003
問題原因:
Redis集群的問題:我需要從新設置redis集群某個鍵的值,沒有機器的登錄權限,然后用python寫了一個腳本處理,報這個錯。
節點會對命令請求進行分析和key的slot計算,並且會查找這個命令所要處理的鍵所在的槽。如果要查找的哈希槽正好就由接收到命令的節點負責處理, 那么節點就直接執行這個命令。
如果所查找的槽不是由該節點處理的話, 節點將查看自身內部所保存的哈希槽到節點 ID 的映射記錄, 並向客戶端回復一個 MOVED 錯誤。上面的錯誤信息包含鍵 x 所屬的哈希槽15495, 以及負責處理這個槽的節點的 IP 和端口號 192.168.50.177:8003
解決辦法:
直接用返回的MOVED 錯誤里的IP和端口連接就可以了,當然也可以捕獲異常的方式處理。
#!/usr/bin/env python # -*- encoding: utf-8 -*- # pip install redis # Python 3.9.0 ''' @File : redisclear.py @Time : 2021/12/1 10:32:56 @Author : Li Ruilong @Version : 1.0 @Contact : 1224965096@qq.com @Desc : redis 集群指定鍵值clear ''' # here put the import lib import redis ip = '192.168.50.177' password = '*********' port = 8003 conn=redis.Redis(host=ip,password=password,port=port,decode_responses=True) print("redis連接成功",conn,"\n") def ex(conn): print("當前的redis值為:",conn.get('GROUP_CIRCUIT-3'),"\n") conn.set('GROUP_CIRCUIT-3',600) print("修改后redis值為:",conn.get('GROUP_CIRCUIT-3'),"\n") if __name__ == '__main__': try: rs = conn.get('GROUP_CIRCUIT-3') except Exception as e: print(e) c= str(e).split() print("集群節點問題,從新連接到輸出節點操作","\n") ip = str(c[2]).split(':')[0] port = str(c[2]).split(':')[1] print(ip,port,"\n") conn=redis.Redis(host=ip,password=password,port=int(port),decode_responses=True) rs = conn.get('GROUP_CIRCUIT-3') ex(conn) else: ex(conn)
雖然我們用Node ID來標識集群中的節點, 但是為了讓客戶端的轉向操作盡可能地簡單, 節點在 MOVED 錯誤中直接返回目標節點的 IP 和端口號, 而不是目標節點的 ID 。客戶端應該記錄槽15495由節點 192.168.50.177:8003負責處理“這一信息, 這樣當再次有命令需要對槽15495執行時, 客戶端就可以加快尋找正確節點的速度。這樣,當集群處於穩定狀態時,所有客戶端最終都會保存有一個哈希槽至節點的映射記錄,使得集群非常高效: 客戶端可以直接向正確的節點發送命令請求, 無須轉向、代理或者其他任何可能發生單點故障(single point failure)的實體(entiy)。