1. 程式人生 > >Redis叢集常用操作方式

Redis叢集常用操作方式

目前對叢集的操作可以通過社群提供的ruby指令碼(redis-trib.rb,包含在src目錄下)和內建命令進行(Cluster命令組)進行,包括Jedis在內的一些客戶端工具也提供了部分叢集操作。下面以前者為例介紹常用的叢集操作。

安裝叢集
截止本文釋出時,Redis社群並沒有提供叢集版的二進位制包,所以需要自己從github下載最新原始碼然後進行編譯安裝。編譯方法在原始碼包的readme中有詳細說明,需要注意的是記憶體分配器推薦使用jemalloc,即通過“make MALLOC=jemalloc”指令進行編譯。
社群要求最小的Redis叢集需要包含3個Redis主節點,如果考慮到自動故障恢復的話,則需要6個節點為佳。
每個節點單獨啟動Redis服務,務必設定下列配置項(前兩項必須設為yes):
Daemonizeyes //redis服務為後臺守護程序
cluster-enabledyes//redis服務以叢集模式啟動
pidfilepid檔案路徑
logfilelog檔案路徑
cluster-config-filenode配置檔案路徑 //此檔案在redis服務啟動時產生,一般只供程式讀寫
如果僅僅將Redis作為快取,而不需要持久化的話,啟動時需要設定引數save為空字串,引數appendonly為no。
如果作為測試意圖,可以在一臺物理機器上啟動多個例項,每個模擬不同的節點,此時不同例項需要使用不同的埠。如果用作生產叢集,不建議多個節點共享一臺機器。
然後使用下列命令建立叢集:
./redis-trib.rb create --replicas 1 <all node's address>
該命令根據引數中指定的節點地址,生成推薦的主節點和從節點,以及資料分割槽和節點的對應關係。當用戶確認後,便開始建立叢集。如果使用者不贊同推薦的配置,則叢集不能建立。此次只有推薦的配置,使用者不能自定義配置。當然,如果對節點角色和資料分割槽有異議,也可在叢集建立後,通過後續的命令進行調整。

重新分割槽
此操作一般用於新增或者移除節點的場景,否則,請慎用此操作。重新分割槽命令如下:
./redis-trib.rb reshard <arbitray node's address in cluster>
引數中只要指定叢集中任一節點的地址即可,該命令能自動發現叢集中的所有節點。重新分割槽必須在叢集沒有寫入操作的場景下進行,否則不但會導致寫入失敗,而且分割槽操作也會失敗。
重新分割槽後應該執行下列命令進行檢查:
./redis-trib.rb check <arbitray node's address in cluster>
重新分割槽會導致分割槽中的所有key在不同的節點之間移動,所以這是一個的代價高的操作。

移除節點
./redis-trib.rb del-node <arbitray node's address in cluster> <node-id>
上述為移除節點的命令,引數node-id表示需要移除的節點標示,該標識可通過cluster nodes命令獲取,也可從節點的cluster-config-file中查閱。
從節點可以直接移除,但是主節點必須先置空後才能移除。置空master節點的方法是通過reshar命令移除其包含的所有資料分割槽。
節點被移除後,其在剩餘節點的cluster-config-file中的相應記錄也會被清除。
移除節點的內部命令是CLUSTER FORGET <node-id>。

Failover
自動failover

當一個主節點故障後,會觸發自動failover,也就是將此主節點對應的一個從節點選舉為新的主節點。自動failover過程中,會影響客戶端的讀寫,例如:客戶端寫可能會丟擲下列異常:
Exception in thread "main" redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException: Too many Cluster redirections?
自動failover完成後,如果重啟故障的主節點成功,它將自動變為一個從節點。
手動failover
在從節點上執行“cluster failover”命令將觸發手動failover,結果是原來的主節點變成了從節點,從節點變成了主節點。
較之自動failover,手動的更安全可靠,因為在主從節點沒有完全同步之前,不會將客戶端的操作重定向到新的主節點。在手動failover執行期間,客戶端讀寫操作不受影響。

新增節點
./redis-trib.rb add-node  <new node's address>  <arbitray node's address in cluster>
該命令將新新增的節點作為一個“空”的主節點,即不包含任何的資料分割槽。
./redis-trib.rb add-node --slave <new node's address> <arbitray node's address in cluster>
該命令將新新增的節點將作為一個從節點,其對應的主節點由叢集隨機選取從節點數最少的主節點。
./redis-trib.rb add-node --slave --master-id <master-node-id> <new node's address> <arbitray node's address in cluster>
該命令將新新增的節點作為一個指定主節點的從節點。
不管新新增的節點作為主節點還是從節點,都不影響當前的讀寫操作。但是如果新節點作為主節點的話,初始時其不包含任何資料分割槽,也就是說其實並未真正發揮主節點的作用。為了給其分配新的資料分割槽需要執行重新分割槽(reshard)命令,此時需要在寫操作暫停的場景下進行操作。
也可以將新新增的“空”主節點轉變為從節點,使用如下類似命令:
redis 127.0.0.1:7006> cluster replicate  < master-node-id >
該命令執行時,必須通過redis-cli登陸到需要轉換的節點上,否則命令結果可能錯亂。master-node-id表示從節點對應的主節點標識。這個命令還可以切換從節點對應到不同的主節點。
如果要將之前移除的一個節點再次加入,需要刪除以前的rdb和cluster-config-file檔案。

副本遷移
假設叢集中每個主節點各有一個從節點,萬一某個主節點和對應的從節點都失敗了,則叢集會出現不可用的情況。雖然這種場景很少,但是不能完全避免。
可以為一個主節點新增多個從節點,這樣可以避免這個問題,但是這種方法太昂貴了。一種折衷的方法是:在每個主節點各有一個從節點的前提下,再新增少數幾個從節點,先將它們對應到任意的主節點上。當發現有主節點的從節點個數為0時,並且還有其它主節點擁有多個從節點時。則從後者中選取一個從節點,將其轉變為前者的從節點。
這種方法雖然可以最大化的避免叢集不可用的問題,但是不能完全避免。
Redis叢集目前已經實現了自動的副本遷移功能,只需在配置檔案中啟用“cluster-migration-barrier”選項即可(預設值為1),即如果出現一個主節點的所有從節點故障,並且還有其它主節點的從節點個數大於1的場景,則從後者的從節點中選擇一個轉換為前者的從節點。
也可手動執行副本遷移,通過命令“CLUSTER REPLICATE <master-node-id>”來實現。

停止叢集
社群並沒有提及叢集的停止方法,經過實驗後發現可以通過先停止所有從節點,再停止所有主節點的方式完成此功能。如果先停止主節點的話,可能會觸發自動failover。啟動時先啟動所有主節點,再啟動所有從節點。啟動時將從cluster-config-file中獲取節點之前的角色。 

升級叢集
從節點升級很簡單,只需要先停止節點服務,然後啟動更新後版本即可。如果此過程中有客戶端正在使用此節點,當發現不可用時會重連到其它從節點或者主節點。
如果升級主節點,過程稍微麻煩一點,可以按照下列步驟:
1.使用cluster failover命令執行手動failover,將主節點轉換為從節點;
2.對轉換後的從節點進行升級;
3.再次執行手動failover,將從節點轉換為主節點。
上述步驟只能對一個主節點進行升級,其餘主節點升級,按照這些步驟執行多次即可。