成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

代碼很少,卻很優秀!RocketMQ的NameServer是如何做到的?

開發
RocketMQ的注冊中心 NameServer 是采用 CAP理論中的 AP,各個節點之間是Peer to Peer的對等關系,數據的一致性通過心跳機制,定時器,延時感知來完成。

今天我們來一起深入分析 RocketMQ的注冊中心 NameServer。

本文基于 RocketMQ release-5.2.0。

首先,我們回顧下 RocketMQ的內核原理鳥瞰圖:

從上面的鳥瞰圖,我們可以看出:Nameserver既和 Broker交互,也和 Producer和 Consumer交互,因此,在 RocketMQ中,Nameserver起到了一個紐帶性的作用。

接著,我們再看看 NameServer的工程結構,如下圖:

整個工程只有 11個類(老版本好像只有不到 10個類),為什么 RocketMQ可以用如此少的代碼,設計出如此高性能且輕量的注冊中心?

我覺得最核心的 3個點是:

  • AP設計思想
  • 簡單的數據結構
  • 心跳機制

一、AP設計思想

像 ZooKeeper,采用了 Zab (Zookeeper Atomic Broadcast) 這種比較重的協議,必須大多數節點(過半數)可用,才能確保了數據的一致性和高可用,大大增加了網絡開銷和復雜度。

而 NameServer遵守了 CAP理論中 AP,在一個 NameServer集群中,NameServer節點之間是P2P(Peer to Peer)的對等關系,并且 NameServer之間并沒有通信,減少很多不必要的網絡開銷,即便只剩一個 NameServer節點也能繼續工作,足以保證高可用。

二、數據結構

NameServer維護了一套比較簡單的數據結構,內部維護了一個路由表,該路由表包含以下幾個核心元數據,對應的源碼類RouteInfoManager如下:

public class RouteInfoManager {
    private final static long DEFAULT_BROKER_CHANNEL_EXPIRED_TIME = 1000 * 60 * 2; // broker失效時間 120s
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private final Map<String/* topic */, Map<String, QueueData>> topicQueueTable;
    private final Map<String/* brokerName */, BrokerData> brokerAddrTable;
    private final Map<String/* clusterName */, Set<String/* brokerName */>> clusterAddrTable;
    private final Map<BrokerAddrInfo/* brokerAddr */, BrokerLiveInfo> brokerLiveTable;
    private final Map<BrokerAddrInfo/* brokerAddr */, List<String>/* Filter Server */> filterServerTable;
}

  • topicQueueTable:Topic消息隊列路由信息,消息發送時根據路由表進行負載均衡
  • brokerAddrTable:Broker基礎信息,包括brokerName、所屬集群名稱、主備Broker地址
  • clusterAddrTable:Broker集群信息,存儲集群中所有Broker名稱
  • brokerLiveTable:Broker狀態信息,NameServer每次收到心跳包會替換該信息
  • filterServerTable:Broker上的FilterServer列表,用于過濾標簽(Tag)或 SQL表達式,以減輕 Consumer的負擔,提高消息消費的效率。

1.TopicRouteData

TopicRouteData是 NameServer中最重要的數據結構之一,它包括了 Topic對應的所有 Broker信息以及每個 Broker上的隊列信息,filter服務器列表,其源碼如下:

public class TopicRouteData {
    private List<QueueData> queueDatas;
    private List<BrokerData> brokerDatas;
    private HashMap<String, List<String>> filterServerTable;
    //It could be null or empty
    private Map<String/*brokerName*/, TopicQueueMappingInfo> topicQueueMappingByBroker;
}

2.BrokerData

BrokerData包含了 Broker的基本屬性,狀態,所在集群以及 Broker服務器的 IP地址,其源碼如下:

public class BrokerData {
    private String cluster;//所在的集群
    private String brokerName;//所在的brokerName
    private HashMap<Long, String> brokerAddrs;//該broker對應的機器IP列表
    private String zoneName; // 區域名稱
}

3.QueueData

QueueData包含了 BrokerName,readQueue的數量,writeQueue的數量等信息,對應的源碼類是QueueData,其源碼如下:

public class QueueData {
    private String brokerName;//所在的brokerName
    private int readQueueNums;// 讀隊列數量
    private int writeQueueNums;// 寫隊列數量
    private int perm; // 讀寫權限,參考PermName 類
    private int topicSysFlag; // topic同步標記,參考TopicSysFlag 類
}

4.元數據舉例

為了更好地理解元數據,這里對每一種元數據都給出一個數據實例:

topicQueueTable:{
    "topicA":[
        {
            "brokeName":"broker-a",
            "readQueueNums":4,
            "writeQueueNums":4,
            "perm":6, 
            "topicSyncFlag":0 
        },
        {
            "brokeName":"broker-b",
            "readQueueNums":4,
            "writeQueueNums":4,
            "perm":6, 
            "topicSyncFlag":0
        }
    ],
    "topicB":[]
}
brokeAddrTable:{
    "broker-a":{
        "cluster":"cluster-1",
        "brokerName":"broker-a",
        "brokerAddrs":{
            0:"192.168.0.1:8000",
            1:"192.168.0.2:8000"
        }
    },
    "broker-b":{
        "cluster":"cluster-1",
        "brokerName":"broker-b",
        "brokerAddrs":{
            0:"192.168.0.3:8000",
            1:"192.168.0.4:8000"
        }
    }
}

三、心跳機制

心跳機制是 NameServer維護 Broker的路由信息最重要的一個抓手,主要分為接收心跳、處理心跳、心跳超時 3部分:

1.接收心跳

Broker每 30s會向所有的 NameServer發送心跳包,告訴它們自己還存活著,從而更新自己在 NameServer的狀態,整體交互如下圖:

2.處理心跳

NameServer收到心跳包時會更新 brokerLiveTable緩存中 BrokerLiveInfo的 lastUpdateTimeStamp信息,整體交互如下圖:

處理邏輯可以參考源碼:org.apache.rocketmq.namesrv.processor.DefaultRequestProcessor#processRequest#brokerHeartbeat:

public RemotingCommand brokerHeartbeat(ChannelHandlerContext ctx,
    RemotingCommand request) throws RemotingCommandException {
    final RemotingCommand response = RemotingCommand.createResponseCommand(null);
    final BrokerHeartbeatRequestHeader requestHeader =
        (BrokerHeartbeatRequestHeader) request.decodeCommandCustomHeader(BrokerHeartbeatRequestHeader.class);

    this.namesrvController.getRouteInfoManager().updateBrokerInfoUpdateTimestamp(requestHeader.getClusterName(), requestHeader.getBrokerAddr());

    response.setCode(ResponseCode.SUCCESS);
    response.setRemark(null);
    return response;
}

3.心跳超時

NameServer每隔 10s(每隔5s + 5s延遲)掃描 brokerLiveTable檢查 Broker的狀態,如果在 120s內未收到 Broker心跳,則認為 Broker異常,會從路由表將該 Broker摘除并關閉 Socket連接,同時還會更新路由表的其他信息,整體交互如下圖:

private void startScheduleService() {
this.scanExecutorService.scheduleAtFixedRate(NamesrvController.this.routeInfoManager::scanNotActiveBroker,
        5, this.namesrvConfig.getScanNotActiveBrokerInterval(), TimeUnit.MILLISECONDS);
}

源碼參考:org.apache.rocketmq.namesrv.routeinfo.RouteInfoManager#unRegisterBroker(),核心流程:

  • 遍歷brokerAddrTable
  • 遍歷broker地址
  • 根據 broker地址移除 brokerAddr
  • 如果當前 Topic只包含待移除的 Broker,則移除該 Topic

四、其他核心源碼解讀

NameServer啟動

NameServer的啟動類為:org.apache.rocketmq.namesrv.NamesrvStartup,整個流程如下圖:

NameServer啟動最核心的 3個事情是:

  • 加載配置:NameServerConfig、NettyServerConfig主要是映射配置文件,并創建 NamesrvController。
  • 啟動 Netty通信服務:NettyRemotingServer是 NameServer和Broker,Producer,Consumer通信的底層通道 Netty服務器。
  • 啟動定時器和鉤子程序:NameServerController實例一方面處理 Netty接收到消息后,一方面內部有多個定時器和鉤子程序,它是 NameServer的核心控制器。

五、總結

NameServer并沒有采用復雜的分布式協議來保持數據的一致性,而是采用 CAP理論中的 AP,各個節點之間是Peer to Peer的對等關系,數據的一致性通過心跳機制,定時器,延時感知來完成。

責任編輯:趙寧寧 來源: 猿java
相關推薦

2023-11-30 10:13:17

TensorRT架構

2020-02-19 14:10:27

代碼開發工具

2017-11-14 08:25:36

數據庫MySQL安全登陸

2021-08-02 09:01:05

MySQL 多版本并發數據庫

2016-11-30 14:18:30

互聯網

2019-01-03 14:00:37

降價青云全棧云

2024-07-10 17:28:51

2019-12-23 09:25:29

日志Kafka消息隊列

2011-11-09 15:49:52

API

2011-06-22 09:45:46

JavaScriptAPI

2018-05-15 16:19:39

程序員bug代碼

2024-03-08 07:58:13

QPShttpsync

2017-12-05 11:48:44

AI人工智能開發者

2020-06-01 08:41:29

蘇寧分析大數據

2023-01-17 16:05:50

程序員時間管理日程表

2011-04-29 10:32:46

項目管理

2011-08-01 09:08:49

程序員

2018-09-07 18:14:37

2009-11-20 11:37:11

Oracle完全卸載

2014-04-01 09:29:12

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产草草视频 | 一级免费在线视频 | av网站免费在线观看 | 狠狠操电影 | 一区二区免费在线观看 | 9191av| 奇米影视77| 黄免费观看视频 | 国产精品久久久久久福利一牛影视 | 狠狠干av| 成人在线视频免费播放 | 久久久99精品免费观看 | av大片 | 亚洲精品视频在线播放 | 国产在线观看一区二区 | av一级 | 欧美日韩精品一区二区三区蜜桃 | 亚洲日本中文 | 欧美日韩成人在线 | 亚洲精品自拍视频 | 午夜极品 | 亚洲五码在线 | 99亚洲视频 | 美女拍拍拍网站 | 欧美日韩亚 | 91精品国产自产精品男人的天堂 | 国产精品久久久久无码av | 国产一区不卡 | 国产亚洲精品久久午夜玫瑰园 | 国产黄色小视频在线观看 | 亚洲精品成人免费 | av天天看| 日韩中文在线视频 | 日韩一区二区三区四区五区六区 | 国产成人a亚洲精品 | 成人精品在线视频 | 亚洲一区二区三区免费在线 | 国产亚洲精品a | 午夜免费观看体验区 | 午夜不卡一区二区 | 国产精品1 |