1、無中心化
- Redis Cluster采用無中心架構(gòu),每個節(jié)點都保存數(shù)據(jù)和整個集群的節(jié)點狀態(tài)
- 每個節(jié)點都和集群中的其它節(jié)點保持連接
- 使用gossip協(xié)議傳播信息以及發(fā)現(xiàn)新的節(jié)點
- 節(jié)點不作為client請求的代理,client應(yīng)該根據(jù)節(jié)點返回的錯誤信息重定向到目標(biāo)client
2、數(shù)據(jù)分布(slot)
redis預(yù)設(shè)16384個slot(槽),集群中的每個master節(jié)點負(fù)責(zé)分管一部份slot,保存數(shù)據(jù)時,根據(jù)CRC16(key) mod 16384的值,決定將一個key放到哪個槽中,從而定位由哪個redis實例存儲。當(dāng)發(fā)生Redis節(jié)點增減時,調(diào)整桶的分布即可,實現(xiàn)了集群的動態(tài)擴容功能。同時也間接的說明redis集群最多只能有16384個節(jié)點。
例如:假設(shè)Redis集群有三個節(jié)點A/B/C,在開始創(chuàng)建的時候,集群中節(jié)點槽的分配如下:
Node A 分管slot的編號為:0 ~ 5460
Node B 分管slot的編號為:5461 ~ 10922
Node C 分管slot的編號為:10923 ~ 16383
當(dāng)添加一個新的master節(jié)點D,假設(shè)為它分配900個slot,你可以從節(jié)點ABC三中各取300個分配給D,也可指定從A或B或C中移出900個slot分配給D,或選其中幾個節(jié)點中各取一部份湊夠900個分配給D即可。同樣的,如果要將D節(jié)點移除,需要先將D節(jié)點分管的slot全部分配到其它master節(jié)點后才能移除,否則有無效的slot,集群將無法服務(wù)。
3、可用性:Master-Slave
- 為了保證服務(wù)的可用性,Redis Cluster采取的方案是Master-Slave機制
- 每個Redis Master Node可以有一個或者多個Slave Node。當(dāng)Master Node掛掉時,會從Slave Node中選一個新的Master
- 每個Master Node都負(fù)責(zé)分管一定范圍的slot,當(dāng)這些slot對應(yīng)的Master和Slave都掛掉時,這部份slot對應(yīng)的數(shù)據(jù)將不可用
- 16384個slot必須被全部分配,否則集群將不可用。通過
cluster info
查看集群狀態(tài)可以得知。
4、寫
Redis Cluster采用異步復(fù)制機制
一個完整的寫操作步聚:
1. client寫數(shù)據(jù)到master
2. master回復(fù)client “OK”
3. master將數(shù)據(jù)傳播更新到slave
存在數(shù)據(jù)丟失的風(fēng)險:
1. 上述步聚1)和2)成功后,如果此時master crash,而數(shù)據(jù)還沒有傳播到slave。此時slave選主為master,但那部份數(shù)據(jù)可能就被丟失了。
2. 由于分區(qū)導(dǎo)致同時存在兩個master,client向舊的master寫入了數(shù)據(jù)
當(dāng)然,由于Redis Cluster存在超時及故障恢復(fù)機制,第2個風(fēng)險基本上可以忽略不計
5、數(shù)據(jù)遷移
Redis Cluster支持在線增、減節(jié)點。基于slot的數(shù)據(jù)分布方式大大降低了遷移成本,只需將數(shù)據(jù)slot從一個redis node遷移到另一個redis node即可完成遷移工作 。
當(dāng)slot從一個Node A向另一個Node B遷移時,Node A和Node B都會有這個slot,Node A上slot的狀態(tài)設(shè)置為MIGRATING,Node B上的狀態(tài)被設(shè)置為IMPORTING。此時當(dāng)客戶端請求時,所有key在Node A上的請求都由A來處理,所有不在A上的key都由Node B來處理。同時,Node A上將不會創(chuàng)建新的key。
6、客戶端操作的一些缺陷
- 不支持多數(shù)據(jù)庫,默認(rèn)只有一個0號db,select 0
- cluster環(huán)境下slave默認(rèn)不接受任何讀寫操作,在slave執(zhí)行readonly命令后,可執(zhí)行讀操作。執(zhí)行readwrite命令后,可執(zhí)行讀寫操作。
- client端不支持多key操作(mget,mset等),但當(dāng)keys集合對應(yīng)的slot相同時支持mget操作。