redis集群 第三節(jié) 在集群中執(zhí)行命令

在對(duì)數(shù)據(jù)庫中的16384個(gè)槽都進(jìn)行了指派之后,集群就會(huì)進(jìn)入上線狀態(tài),這時(shí)客戶端就可以向集群中的節(jié)點(diǎn)發(fā)送數(shù)據(jù)命令了。
當(dāng)客戶端向節(jié)點(diǎn)發(fā)送與數(shù)據(jù)庫鍵有關(guān)的命令時(shí),接收命令的節(jié)點(diǎn)會(huì)計(jì)算出命令要處理的數(shù)據(jù)庫鍵屬于哪個(gè)槽,并檢查這個(gè)槽是否指派給了自己:

  • 如果鍵所在的槽正好就指派給了當(dāng)前節(jié)點(diǎn),那么節(jié)點(diǎn)直接執(zhí)行這個(gè)命令
  • 如果將所在的槽并沒有指派給當(dāng)前節(jié)點(diǎn),那么節(jié)點(diǎn)會(huì)向客戶端返回一個(gè)MOVED錯(cuò)誤,指引客戶端轉(zhuǎn)向(redirect)至正確的節(jié)點(diǎn),并在此發(fā)送之前想要執(zhí)行的命令。

本節(jié)接下來的內(nèi)容將介紹計(jì)算鍵所屬槽的方法,節(jié)點(diǎn)判斷某個(gè)槽是否由自己負(fù)責(zé)的方法,以及MOVED錯(cuò)誤的實(shí)現(xiàn)方法,最后,本節(jié)還會(huì)介紹節(jié)點(diǎn)和單機(jī)Redis服務(wù)器保存鍵值對(duì)的相同和不同之處。

3.1 計(jì)算鍵屬于哪個(gè)槽

節(jié)點(diǎn)使用以下算法來計(jì)算給定鍵key屬于哪個(gè)槽:

def slot_number(key):
return CRC16(key) & 16383

其中CRC16(key)語句用于計(jì)算鍵key的CRC-16校驗(yàn)和,而&16383語句則用于計(jì)算出一個(gè)介于0至16383之間的整數(shù)作為鍵key的槽號(hào)。
使用CLUSTER KEYSLOT <key>命令可以查看一個(gè)給定鍵屬于哪個(gè)槽,以下是該命令的偽代碼實(shí)現(xiàn):

def CLUSTER_KEYSLOT(key):
# 計(jì)算槽號(hào)
slot = slot_number(key)
# 將槽號(hào)返回給客戶端
reply_client(slot)

3.2 判斷槽是否由當(dāng)前節(jié)點(diǎn)負(fù)責(zé)處理

當(dāng)節(jié)點(diǎn)計(jì)算出鍵所屬的槽i之后,節(jié)點(diǎn)就會(huì)檢查自己在clusterState.slots數(shù)組中的項(xiàng)i,判斷鍵所在的槽是否由自己負(fù)責(zé):

  • 如果clusterState.slots[i]等于clusterState.myself,那么說明槽i由當(dāng)前節(jié)點(diǎn)負(fù)責(zé),節(jié)點(diǎn)可以執(zhí)行客戶端發(fā)送的命令。
  • 如果clusterState.slots[i]不等于clusterState.myself,那么說明槽i并非由當(dāng)前節(jié)點(diǎn)負(fù)責(zé),節(jié)點(diǎn)會(huì)根據(jù)clusterState.slots[i]指向的clusterNode結(jié)構(gòu)所記錄的節(jié)點(diǎn)IP和端口號(hào),向客戶端返回MOVED錯(cuò)誤,指引客戶端轉(zhuǎn)向至正在處理槽i的節(jié)點(diǎn)。

3.3 MOVED錯(cuò)誤

當(dāng)節(jié)點(diǎn)發(fā)現(xiàn)鍵所在的槽并非由自己負(fù)責(zé)處理的時(shí)候,節(jié)點(diǎn)就會(huì)向客戶端返回一個(gè)MOVED錯(cuò)誤,指引客戶端轉(zhuǎn)向至正在負(fù)責(zé)槽的節(jié)點(diǎn)。

MOVED錯(cuò)誤的格式為:

MOVED <slot> <ip>:<port>

其中slot為鍵所在的槽,而ip和port則是負(fù)責(zé)處理槽slot的節(jié)點(diǎn)的IP地址和端口號(hào)
當(dāng)客戶端接收到節(jié)點(diǎn)返回的MOVED錯(cuò)誤時(shí),客戶端會(huì)根據(jù)MOVED錯(cuò)誤中提供的IP地址和端口號(hào),轉(zhuǎn)向至負(fù)責(zé)處理槽slot的節(jié)點(diǎn),并向該節(jié)點(diǎn)重新發(fā)送之前想要執(zhí)行的命令。
一個(gè)集群客戶端通常會(huì)與集群中的多個(gè)節(jié)點(diǎn)創(chuàng)建套接字連接,而所謂的節(jié)點(diǎn)轉(zhuǎn)向?qū)嶋H上就是換一個(gè)套接字來發(fā)送命令。
如果客戶端尚未與想要轉(zhuǎn)向的節(jié)點(diǎn)創(chuàng)建套接字連接,那么客戶端會(huì)現(xiàn)根據(jù)MOVED錯(cuò)誤提供的IP地址和端口號(hào)來連接節(jié)點(diǎn),然后再進(jìn)行轉(zhuǎn)向。

3.4 節(jié)點(diǎn)數(shù)據(jù)庫的實(shí)現(xiàn)

節(jié)點(diǎn)和單機(jī)服務(wù)器在數(shù)據(jù)庫方面的一個(gè)區(qū)別是,節(jié)點(diǎn)只能使用0號(hào)數(shù)據(jù)庫,而單機(jī)Redis服務(wù)器則沒有這一限制。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文檔翻譯自 http://redis.io/topics/cluster-tutorial 。 本文檔是 Red...
    會(huì)跳舞的機(jī)器人閱讀 67,064評(píng)論 2 21
  • Redis Cluster原理分析 文章較長(zhǎng),如需轉(zhuǎn)載可分段。轉(zhuǎn)載請(qǐng)標(biāo)明作者以及文章來源,謝謝! 作者介紹 姓名:...
    lihanglucien閱讀 20,738評(píng)論 3 30
  • 1 Redis介紹1.1 什么是NoSql為了解決高并發(fā)、高可擴(kuò)展、高可用、大數(shù)據(jù)存儲(chǔ)問題而產(chǎn)生的數(shù)據(jù)庫解決方...
    克魯?shù)吕?/span>閱讀 5,707評(píng)論 0 36
  • 基本目標(biāo)與設(shè)計(jì)基本思想 Redis cluster 目標(biāo) 高性能,并且能線性擴(kuò)展到1000個(gè)節(jié)點(diǎn)。不需要代理,使用...
    tafeng閱讀 2,857評(píng)論 0 0
  • 過了十一,一切都不想去做,一直有愿望去四川看大熊貓,能日復(fù)一日的陪伴熊寶寶也是一種幸福吧? 如果有一天自己養(yǎng)的寶寶...
    Wanda_ff08閱讀 246評(píng)論 0 0

友情鏈接更多精彩內(nèi)容