Redis集羣常用操作方式

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

安裝集羣
截止本文發佈時,Redis社區並沒有提供集羣版的二進制包,所以需要自己從github下載最新源碼然後進行編譯安裝。編譯方法在源碼包的readme中有詳細說明,需要注意的是內存分配器推薦使用jemalloc,即通過“make MALLOC=jemalloc”指令進行編譯。
社區要求最小的Redis集羣需要包含3個Redis主節點,如果考慮到自動故障恢復的話,則需要6個節點爲佳。
每個節點單獨啓動Redis服務,務必設置下列配置項(前兩項必須設爲yes):
Daemonize yes //redis服務爲後臺守護進程
cluster-enabled yes //redis服務以集羣模式啓動
pidfile pid文件路徑
logfile log文件路徑
cluster-config-file node配置文件路徑 //此文件在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,將從節點轉換爲主節點。
上述步驟只能對一個主節點進行升級,其餘主節點升級,按照這些步驟執行多次即可。

發佈了66 篇原創文章 · 獲贊 6 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章