Redis集群101
Redis 集群是一個(gè)提供在多個(gè)Redis節(jié)點(diǎn)間自動(dòng)地共享數(shù)據(jù)的程序集。
Redis 集群在分區(qū)時(shí)也提供了一定程度的可用性,即當(dāng)某些節(jié)點(diǎn)失敗或不能通訊時(shí),還能繼續(xù)操作的能力。但是發(fā)生大的故障它還是會(huì)停止的(例如當(dāng)大部分主節(jié)點(diǎn)不可用時(shí))。
所以在實(shí)際中,你能從集群中得到什么?
在多個(gè)節(jié)點(diǎn)間自動(dòng)劃分你的數(shù)據(jù)集的能力。
當(dāng)一部分節(jié)點(diǎn)不工作了或者不能和其余的節(jié)點(diǎn)通訊了,你仍然能夠處理命令。
Redis 集群的數(shù)據(jù)分片
Redis 集群沒有使用一致性hash, 而是引入了哈希槽的概念.
Redis 集群有16384個(gè)哈希槽,每個(gè)key通過CRC16校驗(yàn)后對(duì)16384取模來決定放置哪個(gè)槽.集群的每個(gè)節(jié)點(diǎn)負(fù)責(zé)一部分hash槽,舉個(gè)例子,比如當(dāng)前集群有3個(gè)節(jié)點(diǎn),那么:
節(jié)點(diǎn) A 包含 0 到 5500號(hào)哈希槽.
節(jié)點(diǎn) B 包含5501 到 11000 號(hào)哈希槽.
節(jié)點(diǎn) C 包含11001 到 16384號(hào)哈希槽.
這
種結(jié)構(gòu)很容易添加或者刪除節(jié)點(diǎn). 比如如果我想新添加個(gè)節(jié)點(diǎn)D, 我需要從節(jié)點(diǎn) A, B, C中得部分槽到D上.
如果我像移除節(jié)點(diǎn)A,需要將A中得槽移到B和C節(jié)點(diǎn)上,然后將沒有任何槽的A節(jié)點(diǎn)從集群中移除即可.
由于從一個(gè)節(jié)點(diǎn)將哈希槽移動(dòng)到另一個(gè)節(jié)點(diǎn)并不會(huì)停止服務(wù),所以無論添加刪除或者改變某個(gè)節(jié)點(diǎn)的哈希槽的數(shù)量都不會(huì)造成集群不可用的狀態(tài).
Redis 集群的主從復(fù)制模型
為了使在部分節(jié)點(diǎn)失敗或者大部分節(jié)點(diǎn)無法通信的情況下集群仍然可用,所以集群使用了主從復(fù)制模型,每個(gè)節(jié)點(diǎn)都會(huì)有N-1個(gè)復(fù)制品.
在我們例子中具有A,B,C三個(gè)節(jié)點(diǎn)的集群,在沒有復(fù)制模型的情況下,如果節(jié)點(diǎn)B失敗了,那么整個(gè)集群就會(huì)以為缺少5501-11000這個(gè)范圍的槽而不可用.
然而如果在集群創(chuàng)建的時(shí)候(或者過一段時(shí)間)我們?yōu)槊總€(gè)節(jié)點(diǎn)添加一個(gè)從節(jié)點(diǎn)A1,B1,C1,那么整個(gè)集群便有三個(gè)master節(jié)點(diǎn)和三個(gè)slave節(jié)點(diǎn)組成,這樣在節(jié)點(diǎn)B失敗后,集群便會(huì)選舉B1為新的主節(jié)點(diǎn)繼續(xù)服務(wù),整個(gè)集群便不會(huì)因?yàn)椴壅也坏蕉豢捎昧?/p>
不過當(dāng)B和B1 都失敗后,集群是不可用的.