簡介
Redis Cluster提供了另一種運(yùn)行Redis的形式,構(gòu)建一個(gè)分布式Redis系統(tǒng),提供數(shù)據(jù)分區(qū)和故障轉(zhuǎn)移服務(wù)。
Redis以集群形式啟動時(shí),將會開啟兩個(gè)端口client_port和cluster_port(=client_port+10000),前者用于服務(wù)客戶端請求(讀、寫、主從同步、鍵值遷移等),后者是用于與其他節(jié)點(diǎn)進(jìn)行集群通信(故障檢測、配置更新、故障轉(zhuǎn)移授權(quán)等)。
注意:當(dāng)使用Docker運(yùn)行Redis時(shí),需要使用主機(jī)網(wǎng)絡(luò)(--network host),否則將無法與集群端口通信。
分區(qū)策略
Redis使用一種叫做散列槽(hash slot)的分區(qū)策略,對于給定的key計(jì)算其所屬的散列槽(key => CRC16(key) % 16384),然后每個(gè)節(jié)點(diǎn)負(fù)責(zé)散列槽的子集。添加和刪除節(jié)點(diǎn)只需要移動散列槽即可。
Redis使用Hash tag,來確保指定的key落在同一個(gè)散列槽,即this{foo}key與that{foo}key將保證位于相同的散列槽。如此,便可執(zhí)行涉及多個(gè)鍵的操作。
主從模型
主從模型保證每個(gè)主節(jié)點(diǎn)都有多個(gè)奴隸,當(dāng)主節(jié)點(diǎn)出現(xiàn)故障時(shí)集群會提升一個(gè)奴隸作為主節(jié)點(diǎn)以確保服務(wù)可以正常運(yùn)行。
Redis使用異步復(fù)制來保證性能,所以無法保證強(qiáng)一致性。異步復(fù)制的過程:
- 客戶端請求寫入
- 主節(jié)點(diǎn)處理并回復(fù)確認(rèn)
- 主節(jié)點(diǎn)向奴隸傳播寫入
使用
集群配置參數(shù)
- cluster-enabled <yes/no>:開啟集群模式還是
standlone模式。 - cluster-config-file <filename>:集群的配置信息,由節(jié)點(diǎn)保存和修改,可以此進(jìn)入集群。
- cluster-node-timeout <milliseconds>:用于節(jié)點(diǎn)的自我故障檢測和故障轉(zhuǎn)移。如果節(jié)點(diǎn)在指定時(shí)間內(nèi)無法訪問大部分主節(jié)點(diǎn),將會停止對外服務(wù)。
- cluster-slave-validity-factor <factor>:如果設(shè)置為0,
奴隸在超時(shí)發(fā)生后立即進(jìn)入故障轉(zhuǎn)移。如果該值為正,奴隸在超時(shí)cluster-node-timeout * cluster-slave-validity-factor之后,將不進(jìn)行故障轉(zhuǎn)移。 - cluster-require-full-coverage <yes/no>:集群是否需要覆蓋全部
key空間時(shí),才能提供服務(wù)。 - cluster-migration-barrier <num>:配置該節(jié)點(diǎn)要求的奴隸數(shù)量,當(dāng)該節(jié)點(diǎn)奴隸數(shù)量大于配置的值時(shí),將允許分出奴隸給孤兒節(jié)點(diǎn)來執(zhí)行奴隸遷移。
創(chuàng)建集群
redis-cli --cluster是一個(gè)集群管理工具,其中包含創(chuàng)建集群、添加刪除節(jié)點(diǎn)、重新分區(qū)等等命令,可以使用 redis-cli --cluster help 查看命令參數(shù)。Redis集群最少需要3個(gè)主節(jié)點(diǎn)才能創(chuàng)建。
步驟:
- 使用集群模式啟動空的
redis-server實(shí)例,此時(shí)會生成一個(gè)集群配置文件,其中存有一個(gè)Node ID用以唯一標(biāo)記此節(jié)點(diǎn)在集群中的身份。 - 使用
redis-cli --cluster create來創(chuàng)建集群
添加刪除節(jié)點(diǎn)
下面的所有命令都需要與集群中的任意一個(gè)工作節(jié)點(diǎn) host:port 連接通訊。
# 1. 集群模式啟動空實(shí)例
cd /data && redis-server ./redis.conf
# 2. 加入集群
## 添加為主節(jié)點(diǎn),此時(shí)節(jié)點(diǎn)已經(jīng)可以進(jìn)行請求重定向,但是沒有分配散列槽和數(shù)據(jù),也不參加選舉過程
redis-cli --cluster add-node new_host:new_port existing_host:existing_port
## 添加為奴隸,如果不指定主節(jié)點(diǎn)id,將會選取副本較少的主節(jié)點(diǎn)作為其主節(jié)點(diǎn)
redis-cli --cluster add-node new_host:new_port existing_host:existing_port \
--cluster-slave [--cluster-master-id <master_id>]
# 3. 刪除節(jié)點(diǎn),當(dāng)刪除主節(jié)點(diǎn)時(shí)必須保證主節(jié)點(diǎn)為空
redis-cli --cluster del-node host:port <node-id>
重新分區(qū)
重新分區(qū)意味著將散列槽從一組節(jié)點(diǎn)移動到另一組節(jié)點(diǎn)。
redis-cli --cluster reshard host:port \
--cluster-from <node-id> \
--cluster-to <node-id> \
--cluster-slots <number of slot> \
--cluster-yes
故障轉(zhuǎn)移
Redis集群可以在主節(jié)點(diǎn)死亡后,自動挑選一個(gè)奴隸升級為主節(jié)點(diǎn)繼續(xù)服務(wù)。
# 手動故障轉(zhuǎn)移,將一個(gè)奴隸安全的提升了主節(jié)點(diǎn)
redis-cli -c -h <slave_ip> -p <slave_port>
> CLUSTER FAILOVER
奴隸遷移
集群中的奴隸可以遷移給孤兒主節(jié)點(diǎn),這樣就可以防止當(dāng)孤兒主節(jié)點(diǎn)在死亡后,沒有工作的奴隸進(jìn)行故障轉(zhuǎn)移,從而提高可用性。配置參數(shù) cluster-migration-barrier 控制著遷移條件。
集群客戶端
redis-cli -c利用節(jié)點(diǎn)的查詢路由,支持非常基礎(chǔ)的集群訪問功能(將請求發(fā)送給指定的節(jié)點(diǎn),由該節(jié)點(diǎn)保證將請求重定向到正確的節(jié)點(diǎn))。一個(gè)好的集群客戶端,可以實(shí)現(xiàn)客戶端分區(qū),緩存散列槽 => 節(jié)點(diǎn)ip映射,以直接訪問正確的節(jié)點(diǎn),并且可以在集群配置更改后刷新緩存。