日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis集群明细文档(转)

發(fā)布時間:2025/3/17 数据库 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis集群明细文档(转) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  相信很多用過Redis的同學都知道,Redis目前版本是沒有提供集群功能的,只能單打獨斗。如果要實現多臺Redis同時提供服務只能通過客戶端自身去實現。目前根據文檔已經看到Redis正在開發(fā)集群功能,其中一部分已經開發(fā)完成,但是具體什么時候可以用上,還不得而知。本文是對其集群文檔的翻譯,文檔來源:http://redis.io/topics/cluster-spec

  總體來說,其集群沒有存在代理節(jié)點或者控制器的東西,所有節(jié)點功能一樣,并且所有節(jié)點通過一個叫做連接總線的東西上發(fā)送消息包。每個節(jié)點會連接到其他節(jié)點,每個節(jié)點都保存著該集群的狀態(tài)信息。集群中將所有的key分割成4096個slot每個節(jié)點服務于其中的若干個slot。客戶端可以講查詢請求發(fā)送到任意一個節(jié)點,當節(jié)點發(fā)現該key不是其服務對象是會返回服務該slot的節(jié)點ip,port信息。

  由于本人英文水平有限,其中也有一些自己的理解,看官僅可作為了解參考使用,任何具體內容實際驗證過才能確信。

http://redis.io/topics/cluster-spec

一、介紹

  該文檔是開發(fā)之中的redis集群實現細節(jié)。該文檔分成兩個部分,第一部分為在redis非穩(wěn)定版本代碼分支上已經實現的,另外一部分為還需要去實現的。在未來若集群實現設計變更這些都可能被修改,但是相對來說,未實現的部分相較于已經實現的部分被修改的可能性更大些。該文檔包括了實現客戶端需要的各種細節(jié),但是客戶端作者需要注意這些細節(jié)都有可能被修改。

二、什么是Redis集群

  集群是獨立服務器關于分布式與容錯實現的一個子集。在集群之中沒有中心點與代理點,設計上的一個主要目標是線性的可測量性。集群犧牲容錯來實現一致性,因此該系統(tǒng)在面對有限的子節(jié)點分離與節(jié)點錯誤時盡可能保存一致性。

可以使用節(jié)點的兩種角色來實現容錯性,即主與備。雖然節(jié)點具有相同的功能與執(zhí)行相同的服務代碼實現,但是備節(jié)點不會被使用除非用來代替丟失的主節(jié)點。也很可能使用備節(jié)點用作只讀當不需要讀然后寫的一致性時。

三、已經實現的子集

  集群實現了在非分布式版本上的所有單個命令。復雜的多命令操作例如集合sets的交集并集還沒有實現。通常情況下理論上對于不在同一個節(jié)點上的操作不會被實現。將來可能實現一種新的節(jié)點類型叫做計算節(jié)點,用于以只讀的方式在集群上進行多關鍵字的處理,但是不太可能集群中的節(jié)點自己通過某種移動關鍵字的方式處理復雜的多關鍵字問題。

  集群中的節(jié)點不像獨立服務器那樣支持多個數據庫,將會只有數據庫0,并且不支持select命令。

四、集群協(xié)議中的客戶端與服務器角色

  集群中的節(jié)點負責持有數據,知道集群的狀態(tài),包括映射鍵到正確的節(jié)點。集群節(jié)點能夠自動發(fā)現其他節(jié)點,檢測到不工作的節(jié)點,并且在必要是時候執(zhí)行備節(jié)點提升為主節(jié)點的操作。

  為了執(zhí)行任務,所有的節(jié)點都被使用一個TCP-BUS連(連接總線),并且執(zhí)行一個二進制的協(xié)議,每一個節(jié)點都使用連接總線連接到集群中的其他節(jié)點。節(jié)點為了發(fā)現新節(jié)點使用一個傳播協(xié)議用于擴散信息,發(fā)送ping消息以確認其他節(jié)點是否正常工作,并且發(fā)送集群消息需要特定的信號條件。集群連接總線也在擴展PUB/SUB信息時被使用。

  當集群中的節(jié)點不能滿足客戶端的請求時,可能會使用MOVED、ASKED命令來告知重定向。理論上客戶端允許向集群中的任意節(jié)點發(fā)送請求,如果需要時會得到重定向應答,因此客戶端不需要知道集群的狀態(tài)信息。然而客戶端可以緩存keys與節(jié)點的關系以改善執(zhí)行性能。

五、關鍵字分布式模型

  關鍵字空間被分割成4096個槽,實際上設置了集群最大節(jié)點數為4096個。然后建議的最大值為小幾百個節(jié)點。所有的主節(jié)點將處理4096個百分比的slot。當集群穩(wěn)定時(即沒有正在轉移某個slot到另外一個節(jié)點),則某個slot必定只被某個節(jié)點處理,然后某個節(jié)點可以同時處理多個槽。

  映射鍵值到指定槽值的算法如下:

  HASH_SLOT = CRC16(key) mod 4096

  在該文檔的附注1之中有CRC16算法介紹。

  使用12滿分的CRC16的16位輸出,在我們的測試之中CRC16能夠很好的將各種類型的key映射到4096的空間之中。

六、集群節(jié)點的屬性

  在集群中的每個節(jié)點都有其在集群中唯一的ID,其ID為160比特隨機數的十六進制表示。節(jié)點首次啟動時即獲取ID,節(jié)點將獲取其ID并保存在其配置文件之中,并且將一直使用該ID,直到該配置文件被系統(tǒng)管理員刪除。

  節(jié)點的ID作為集群中的節(jié)點識別,一個節(jié)點可能修改IP或地址但是不必須修改節(jié)點名稱。集群也能夠檢測到節(jié)點IP、PORT的變化然后通過連接總線發(fā)送變更的協(xié)議通知。

  每個節(jié)點都有一些相關的信息,被其他節(jié)點所知道:

  1)該節(jié)點的IP地址與端口

  2)一些標志位

  3)該節(jié)點服務的key-slot

  4)最后一次通過集群連接總線發(fā)送ping的時間

  5)最后一次收到pong的時間

  6)該節(jié)點的備份節(jié)點數

  7)如果其為備份節(jié)點,則其主節(jié)點的ID(若該節(jié)點為主節(jié)點則該值為0000000

  通過CLUSTER NODES命令可以獲取該集群中的所有節(jié)點信息,包括主節(jié)點與備份節(jié)點。

  如下為一個示例:

  $ redis-cli cluster nodes

  d1861060fe6a534d42d8a19aeb36600e18785e04 :0 myself - 0 1318428930 connected 0-1364

  3886e65cc906bfd9b1f7e7bde468726a052d1dae 127.0.0.1:6380 master - 1318428930 1318428931   connected 1365-2729

  d289c575dcbc4bdd2931585fd4339089e461a27d 127.0.0.1:6381 master - 1318428931 1318428931   connected 2730-4095

  上述顯示各項信息依次為:ID、IP:PORT、 FLAGS、最近發(fā)送PING的時間,最近接受到PONG時間、連接狀態(tài)、slots

?

七、節(jié)點間的握手(已實現)

  節(jié)點總是接受來自集群總線的端口連接請求,并且在收到ping請求時總是回復,即使ping的源節(jié)點非可信的。然而若發(fā)送端的節(jié)點非所在集群,則其消息將被丟棄。

  一個節(jié)點接受另一個節(jié)點為集群的一部分有如下兩種情況:

  1)假如一個節(jié)點使用一個MEET消息介紹自己。MEET消息很像一個PING消息,但是其要求接受者將其接受為集群的一部分。節(jié)點只有在收到管理員執(zhí)行的CLUSTER MEET ip port 命令之后才會發(fā)送MEET消息到其他節(jié)點

  2)當一個節(jié)點已經被信任時,另一個節(jié)點也可以注冊其為該集群的一部分,將擴展該消息到其他節(jié)點。假如:A知道B,B知道C,最后B將傳播伙伴信息到A與C,這時A將注冊C為該網絡的一部分,并且試圖連接到C。

  這意味著,只要我們加入節(jié)點到任意連通圖,他們最終將自動實現全連接。該項意味著集群可以自動發(fā)現新節(jié)點,但是信任關系需要有管理員設定。這種方式使得集群更加強大并且確保集群不會因為IP或PORT變更而導致多個集群互相混淆。

  所有的節(jié)點將試圖連接已知的所有其他節(jié)點。

八、移動重定向

  一個redis客戶端可以自由地將請求發(fā)送給集群中的任意一個節(jié)點,包括哪些slave節(jié)點。節(jié)點將分析查詢請求,如果不能接受將通過哈希算法計算該關鍵字歸屬的節(jié)點,如果計算出的關鍵字屬于自己處理,則查詢直接被處理,其他情況將根據該節(jié)點的持有的其他節(jié)點信息,計算出關鍵字哈希然后返回客戶端表示MOVED錯誤。

  MOVED錯誤,看起來如下:

  GET x

  -MOVED 3999 127.0.0.1:6381

  錯誤信息中包括了該key哈希出來的slot,以及服務于該slot的節(jié)點地址信息,客戶端需要重新請求到指定地址的節(jié)點。注意,假如客戶端得到該信息后很長一段時間沒有發(fā)起請求,假如集群在此時重組了各個節(jié)點服務的slot,則再次請求時有可能再次接收到MOVED錯誤。

  因此根據集群節(jié)點的視圖以ID為標示來說,我們試圖只是簡單的暴露哈希slot與節(jié)點IP,port之間的映射關系。客戶端不必須但是應該試著緩存slot3999是由 127.0.0.1 6381節(jié)點提供服務。

  這種方式當有一個新的命令需要處理時,就可以計算其slot然后請求到特定的節(jié)點能夠增加成功率。

  當集群服務穩(wěn)定后,最終所有的客戶端都有一張slot與節(jié)點的映射表,客戶端直接請求到正確的節(jié)點而不需要重定向,有助于提高集群的效率。

  客戶端應該也能夠處理本文檔描述的ASK命令的重定向。

九、集群動態(tài)重構

  集群支持在運行時動態(tài)增加與刪除節(jié)點,事實上對于增加或刪除節(jié)點執(zhí)行的是相同操作,即將處理key的slot從一個節(jié)點移動到另一個節(jié)點。

  1)增加一個新節(jié)點時,有一個空的節(jié)點添加到集群之中,同時會有一些哈希slot從現存的節(jié)點移動到新的節(jié)點上

  2)刪除一個節(jié)點,同樣的將其處理的哈希slot移動到其他節(jié)點之上

  因此實現的核心是能夠移動哈希slot,實際上,哈希slot對應的就是一組關鍵字key,因此集群在重新哈希時其實就是將一些key從一個節(jié)點移動到另一個節(jié)點。

  要理解該內容,可以通過CLUSTER子命令來手動移動節(jié)點的哈希slot,有如下命令:

  CLUSTER ADDSLOTS slot1 [slot2] ... [slotN]

  CLUSTER DELSLOTS slot1 [slot2] ... [slotN]

  CLUSTER SETSLOT slot NODE node

  CLUSTER SETSLOT slot MIGRATING node

  CLUSTER SETSLOT slot IMPORTING node

  前面兩個命令 ADDSLOTS、DELSLOTS只是簡單的從某個節(jié)點上增加刪除其處理的slot,當哈希slot分配完成后他們將通過集群協(xié)議將信息廣播到所有節(jié)點。ADDSLOTS通常用于從零配置一個集群的快速方法。SETSLOTS用于將某個哈希slot分配給指定的已存在的節(jié)點。其他情況哈希slot可以通過另外兩種方法設置:MIGRATING、INPORTING

  1)當一個哈希slot被設置成MIGRATING,該節(jié)點會接受所有對該哈希slot的查詢,但是必須是該key已經存在。其他情況,將指引一個ASK重定向到MIGRATING的目標節(jié)點

  2)當一個哈希slot被設置成IMPORTTING,該節(jié)點會接受所有對該哈希slot的查詢,但是前提是必須執(zhí)行一個ASKING命令。其他情況若客戶端沒有提供ASKING命令,則請求會被重定向到真實的服務該slot的節(jié)點上,產生一個MOVED錯誤。

  如此操作可能會奇怪,接下來會詳細說明。假定現在又兩個節(jié)點A、B,現在希望將slot 8從節(jié)點A移動到節(jié)點B,我們使用如下命令:

  We send B: CLUSTER SETSLOT 8 IMPORTING A

  We send A: CLUSTER SETSLOT 8 MIGRATING B

  此時,所有其他節(jié)點都會將查詢slot 8的請求定向到A,因此發(fā)生如下情況:

  1)所有已經存在的key查詢請求都在A中處理

  2)而所有未存在的key查詢請求都在B中處理

  這種方式我們不會在A中創(chuàng)建新的key,一個特殊的客戶端redis_trib作為集群的重配置將已經存在A中的key遷移到B之中,有如下命令執(zhí)行:

  CLUSTER GETKEYSINSLOT slot count

  該命令返回某個slot中的key數量,對于每一個返回的key都會執(zhí)行一個MIGRATE命令,該命令自動的將key從A遷移到B,這兩種情況下都將鎖定key因此沒有競爭條件。

  MIGRATE target_host target_port key target_database id timeout

?

  MIGRATE命令連接到目標實例,然后發(fā)送key的數據,當返回OK就從原有的數據庫中刪除該key,因此從外部客戶端看來同一時間key只存在于A或者B。

  在redis集群中不需要指定而外的數據庫除了0,但是遷移MIGRATE命令可以用于非集群環(huán)境中,是一個通用的命令。遷移MIGRATE命令最優(yōu)化執(zhí)行遷移復雜的key例如lists。但是重新配置集群不是一個明智的操作特別是在應用程序有時間限制的時候。

十、ASK重定向

  在上一節(jié)我們簡單談及ASK重定向,為什么我們能夠簡單的使用MOVED重定向?因為MOVED意味著我們想要某個哈希slot永遠的由另一個節(jié)點提供服務,并且后續(xù)的查詢應該和試圖到特定的節(jié)點上。ASK只要求后續(xù)的查詢到特定的節(jié)點上。之所以需要如此是由于下次查詢slot 8的可能依然在A上,因此我們希望客戶端嘗試A之后如果需要再查詢B。由于只發(fā)生于4096分之一因此執(zhí)行性能是可以接受的。

  然而我們需要確保客戶端在試圖查詢A之后才查詢B,因此B對于設置為IMPORTING的slot的查詢只接受預先發(fā)送ASKING命令的查詢。簡單地ASKING命令用于設置一個標志位使得節(jié)點能夠為設置為IMPORTING的slot提供服務。

  因此對于ASK重定向,客戶端語義如下:

  1)若在發(fā)送查詢特定節(jié)點時收到ASK重定向信息

  2)使用ASKING請求作為命令的開始

  3)當前不需要修改本地的緩存將slot 8指向B

  當哈希slot 8遷移完成時,A將發(fā)送一個MOVED錯誤,此時客戶端可以將slot 8查詢緩存定向到B。即使客戶端過早的將slot 8緩存指向B,當想B查詢時沒有發(fā)送ASKING開頭,則B將會返回一個MOVED錯誤指向A。

十一、客戶端需要實現

  TODO Pipelining: use MULTI/EXEC for pipelining.

  TODO Persistent connections to nodes.

  TODO hash slot guessing algorithm.

?

容錯機制
十二、節(jié)點的錯誤檢測

  錯誤檢查使用如下機制:

  1)在一段時間內節(jié)點未響應發(fā)出的PING消息,則將其設置為PFAIL(可能錯誤)狀態(tài)。

  2)當ping其他節(jié)點時隨機帶上其他三個節(jié)點的信息,在信息的gossip節(jié)部分帶上其他節(jié)點的flag

  3)假如有一個節(jié)點設置為PFAIL,并且在收到的PING回復中其他節(jié)點也將其設置為PFAIL則將其設置為FAIL狀態(tài)

  4)當一個節(jié)點確認某個另外節(jié)點為FAIL時則發(fā)送消息到所有其他節(jié)點,強制收到該消息的節(jié)點將其設置為FAIL狀態(tài)

  因此一個節(jié)點在沒有獲取外面消息時無法獨立地將某個另外節(jié)點設置為FAIl

  仍然需要實現:當一個節(jié)點被標記為FAIL,當其他節(jié)點收到該節(jié)點的請求或連接時,將回復其“MARK AS FAIL”,當收到該消息時需要強制將自身設置為FAIL狀態(tài)。

十三、集群狀態(tài)檢查(部分實現)

  當集群發(fā)生變更時(更新slot或者一個節(jié)點被設置為fail等)每個節(jié)點都將檢查其保持的節(jié)點列表。

  一旦配置節(jié)點進入如下的階段:

  1)FAIL:集群不能工作,當一個節(jié)點進入該狀態(tài),所有的請求將被拒絕并且返回一個錯誤。當節(jié)點檢查到集群不能同時為4096個slot提供服務時進入該狀態(tài)

  2)OK:集群工作正常:所有的4096個slot都能夠被節(jié)點服務到并且沒有FAIL節(jié)點

  這意味著集群在不能為所有的4096個slot提供服務時停止工作。然而有一部分時間一個slot不能被訪問因為相關聯(lián)的節(jié)點有問題,但是該節(jié)點還未被設置為FAIL。在此時集群只能為其中的部分slot提供訪問服務。

  由于集群不支持MULTI、EXEC執(zhí)行命令,因此程序員需要確保應用程序能夠從只有一部分查詢被集群接受的狀態(tài)中恢復。

十四、備節(jié)點選擇(未實現)

  每一個主節(jié)點都能夠有任意數量的從節(jié)點。從節(jié)點負責在主節(jié)點fail時設置自己為主節(jié)點。舉例:我們有節(jié)點A1,A2,A3其中A1為主節(jié)點,A2,A3為從節(jié)點。假如A在某個階段FAIL并且沒有響應ping請求,最終其他節(jié)點通過gossip協(xié)議會將其設置為fail,當發(fā)生這種情況時,它的第一個從節(jié)點需要嘗試執(zhí)行選擇。第一個從節(jié)點的概念非常簡單。所有的從節(jié)點根據node id進行排序,最小的就為第一個從節(jié)點,依次類推,當第一從節(jié)點也被標記為fail,在后續(xù)節(jié)點執(zhí)行該選擇未主節(jié)點,以此類推。

  當一個配置變更時,錯有從節(jié)點檢查自身主節(jié)點是否為fail,若是則變更自身狀態(tài)為主節(jié)點并發(fā)送到所有的其他節(jié)點以變更配置。

?

十五、保護模式(未實現)

  當網絡不連通導致有孤立節(jié)點時,該節(jié)點會認為所有其他節(jié)點都為fail。這種時候他可能試圖選擇從節(jié)點或者更改集群配置。為了避免這種情況,節(jié)點認定其他主要節(jié)點為pfail或fail要足夠長的時間以避免其采取其他動作。

  保護模式被清除之后,集群狀態(tài)就恢復正常了。

十六、主要的主節(jié)點規(guī)則

  作為網絡分離的結果之一,兩個或多個分割的部分可能為所有的哈希slot提供服務。由于集群努力保持一致性,這種情況不是我們想要的,而且網絡分割總是產生零個或單個可供操作的部分。如果他們有大部分原來的主節(jié)點,當這些規(guī)則節(jié)點被放到一個部分之中他們應該只提供查詢服務。

?

?

十七、分發(fā)與訂閱(未實現需要重定義)

  在一個集群中的客戶端能夠訂閱任何一個節(jié)點,也能夠發(fā)布到任何一個節(jié)點。集群將確保若需要能夠得到轉發(fā)。當前實現只是簡單地廣播訂閱消息到所有節(jié)點,在某些時候這些將通過過濾或其他算法。

?

附注A(CRC16) ANSI C中關于CRC16的實現

?

http://www.cnblogs.com/chang290/archive/2012/09/05/2672506.html

轉載于:https://www.cnblogs.com/softidea/p/5365614.html

總結

以上是生活随笔為你收集整理的Redis集群明细文档(转)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。