1. 程式人生 > >Redis cluster 規範

Redis cluster 規範

redis cluster規範的官方文件,yinmingjun翻譯

Redis cluster規範

Redis Cluster目標

Redis ClusterRedis的一個分散式的實現,有下面這些目標,按設計上的重要程度列出:

  • 高效能和線性的擴充套件性,可以支援到1000個節點。

  • Redis的資料模型層面,沒有必須的因為值大小和語義而要做的操作合併。

  • 寫安全:系統嘗試保留所有的來自客戶端連線的到節點主體的寫。然而,還是會存在寫丟失的可能性。

  • 可用性:Redis Cluster能在主體的master節點群的可以連線到的情況下,並且每個連線不上的

    master節點都至少有一個可以連線的slave時,保障分割槽的可用性。

本文描述的是Github Redisunstable程式碼分支。Redis Cluster目前進入了beta階段,每個月都會有新的release,可以在Redisweb站點的找到。

實現的子集

Redis Cluster實現了所有的非分散式版本的Rediskey的命令。那些執行復雜的多key操作的命令,如Set型別的並集或子集的實現是假設所有的key都從屬於相同的節點。

Redis Cluster的實現有一個hash tags的概念,可以強制那些key是從屬於相同的節點。然而,在手工的

reshardings的過程中,多key的操作會變得一段時間不可用,而單key操作總是可用。

Redis Cluster不支援多databases。只是選擇database 0,並且命令是不可用的。

客戶端和伺服器在Redis cluster協議中的角色

Redis cluster中,節點用於儲存資料,並儲存cluster的狀態,包括對映key到正確的節點。Cluster的節點也能自動發現其他的節點,探測不能工作的節點,並在必要的情況下執行slave節點代master節點的選舉。

未來執行所有cluster節點的會話,所有節點使用一個TCP匯流排和一個二進位制的協議互聯(

cluster bus)。每個節點和每個cluster的其它的節點使用cluster bus連線。節點之間使用gossip協議傳播cluster的資訊,用於發現新節點,傳送ping包來確保其它的節點都能正確的工作,併發送必要的cluster訊息來傳遞針對特定條件的訊號。cluster bus還用於傳遞跨越clusterPub/Sub訊息。

由於cluster的節點不能作為客戶端請求的代理,客戶會根據節點返回的錯誤資訊-MOVED-ASK來重定向請求。客戶端在理論上是可以想cluster中的所有的節點發送請求,在必要的時候來處理重定向,因此客戶端不被要求瞭解cluster的狀態。然而,客戶端可以瞭解和快取key和節點直接的對映關係,用一種明智的方式來提高效能。

寫安全

Redis Cluster在節點之間使用非同步的複製,因此總是有這樣的可能會在寫的時候丟失資料。然而,這些情況與一個客戶端連線到master的主體,而另外一個客戶端和master的一小部分相連的情況是非常不同的。

Redis Cluster會最大程度上保留客戶端在master的主體中寫入的資料,有2個例外:

1)一個寫入也許到達一個master,但當這個master可以應答這個client的時候,寫入也許還沒有經過主從之間的非同步複製傳遞到slaves。如果master在寫到slaves之前死掉,這個寫入會因為這個master因一個足夠長的期間不能聯絡上而導致它的一個slaves被升級,從而這個寫入會永久的丟失。

2)另外一個理論上存在的寫丟失的錯誤的模式有:

  • 因為分割槽導致的一個master聯絡不上。

  • 被它的一個slaves發起故障恢復。

  • 過了一些時間,它有能聯絡上了。

  • 一個客戶端使用未更新的路由表在這個mastercluster配置成一個slave(新master的)之前寫入到這個節點。

實際上這是非常不可能發生的,因為節點如果足夠長的時間不能聯絡上主體中的其它的master,就會觸發故障恢復,也就不再接收寫入,並且當分割槽被修復之後,在一小段時間之內還是會拒絕寫入,使其它的節點能感知配置的變更。

當存在一個master的小分割槽連著一個或多個客戶端的情況下,Redis Cluster會丟失不確定數量的對分割槽的寫入,因為所有對master的寫入都會因為主體的故障恢復而有潛在的丟失的可能性。

特別,對於一個即將執行故障恢復的master,它一定是不能沒master的主體至少NODE_TIMEOUT的時長後沒聯絡上,因此如果在這個時間內分割槽被修復,不會有寫入丟失。

當一個分割槽丟失超過NODE_TIMEOUT時長,小分割槽的一側會在超過NODE_TIMEOUT時長之後開始拒絕寫入,所以在小分割槽形成到小分割槽變得不再可用之間存在一個最大化的視窗期,因為在這個時間之後不會再接收寫入。

可用性

Redis Cluster在小分割槽一邊變得不再可用。在主分割槽一側假設存在每個不再可用的master都存在一個slavecluster會在NODE_TIMEOUT時長加上幾秒slave選舉和對master的錯誤恢復的時間之後變得可用。

這表示Redis Cluster在設計上可以對抗幾個節點失效的故障,但不是應用需要的面向大的網路分裂事件的可用性的完備的方案。

在這個例子中,一個clusterNmaster節點組成,每個節點都有一個slavecluster的主體一側將在一個單獨的節點出現分割槽後繼續可用,並在2個節點分離開之後,繼續1-(1/(N*2-1))的概率保持可用性(在第一個節點失效之後,還剩總計N*2-1個節點,而單個master不包括複製失敗的概率是1/(N*2-1))。

例如,5個節點的cluster每個節點有一個slave,是1/(5*2-1) = 0.1111,在兩個節點從主體分離,cluster將不再可用,這個概率大概是11%

感謝Redis Cluster的一個replicas migration的特性,由於支援副本遷移到獨立的master的特徵,提高了Cluster在真實世界的可用性(master不再有副本)。

效能

Redis Cluster中,節點不會將指定的key轉發到指定的節點,但會通過提供key的分割槽協助客戶端重定向到正確的節點。

最終,客戶端會獲取並更新cluster中那些節點對應那些key的表達,因此在經過一些正常的活動後,客戶端可以直接傳送命令到正確的節點。

因為非同步複製的使用,節點不會等待其它的節點的寫操作的反饋(可以選擇的同步複製正在開發中,未來可能會新增到release之中)。

另外,因為存在不支援多key命令的命令子集的限制,資料在除了resharding之外是不會在節點之間複製的。

所以,一般的操作就像單redis例項一樣來處理。這表示一個有Nmaster節點的Redis Cluster可以具有單個Redis例項N倍的效能,作為設計上承諾的線性的擴充套件能力。同時,查詢通常是單個的往返,由於clients通常保留到節點的持久連線,因此延時也會像單Redis例項一樣。

對於高效能和高可擴充套件性,和相對弱一些(非CAP),但是合理的一致性和可用性的方式,是Redis Cluster的設計的主要目標。

為什麼要避免合併操作

Redis Cluster設計上避免相同key-value對在多個節點之間的版本衝突,由於Redis的資料模型並不是總是可取的:Redis中的值通常非常大,一般是有數百萬成員的列表或排序集合。或資料型別的語義複雜。傳輸或合併這些值會成為一個大的瓶頸,也許是應該在客戶端一側提供一個非通用的解決方案。

key的分佈模式

key的空間被分成16384個槽,有效的cluster的節點的上限是16384個節點(然而建議的最大的節點數是~1000個節點)。

所有的master節點會處理16384hash槽中一定比例的槽。當cluster處於穩定的狀態,這表示cluster中沒有重新配置的操作在處理(那樣hash槽會從一個節點移動到另外一個節點)一個hash槽會明確的被一個節點來處理(但是處理的節點可以有一個或多個slave節點在出現網路分裂或故障的時候來替換它)。

用於對映keyhash槽的基本的演算法是下面(讀下一個小節來看hash tag的例外情況):

HASH_SLOT = CRC16(key) mod 16384

CRC16是指下面:

  • Name: XMODEM (also known as ZMODEM or CRC-16/ACORN)

  • Width: 16 bit

  • Poly: 1021 (That is actually x^16 + x^12 + x^5 + 1)

  • Initialization: 0000

  • Reflect Input byte: False

  • Reflect Output CRC: False

  • Xor constant to output CRC: 0000

  • Output for "123456789": 31C3

CRC1616位輸出的14位被使用(這就是為在什麼在上面的公式中對16384取模的原因)。

在我們的測試中,CRC16在分發不同型別的可以到最終的16384hash槽的過程中表現的非常優異。

注意:使用的是一個CRC16演算法的參考實現,在附錄A中能看到。

keyhash tag

hash槽的計算上這裡存在一個例外,就是實現hash tagshash tags是一種保障兩個key可以存在於相同的hash槽的方式。這用於在Redis Cluster中實現多key操作。

為了實現hash tagshash slot的計算過程有所不同。基本上,如果一個key包含"{...}"的形式,那麼只有{}之間的字串用於計算hash來獲取一個hash槽。然而,由於存在這種可能性會出現多個{},在演算法明確了下面的規則:

  • 如果key包含一個{字元。

  • 如果在{的右邊有一個}字元。

  • 存在一個或多個字元在首次出現的{和首次出現的}之間

那麼使用其來替代這個key來做hash,只有首次出現的{和其右側首次出現的}之間的內容用來做hash

例如:

  • 有兩個key{user1000}.following{user1000}.followers將具有相同的hash槽,因為它們都使用user1000子字串來計算hash槽的hash值。

  • keyfoo{}{bar}的整個key會被用來計算hash值,因為它首次出現的{和其右側首次出現的}之間沒有字元。

  • keyfoo{{bar}}zap的子字串{bar會被用來計算hash值,因為它是首次出現的{和其右側首次出現的}之間的字元。

  • keyfoo{bar}{zap}的子字串bar會被用來計算hash值,因為演算法會在第一次的有效或無效({}之間沒有子字串)的{}的匹配之後停止。

  • 如果key{}開頭無論後面是什麼,演算法保證整個key會作為一個整體來算hash。這在使用二進位制資料做key的時候會用到。

增加了這個hash tags的例外,下面是使用RubyC語言給出的HASH_SLOT函式的實現。

Ruby程式碼:

def HASH_SLOT(key)

    s = key.index "{"

    if s

        e = key.index "}",s+1

        if e && e != s+1

            key = key[s+1..e-1]

        end

    end

    crc16(key) % 16384

end

C程式碼:

unsigned int HASH_SLOT(char *key, int keylen) {

    int s, e; /* start-end indexes of { and } */

    /* Search the first occurrence of '{'. */

    for (s = 0; s < keylen; s++)

        if (key[s] == '{') break;

    /* No '{' ? Hash the whole key. This is the base case. */

    if (s == keylen) return crc16(key,keylen) & 16383;

    /* '{' found? Check if we have the corresponding '}'. */

    for (e = s+1; e < keylen; e++)

        if (key[e] == '}') break;

    /* No '}' or nothing between {} ? Hash the whole key. */

    if (e == keylen || e == s+1) return crc16(key,keylen) & 16383;

    /* If we are here there is both a { and a } on its right. Hash

     * what is in the middle between { and }. */

    return crc16(key+s+1,e-s-1) & 16383;

}

Cluster節點的屬性

cluster中的每個節點都有一個唯一的名字。節點的名字是一個160 bit的隨機數,在這個節點首次啟動的時候獲取(一般使用/dev/urandom)。

節點會儲存它的ID到節點的配置檔案,並會永遠的使用這個ID,直到這個節點的配置檔案被管理員刪除。

節點的ID用來在整個cluster中識別節點。因此有可能一個指定的節點在不變更其節點ID的情況下,變更其IP/埠。cluster也可以感知一個節點的IP/埠的變化,並通過cluster bus上執行的gossip協議重新配置和廣播這些資訊。

每個節點都有一些其它節點應該瞭解的關聯資訊:

  • 節點的IP地址和TCP埠。

  • 一個標誌集。

  • 節點的hash槽的集合。

  • 最近一次使用cluster bus傳送ping包的時間。

  • 最近一次我們收到pong包的回覆時間。

  • 這個節點我們標記為失效的時間。

  • 這個節點的slave的數量。

  • 如果這個節點是slave,它的master節點的ID(如果這個節點是master,這個值是0000000...

一些資訊可以使用CLUSTER NODES命令傳送到一個cluster的任意的節點來獲取群集的資訊,無論是master節點還是slave節點。

下面是一個3節點的小cluster的傳送CLUSTER NODES到一個master節點的輸出的例子。

$ 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、地址:埠、標誌位、最近ping傳送時間、最近pong響應時間、連線狀態、槽數量。

Cluster拓撲結構

Redis cluster是一個完整的網格,每個節點都與每一個其它的節點通過TCP連線。

在一個N節點的cluster中,每個節點都有N-1個對外的TCP連線和N-1個向內的連線。

這些TCP連線一直保持活躍,不需要人工干預。

節點握手

節點總是從cluster bus的埠接收連線,甚至響應所有收到的ping,即便這些ping的節點可能不是信任的節點。然而,如果這個節點不是這個cluster的一部分,那麼它傳送所有包都會被丟棄。

有兩種方式,可以讓一個節點會接受其它的節點成為這個cluster的一部分:

  • 如果一個節點使用MEET訊息來展示自己。一個meet訊息和PING訊息極為相似,但是會迫使接收者接收這個節點成為cluster的一部分。系統管理員執行下面的命令,會讓節點發送MEET訊息到其它節點:

CLUSTER MEET ip port

  • 如果一個節點已經通過

    相關推薦

    去中心Redis-Cluster規範(三)-重定向和重雜湊

    去中心Redis-Cluster規範(三) 本文翻譯自官方文件 重定向和重雜湊 MOVED重定向 Redis客戶端可以自由想叢集內的任何節點(包括從節點)傳送查詢指令.收到指令的節點會分析查詢指令,如果指令可接受(查詢指令中只有一個key,或者多

    Redis cluster 規範

    redis cluster規範的官方文件,yinmingjun翻譯 Redis cluster規範 Redis Cluster目標 Redis Cluster是Redis的一個分散式的實現,有下面這些目標,按設計上的重要程度列出:

    redis-cluster的安裝管理

    redis-cluster redis redis集群部署 redis-cluster的安裝管理 聲明:本文只允許用於個人學習交流使用,如有錯誤之處請多多指正。文檔版本:Version 1.0修改記錄:2015-10-30環境介紹系統環境:RedHat Enterprise Linux Serve

    在 Windows 上測試 Redis Cluster的集群填坑筆記

    san hat aix gdb ima erl omx ngs isa %E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A8%8B%E5%BA%8F%E7%9A%84%E6%80%9D%E7%BB%B4%E9%80%BB%E8%BE%91%2010%20-%2

    Redis安全規範----check list

    redis安全Redis安全規範—-check list.1.信任的內網運行,盡量避免有公網訪問在/etc/redis/redis.conf中配置如下: bind 127.0.0.12.綁定redis監聽的網絡接口如果服務器有多個IP,可限定redis server監聽的IP,通過redis配置項bind,可

    虛擬機搭建redis單機版及redis-cluster,使用redis desktop manager和java(eclipse)連接redis過程遇到問題匯總

    init clu centos 一律 有用 tex 保護模式 bin service 如果你看到這裏,我默認你已經安裝好了redis,並且已經成功的在虛擬機的Linux系統中ping通。 介紹一下我的環境:VMware虛擬機安裝centos 6.5版的Linux系統,red

    第十三章 redis-cluster原理

    執行命令 shm 擴容 一段時間 本地 集群 端口號 保存 ron 一、基本定義 虛擬槽slot分區算法,優點是擴容縮容簡單:直接把slot及每個slot上的數據進行縮放即可 redis定義了0-16383(總共為16384個slot,即214個slot) slot會均勻

    redis cluster 實踐總結

    監聽 截至目前 實踐 啟動 但是 -- 是什麽 size 發現 最近項目接觸到了redis cluster,現在趁著使用做一下總結,記錄一下遇到過的問題,簡單的概述一下常用到的命令和功能。 本篇文章主要是以運維的角度去講述如何去更好的規劃redis cluster和跳坑

    JFinal redis cluster集群插件

    ext 註意 param nal system static private rim spa JFinal redis cluster集群插件 JFinal 框架到了2.1版本號,可是依舊僅僅支持redis的主從集群,沒有看到Cluster集群的插件。筆者

    redis cluster

    增加 對數 沒有 端口號 cover clas 刪除 org actor redis cluster 集群命令 註 :這些命令是集群所獨有的。執行下述命令要先登錄(集群已經創建 )集群配置文件:需註意 cluster-migration-barrier 1 clu

    predis連接redis sentinel和redis cluster

    predis的使用 predis連redis cluster predis連redis sentinel 開發之前都是用phpredis連接redis服務的,後來隨著sentinel和redis cluster的成熟,redis主從都結合sentinel做了高可用,部分數據和並發大的業務使

    多節點 安裝redis cluster安裝部署-4.0.1

    redis cluster 4.0 安裝、配置 環境節點數量IP:172.17.7.11 CPU :12 核 MEM:96G 啟動服務數量:6 使用端口:7001~12IP:172.17.7.25 CPU :12 核 MEM:96G 啟動服務數量:6 使用端口:70

    Windows 配置Reids集群 Redis Cluster

    下載 com all 不支持 支持 由於 ble ech 功能 1. 下載安裝Redis Redis官方不支持Windows,但是Microsoft Open Tech group在 GitHub上開發了一個Win64的版本,下載地址為: 下載Redis 啟動服

    Redis Cluster 添加/刪除 完整折騰步驟

    slot redis clust Redis還是挺好玩的,今天測試了集群的添加、刪除節點、重分配slot等。更深入的理解redis的遊戲規則。步驟繁多,但是詳細。環境解釋:我是在一臺Centos 6.9上測試的,各個redis節點以端口號區分。文中針對各個redis,我只是以端口號代表。~~~~M

    Redis Cluster 4.0 on CentOS 6.9 搭建

    combine zip config 失效 對應關系 誰的 direct iss 新節點 集群簡介 Redis 集群是一個可以在多個 Redis 節點之間進行數據共享的設施(installation)。 Redis 集群不支持那些需要同時處理多個鍵的 Redis 命令, 因

    Ubuntu 16.04下Redis Cluster集群搭建(官方原始方案)

    選擇 正數 mil 請求 點數據 包含 最終 util 交互 前提:先安裝好Redis,參考:http://www.cnblogs.com/EasonJim/p/7599941.html 說明:Redis Cluster集群模式可以做到動態增加節點和下線節點,使用起來非常

    Redis Cluster集群搭建後,客戶端的連接研究(Spring/Jedis)(待實踐)

    turn ron 記錄 redis div println 刪除 clu name 說明:無論是否已經搭建好集群,還是使用什麽樣的客戶端去連接,都是必須把全部IP列表集成進去,然後隨機往其中一個IP寫。 這樣做的好處: 1、隨機IP寫入之後,Redis Cluster代

    Redis Cluster 介紹與搭建

    不能 使用 不同的 may 代理服務 解耦 enabled 相對 討論 轉:http://blog.csdn.net/men_wen/article/details/72853078 Redis Cluster 介紹與搭建 1. Redis Cluster介紹 Redis

    centos6下redis cluster集群部署過程

    pap des .sh gcc con 不兼容 migrating 升級ru messages 一般來說,redis主從和mysql主從目的差不多,但redis主從配置很簡單,主要在從節點配置文件指定主節點ip和端口,比如:slaveof 192.168.10.10 6

    Redis Cluster集群總結性梳理

    from 等等 skiplist 數據訪問 更新 1.10 都沒有 daemon rst 前面已經介紹了Redis Cluster集群及其部署過程,下面再補充下有關Redis Cluster應用原理部分內容,以便更加深刻透徹地理解Redis Cluster。 一、Red