欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Redis集群節(jié)點(diǎn)通信過程/原理流程分析

 更新時(shí)間:2022年03月18日 11:35:35   作者:IT利刃出鞘  
這篇文章主要介紹了Redis集群節(jié)點(diǎn)通信過程/原理,詳細(xì)介紹了Cluster(集群)的節(jié)點(diǎn)通信的流程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

簡介

        本文介紹Redis的Cluster(集群)的節(jié)點(diǎn)通信的流程。

通信流程

        在分布式存儲中需要提供維護(hù)節(jié)點(diǎn)元數(shù)據(jù)信息的機(jī)制, 所謂元數(shù)據(jù)是指: 節(jié)點(diǎn)負(fù)責(zé)哪些數(shù)據(jù), 是否出現(xiàn)故障等狀態(tài)信息。 常見的元數(shù)據(jù)維護(hù)方式分為: 集中式和P2P方式。 Redis集群采用P2P的Gossip(流言) 協(xié)議,Gossip協(xié)議工作原理就是節(jié)點(diǎn)彼此不斷通信交換信息, 一段時(shí)間后所有的節(jié)點(diǎn)都會知道集群完整的信息, 這種方式類似流言傳播, 如下所示

通信過程說明:

  • 集群中的每個(gè)節(jié)點(diǎn)都會單獨(dú)開辟一個(gè)TCP通道, 用于節(jié)點(diǎn)之間彼此通信, 通信端口號在基礎(chǔ)端口上加10000。
  • 每個(gè)節(jié)點(diǎn)在固定周期內(nèi)通過特定規(guī)則選擇幾個(gè)節(jié)點(diǎn)發(fā)送ping消息。接收到ping消息的節(jié)點(diǎn)用pong消息作為響應(yīng)。
  • 集群中每個(gè)節(jié)點(diǎn)通過一定規(guī)則挑選要通信的節(jié)點(diǎn), 每個(gè)節(jié)點(diǎn)可能知道全部節(jié)點(diǎn), 也可能僅知道部分節(jié)點(diǎn), 只要這些節(jié)點(diǎn)彼此可以正常通信, 最終它們會達(dá)到一致的狀態(tài)。 當(dāng)節(jié)點(diǎn)出故障、 新節(jié)點(diǎn)加入、 主從角色變化、 槽信息變更等事件發(fā)生時(shí), 通過不斷的ping/pong消息通信, 經(jīng)過一段時(shí)間后所有的節(jié)點(diǎn)都會知道整個(gè)集群全部節(jié)點(diǎn)的最新狀態(tài), 從而達(dá)到集群狀態(tài)同步的目的。 

Gossip消息

消息流程

        Gossip協(xié)議的主要職責(zé)就是信息交換。 信息交換的載體就是節(jié)點(diǎn)彼此發(fā)送的Gossip消息, 了解這些消息有助于我們理解集群如何完成信息交換。

        常用的Gossip消息可分為: ping消息、 pong消息、 meet消息、 fail消息等, 它們的通信模式如下圖所示:

  • meet消息: 用于通知新節(jié)點(diǎn)加入。

消息發(fā)送者通知接收者加入到當(dāng)前集群, meet消息通信正常完成后, 接收節(jié)點(diǎn)會加入到集群中并進(jìn)行周期性的ping、 pong消息交換。

  • ping消息: 集群內(nèi)交換最頻繁的消息

 集群內(nèi)每個(gè)節(jié)點(diǎn)每秒向多個(gè)其他節(jié)點(diǎn)發(fā)送ping消息, 用于檢測節(jié)點(diǎn)是否在線和交換彼此狀態(tài)信息。 ping消息發(fā)送封裝了自身節(jié)點(diǎn)和部分其他節(jié)點(diǎn)的狀態(tài)數(shù)據(jù)。

  • pong消息: 當(dāng)接收到ping、 meet消息時(shí), 作為響應(yīng)消息回復(fù)給發(fā)送方確認(rèn)消息正常通信。

pong消息內(nèi)部封裝了自身狀態(tài)數(shù)據(jù)。 節(jié)點(diǎn)也可以向集群內(nèi)廣播自身的pong消息來通知整個(gè)集群對自身狀態(tài)進(jìn)行更新。
fail消息: 當(dāng)節(jié)點(diǎn)判定集群內(nèi)另一個(gè)節(jié)點(diǎn)下線時(shí), 會向集群內(nèi)廣播一個(gè)fail消息, 其他節(jié)點(diǎn)接收到fail消息之后把對應(yīng)節(jié)點(diǎn)更新為下線狀態(tài)。 具體細(xì)節(jié)將在后面“故障轉(zhuǎn)移”中說明。

消息格式

        所有的消息格式劃分為: 消息頭和消息體。 消息頭包含發(fā)送節(jié)點(diǎn)自身狀態(tài)數(shù)據(jù), 接收節(jié)點(diǎn)根據(jù)消息頭就可以獲取到發(fā)送節(jié)點(diǎn)的相關(guān)數(shù)據(jù), 結(jié)構(gòu)如下:

typedef struct {
    char sig[4]; /* 信號標(biāo)示 */
    uint32_t totlen; /* 消息總長度 */
    uint16_t ver; /* 協(xié)議版本*/
    uint16_t type; /* 消息類型,用于區(qū)分meet,ping,pong等消息 */
    uint16_t count; /* 消息體包含的節(jié)點(diǎn)數(shù)量, 僅用于meet,ping,ping消息類型*/
    uint64_t currentEpoch; /* 當(dāng)前發(fā)送節(jié)點(diǎn)的配置紀(jì)元 */
    uint64_t configEpoch; /* 主節(jié)點(diǎn)/從節(jié)點(diǎn)的主節(jié)點(diǎn)配置紀(jì)元 */
    uint64_t offset; /* 復(fù)制偏移量 */
    char sender[CLUSTER_NAMELEN]; /* 發(fā)送節(jié)點(diǎn)的nodeId */
    unsigned char myslots[CLUSTER_SLOTS/8]; /* 發(fā)送節(jié)點(diǎn)負(fù)責(zé)的槽信息 */
    char slaveof[CLUSTER_NAMELEN]; /* 如果發(fā)送節(jié)點(diǎn)是從節(jié)點(diǎn), 記錄對應(yīng)主節(jié)點(diǎn)的nodeId */
    uint16_t port; /* 端口號 */
    uint16_t flags; /* 發(fā)送節(jié)點(diǎn)標(biāo)識,區(qū)分主從角色, 是否下線等 */
    unsigned char state; /* 發(fā)送節(jié)點(diǎn)所處的集群狀態(tài) */
    unsigned char mflags[3]; /* 消息標(biāo)識 */
    union clusterMsgData data /* 消息正文 */;
} clusterMsg;

        集群內(nèi)所有的消息都采用相同的消息頭結(jié)構(gòu)clusterMsg, 它包含了發(fā)送節(jié)點(diǎn)關(guān)鍵信息, 如節(jié)點(diǎn)id、 槽映射、 節(jié)點(diǎn)標(biāo)識(主從角色, 是否下線) 等。消息體在Redis內(nèi)部采用clusterMsgData結(jié)構(gòu)聲明, 結(jié)構(gòu)如下:

union clusterMsgData {
    /* ping,meet,pong消息體*/
    struct {
        /* gossip消息結(jié)構(gòu)數(shù)組 */
        clusterMsgDataGossip gossip[1];
    } ping;
    
    /* FAIL 消息體 */
    struct {
        clusterMsgDataFail about;
    } fail;
    // ...
};

        消息體clusterMsgData定義發(fā)送消息的數(shù)據(jù), 其中ping、 meet、 pong都采用cluster MsgDataGossip數(shù)組作為消息體數(shù)據(jù), 實(shí)際消息類型使用消息頭的type屬性區(qū)分。 每個(gè)消息體包含該節(jié)點(diǎn)的多個(gè)clusterMsgDataGossip結(jié)構(gòu)數(shù)據(jù), 用于信息交換, 結(jié)構(gòu)如下:

typedef struct {
    char nodename[CLUSTER_NAMELEN]; /* 節(jié)點(diǎn)的nodeId */
    uint32_t ping_sent; /* 最后一次向該節(jié)點(diǎn)發(fā)送ping消息時(shí)間 */
    uint32_t pong_received; /* 最后一次接收該節(jié)點(diǎn)pong消息時(shí)間 */
    char ip[NET_IP_STR_LEN]; /* IP */
    uint16_t port; /* port*/
    uint16_t flags; /* 該節(jié)點(diǎn)標(biāo)識, */
} clusterMsgDataGossip;

        當(dāng)接收到ping、 meet消息時(shí), 接收節(jié)點(diǎn)會解析消息內(nèi)容并根據(jù)自身的識別情況做出相應(yīng)處理, 對應(yīng)流程如下圖所示:

接收節(jié)點(diǎn)收到ping/meet消息時(shí), 執(zhí)行解析消息頭和消息體流程:

  • 解析消息頭過程:

消息頭包含了發(fā)送節(jié)點(diǎn)的信息, 如果發(fā)送節(jié)點(diǎn)是新節(jié)點(diǎn)且消息是meet類型, 則加入到本地節(jié)點(diǎn)列表; 如果是已知節(jié)點(diǎn), 則嘗試更新發(fā)送節(jié)點(diǎn)的狀態(tài), 如槽映射關(guān)系、 主從角色等狀態(tài)。

  • 解析消息體過程:

如果消息體的clusterMsgDataGossip數(shù)組包含的節(jié)點(diǎn)是新節(jié)點(diǎn), 則嘗試發(fā)起與新節(jié)點(diǎn)的meet握手流程; 如果是已知節(jié)點(diǎn), 則根據(jù)cluster MsgDataGossip中的flags字段判斷該節(jié)點(diǎn)是否下線, 用于故障轉(zhuǎn)移。
消息處理完后回復(fù)pong消息, 內(nèi)容同樣包含消息頭和消息體, 發(fā)送節(jié)點(diǎn)接收到回復(fù)的pong消息后, 采用類似的流程解析處理消息并更新與接收節(jié)點(diǎn)最后通信時(shí)間, 完成一次消息通信。

節(jié)點(diǎn)選擇

        雖然Gossip協(xié)議的信息交換機(jī)制具有天然的分布式特性, 但它是有成本的。 由于內(nèi)部需要頻繁地進(jìn)行節(jié)點(diǎn)信息交換, 而ping/pong消息會攜帶當(dāng)前節(jié)點(diǎn)和部分其他節(jié)點(diǎn)的狀態(tài)數(shù)據(jù), 勢必會加重帶寬和計(jì)算的負(fù)擔(dān)。 Redis集群內(nèi)節(jié)點(diǎn)通信采用固定頻率(定時(shí)任務(wù)每秒執(zhí)行10次) 。 因此節(jié)點(diǎn)每次選擇需要通信的節(jié)點(diǎn)列表變得非常重要。 通信節(jié)點(diǎn)選擇過多雖然可以做到信息及時(shí)交換但成本過高。 節(jié)點(diǎn)選擇過少會降低集群內(nèi)所有節(jié)點(diǎn)彼此信息交換頻率,從而影響故障判定、 新節(jié)點(diǎn)發(fā)現(xiàn)等需求的速度。 因此Redis集群的Gossip協(xié)議需要兼顧信息交換實(shí)時(shí)性和成本開銷, 通信節(jié)點(diǎn)選擇的規(guī)則如下圖所示

        根據(jù)通信節(jié)點(diǎn)選擇的流程可以看出消息交換的成本主要體現(xiàn)在單位時(shí)間選擇發(fā)送消息的節(jié)點(diǎn)數(shù)量和每個(gè)消息攜帶的數(shù)據(jù)量。

1.選擇發(fā)送消息的節(jié)點(diǎn)數(shù)量

        集群內(nèi)每個(gè)節(jié)點(diǎn)維護(hù)定時(shí)任務(wù)默認(rèn)每秒執(zhí)行10次, 每秒會隨機(jī)選取5個(gè)節(jié)點(diǎn)找出最久沒有通信的節(jié)點(diǎn)發(fā)送ping消息, 用于保證Gossip信息交換的隨機(jī)性。 每100毫秒都會掃描本地節(jié)點(diǎn)列表, 如果發(fā)現(xiàn)節(jié)點(diǎn)最近一次接受pong消息的時(shí)間大于cluster_node_timeout/2, 則立刻發(fā)送ping消息, 防止該節(jié)點(diǎn)信息太長時(shí)間未更新。 根據(jù)以上規(guī)則得出每個(gè)節(jié)點(diǎn)每秒需要發(fā)送ping消息的數(shù)
量=1+10*num(node.pong_received>cluster_node_timeout/2) , 因此cluster_node_timeout參數(shù)對消息發(fā)送的節(jié)點(diǎn)數(shù)量影響非常大。 當(dāng)我們的帶寬資源緊張時(shí), 可以適當(dāng)調(diào)大這個(gè)參數(shù), 如從默認(rèn)15秒改為30秒來降低帶寬占用率。 過度調(diào)大cluster_node_timeout會影響消息交換的頻率從而影響故障轉(zhuǎn)移、 槽信息更新、 新節(jié)點(diǎn)發(fā)現(xiàn)的速度。 因此需要根據(jù)業(yè)務(wù)容忍度和資源消耗進(jìn)行平衡。 同時(shí)整個(gè)集群消息總交換量也跟節(jié)點(diǎn)數(shù)成正比。

2.消息數(shù)據(jù)量

        每個(gè)ping消息的數(shù)據(jù)量體現(xiàn)在消息頭和消息體中, 其中消息頭主要占用空間的字段是myslots[CLUSTER_SLOTS/8], 占用2KB, 這塊空間占用相對固定。 消息體會攜帶一定數(shù)量的其他節(jié)點(diǎn)信息用于信息交換。 具體數(shù)量見以下偽代碼:

def get_wanted():
    int total_size = size(cluster.nodes)
    
    # 默認(rèn)包含節(jié)點(diǎn)總量的1/10
    594int wanted = floor(total_size/10);
    if wanted < 3:
    # 至少攜帶3個(gè)其他節(jié)點(diǎn)信息
    wanted = 3;
    if wanted > total_size -2 :
    # 最多包含total_size - 2個(gè)
    wanted = total_size - 2;
    return wanted;

        根據(jù)偽代碼可以看出消息體攜帶數(shù)據(jù)量跟集群的節(jié)點(diǎn)數(shù)息息相關(guān), 更大的集群每次消息通信的成本也就更高, 因此對于Redis集群來說并不是大而全的集群更好, 對于集群規(guī)??刂频慕ㄗh見之后“集群運(yùn)維”。

其他網(wǎng)址

《Redis開發(fā)與運(yùn)維》=> 第10章 集群=> 10.3 節(jié)點(diǎn)通信

到此這篇關(guān)于Redis集群節(jié)點(diǎn)通信過程/原理的文章就介紹到這了,更多相關(guān)Redis集群節(jié)點(diǎn)通信內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis Scan命令的基本使用方法

    Redis Scan命令的基本使用方法

    這篇文章主要給大家介紹了關(guān)于Redis中Scan命令的基本使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Redis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Redis中ZSet的具體使用

    Redis中ZSet的具體使用

    本文主要介紹了Redis中ZSet的具體使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Redis可視化工具Redis?Desktop?Manager的具體使用

    Redis可視化工具Redis?Desktop?Manager的具體使用

    本文主要介紹了Redis可視化工具Redis?Desktop?Manager的具體使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • redis?zrange?與?zrangebyscore的區(qū)別解析

    redis?zrange?與?zrangebyscore的區(qū)別解析

    這篇文章主要介紹了redis?zrange與zrangebyscore的區(qū)別,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • redis復(fù)制集群搭建的實(shí)現(xiàn)

    redis復(fù)制集群搭建的實(shí)現(xiàn)

    redis 復(fù)制集群是開發(fā)中一種比較常用的集群模式,本文主要介紹了redis復(fù)制集群搭建的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Redis分布式非公平鎖的使用

    Redis分布式非公平鎖的使用

    分布式鎖很多人都能接觸到,本文主要介紹了Redis分布式非公平鎖,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Redis集群Lettuce主從切換問題解決方案

    Redis集群Lettuce主從切換問題解決方案

    這篇文章主要為大家介紹了Redis集群Lettuce主從切換問題解決方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Redis 哨兵機(jī)制及配置實(shí)現(xiàn)

    Redis 哨兵機(jī)制及配置實(shí)現(xiàn)

    本文主要介紹了Redis 哨兵機(jī)制及配置實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Redis實(shí)現(xiàn)排行榜及相同積分按時(shí)間排序功能的實(shí)現(xiàn)

    Redis實(shí)現(xiàn)排行榜及相同積分按時(shí)間排序功能的實(shí)現(xiàn)

    這篇文章主要介紹了Redis實(shí)現(xiàn)排行榜及相同積分按時(shí)間排序,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • Redis偶發(fā)連接失敗案例實(shí)戰(zhàn)記錄

    Redis偶發(fā)連接失敗案例實(shí)戰(zhàn)記錄

    這篇文章主要給大家介紹了關(guān)于Redis偶發(fā)連接失敗的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使Redis具有一定的參考學(xué)習(xí)價(jià)值,用需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-10-10

最新評論