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

歡迎訪問 生活随笔!

生活随笔

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

数据库

Redis Cluster原理初步

發布時間:2024/1/17 数据库 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis Cluster原理初步 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

目錄 1

1.?前言 1

2.?槽(slots 1

3.?路由配置(node.conf 1

4.?總slots數(cluster.h:16384 2

5.?key的路由 2

6.?將key轉成整數值(crc16.c:crc16 2

7.?計算key所在slotcluster.c:keyHashSlot 2

8.?Redis?Cluster?Client實現 3

?

1.?前言

截至2016/5/16最新版本的redis-3.2.0仍然非強一致性,基于性能考慮master和它的slaves間數據是異步復制的。另外,一個確定的key總是只會落到確定的master,除非使用redis-trib.rb等工具修改slotsmaster間的綁定關系,目前的redis?cluste不支持自動從一個master遷移一個slot到另一個masterslavesslots來說,可以認為和對應的master相同)。

2.?槽(slots

Redis?cluster將所有存儲在其上的key通過一個hash算法劃分成若干slots,當前為16384slots,值在cluster.h文件中由宏CLUSTER_SLOSTS指定。

3.?路由配置(node.conf

存儲的內容和redis命令“cluster?nodes”的輸出相同,即存儲了masterslave信息,以及各master存儲的slots,亦即slots的路由信息存儲在node.conf

同一Redis?cluster中的所有節點的node.conf文件內容最終是一致的。

4.?總slots數(cluster.h:16384

#define?CLUSTER_SLOTS?16384?//?等于(0x3FFF?+?1)

?

CLUSTER_SLOTS定義了redis?clusterslots數,理論上這個值應當可以修改重編譯。其值越大,相對更容易均衡,可支撐更多節點數的集群(實際受限于無中心節點,當然架構的redis?cluster節點數不宜過大,否則可能引起網絡風暴)。

5.?key的路由

->?key轉成整數值

->?計算key所在的slot

->?找到slot所在的masterslavesredis?cluster可配置允許slaves提供讀)

->?轉成直接對masterslaves的請求。

?

由于任何一個redis?cluster節點都存儲了相同內容的node.conf,所以client可以請求任一節點獲得slots的路由數據。

而且由于node.conf中包含了masterslaves信息,因此讀寫操作可以完美的路由到相應的節點。

6.?將key轉成整數值(crc16.c:crc16

Redis使用crc算法將一個字符串轉成整數,CLUSTER_SLOTS的值是不能超過CRC返回的最大值。

uint16_t?crc16(const?char?*buf,?int?len)?{

????int?counter;

????uint16_t?crc?=?0;

????for?(counter?=?0;?counter?<?len;?counter++)

????????????crc?=?(crc<<8)?^?crc16tab[((crc>>8)?^?*buf++)&0x00FF];

????return?crc;

}

7.?計算key所在slotcluster.c:keyHashSlot

對于一個redis?KEY它歸屬于哪一個slot,這個可以通過函數keyHashSlot()調用計算出來:

unsigned?int?keyHashSlot(char?*key,?int?keylen)?{

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

?

????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)?&?0x3FFF;

?

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

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

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

?

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

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

?

????/*?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)?&?0x3FFF;?//?3FFF即為16383

}

8.?Redis?Cluster?Client實現

通過上面的信息,不然發現,Redis?Cluster?Client只是在原來單機版client基礎上多了一層薄的路由邏輯。因此可以基于現有的hiredis等實現支持redis?clusterclient庫。大致過程如下:

class?CRedisClusterClient

{

public:

????//?nodes?Redis集群中的單個或多個節點,格式為:ip1:port1,ip2:port2,如:127.0.0.1:6379,127.0.0.1:6380,192.168.31.11:6379

????CRedisClusterClient(const?std::string&?nodes);

????void?set(const?std::string&?key,?const?std::string&?value)?const;

????void?get(const?std::string&?key,?std::string*?value);

?

private:

????redisContext*?_redis_context;?//?hiredis

};

?

set()函數實現:

1)?CRedisClusterClient從nodes取任一nodeA,如:127.0.0.1:6380

2)?建立與nodeA的連接

3)?從nodeA取得slots路由數據(實現時可緩存這部分數據,以提升性能)

4)?構造slots路由數據表(由于slots總數有限,可以以slot為下標數組方式組織路由表)

5)?計算key所在的slot

6)?找到slot所在的nodeB(對于寫操作,要求nodeBmaster,有可能碰巧就是nodeA

7)?使用hiredis訪問nodeB(從這步開始和原使用hiredis相同)

8)?取得hiredis返回的結果

?

如果使用hiredis發生網絡異常,對于寫操作從第3步開始重執行,對于讀操作從第6步重選一個node重執行。

?

轉載于:https://www.cnblogs.com/aquester/p/9891529.html

總結

以上是生活随笔為你收集整理的Redis Cluster原理初步的全部內容,希望文章能夠幫你解決所遇到的問題。

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