Redis集群碎碎念:集群總線是個(gè)啥?
在Redis集群中,節(jié)點(diǎn)除了存儲(chǔ)數(shù)據(jù)外,還會(huì)持有其他節(jié)點(diǎn)的信息:包括把key映射到恰當(dāng)?shù)墓?jié)點(diǎn)上去。
同時(shí),集群中的節(jié)點(diǎn)能夠自動(dòng)發(fā)現(xiàn)其他節(jié)點(diǎn)、檢測(cè)失效節(jié)點(diǎn)、把從節(jié)點(diǎn)提升為主節(jié)點(diǎn)等。
那么,節(jié)點(diǎn)是如何做到這些的呢?在Redis集群中,所有的節(jié)點(diǎn)通過(guò)一個(gè)TCP總線和二進(jìn)制協(xié)議彼此進(jìn)行連接,這就是Redis集群總線。
每個(gè)節(jié)點(diǎn)都通過(guò)集群總線與其他節(jié)點(diǎn)建立連接。使用gossip協(xié)議,可以達(dá)到故障檢測(cè)、節(jié)點(diǎn)發(fā)現(xiàn)、配置信息同步等功能。每個(gè)節(jié)點(diǎn)都會(huì)定期向隨機(jī)選擇的其他節(jié)點(diǎn)發(fā)送自己的狀態(tài)信息,通過(guò)多次傳播,最終所有節(jié)點(diǎn)都能獲得整個(gè)集群的狀態(tài)。
圖片
所以,對(duì)于集群的信息,不是存在于某個(gè)節(jié)點(diǎn)上,而是在節(jié)點(diǎn)之間不斷的相互通信,從而保持集群中的節(jié)點(diǎn)信息是完整的。
由于集群總線的存在,需要每個(gè)節(jié)點(diǎn)都有一個(gè)總線端口,它默認(rèn)等于數(shù)據(jù)端口加上10000,比如16379。
由于集群總線的存在,所以節(jié)點(diǎn)都清楚了解彼此的存在,而對(duì)于客戶(hù)端的請(qǐng)求,Redis并不是通過(guò)代理的方式來(lái)處理的,而是把命令重定向到正確的節(jié)點(diǎn)上。我們來(lái)實(shí)踐看看:
先連上集群,查看fullstack的hash值,然后設(shè)置它的value,看看會(huì)發(fā)生什么:
127.0.0.1:7000> cluster keyslot fullstack
(integer) 15274
127.0.0.1:7000> set fullstack good
-> Redirected to slot [15274] located at 127.0.0.1:7002
OK
我們先連接的是7000的客戶(hù)端,而fullstack的hash槽位是15274,不是7000所存儲(chǔ)的范圍,所以自動(dòng)重定向到了7002端口。
所以客戶(hù)端不需要保存集群的狀態(tài),只要連接任意一個(gè)節(jié)點(diǎn),剩下的事情就交給集群吧。
另外,我想說(shuō)的是,編程技術(shù)很多時(shí)候都是細(xì)節(jié),那一張張所謂高大上的架構(gòu)圖,并不能解決所有問(wèn)題,所以我想通過(guò)這些“碎碎念”的系列文章把Redis集群講得透徹、深入,不論是日常開(kāi)發(fā)、維護(hù),還是應(yīng)對(duì)面試,這些都是很有價(jià)值的。
當(dāng)然,除了Redis,后續(xù)會(huì)有系列文章講解Kafka、MySQL、Java、CI/CD、Docker、分布式事務(wù)、AI等,敬請(qǐng)期待。
最后,插播一句,不要過(guò)于依賴(lài)或者過(guò)于相信AI。對(duì)于Redis集群總線,它告訴我,使用如下的命令可以查看集群總線的狀態(tài):
redis-cli -h host -p port CLUSTER BUS LIST
然而,執(zhí)行上面的命令會(huì)報(bào)錯(cuò)(替換ip、端口等信息),我使用cluster help也沒(méi)有找到bus相關(guān)的命令,恕我無(wú)知,不知道這個(gè)命令是怎么來(lái)的。給人的感覺(jué)是,就像有人說(shuō)的,AI在一本正經(jīng)的胡說(shuō)八道。