中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Raft算法是什么?Nacos如何實現Raft算法?

發布時間:2020-05-29 20:28:23 來源:億速云 閱讀:524 作者:鴿子 欄目:編程語言

一、快速了解Raft算法

Raft 適用于一個管理日志一致性的協議,相比于 Paxos 協議 Raft 更易于理解和去實現它。為了提高理解性,Raft 將一致性算法分為了幾個部分,包括領導選取(leader selection)、日志復制(log replication)、安全(safety),并且使用了更強的一致性來減少了必須需要考慮的狀態。

相比Paxos,Raft算法理解起來更加直觀。

Raft算法將Server劃分為3種狀態,或者也可以稱作角色:

  • Leader
    負責Client交互和log復制,同一時刻系統中最多存在1個。
  • Follower
    被動響應請求RPC,從不主動發起請求RPC。
  • Candidate

一種臨時的角色,只存在于leader的選舉階段,某個節點想要變成leader,那么就發起投票請求,同時自己變成candidate。如果選舉成功,則變為candidate,否則退回為follower

狀態或者說角色的流轉如下:

Raft算法是什么?Nacos如何實現Raft算法?

在Raft中,問題分解為:領導選取、日志復制、安全和成員變化。

復制狀態機通過復制日志來實現:

日志:每臺機器保存一份日志,日志來自于客戶端的請求,包含一系列的命令狀態機:狀態機會按順序執行這些命令一致性模型:分布式環境下,保證多機的日志是一致的,這樣回放到狀態機中的狀態是一致的

Raft算法選主流程

Raft中有Term的概念,Term類比中國歷史上的朝代更替,Raft 算法將時間劃分成為任意不同長度的任期(term)。

Raft算法是什么?Nacos如何實現Raft算法?

選舉流程

1、follower增加當前的term,轉變為candidate。2、candidate投票給自己,并發送RequestVote RPC給集群中的其他服務器。3、收到RequestVote的服務器,在同一term中只會按照先到先得投票給至多一個candidate。且只會投票給log至少和自身一樣新的candidate。

二、Nacos中的CP一致性

Spring Cloud Alibaba Nacos 在 1.0.0 正式支持 AP 和 CP 兩種一致性協議,其中的CP一致性協議實現,是基于簡化的 Raft 的 CP 一致性。

如何實現Raft算法

Nacos server在啟動時,會通過RunningConfig.onApplicationEvent()方法調用RaftCore.init()方法。

啟動選舉

public static void init() throws Exception {

    Loggers.RAFT.info("initializing Raft sub-system");

    // 啟動Notifier,輪詢Datums,通知RaftListener
    executor.submit(notifier);

    // 獲取Raft集群節點,更新到PeerSet中
    peers.add(NamingProxy.getServers());

    long start = System.currentTimeMillis();

    // 從磁盤加載Datum和term數據進行數據恢復
    RaftStore.load();

    Loggers.RAFT.info("cache loaded, peer count: {}, datum count: {}, current term: {}",
        peers.size(), datums.size(), peers.getTerm());

    while (true) {
        if (notifier.tasks.size() <= 0) {
            break;
        }
        Thread.sleep(1000L);
        System.out.println(notifier.tasks.size());
    }

    Loggers.RAFT.info("finish to load data from disk, cost: {} ms.", (System.currentTimeMillis() - start));

    GlobalExecutor.register(new MasterElection()); // Leader選舉
    GlobalExecutor.register1(new HeartBeat()); // Raft心跳
    GlobalExecutor.register(new AddressServerUpdater(), GlobalExecutor.ADDRESS_SERVER_UPDATE_INTERVAL_MS);

    if (peers.size() > 0) {
        if (lock.tryLock(INIT_LOCK_TIME_SECONDS, TimeUnit.SECONDS)) {
            initialized = true;
            lock.unlock();
        }
    } else {
        throw new Exception("peers is empty.");
    }

    Loggers.RAFT.info("timer started: leader timeout ms: {}, heart-beat timeout ms: {}",
        GlobalExecutor.LEADER_TIMEOUT_MS, GlobalExecutor.HEARTBEAT_INTERVAL_MS);
}

在init方法主要做了如下幾件事:

  1. 獲取Raft集群節點 peers.add(NamingProxy.getServers());
  2. Raft集群數據恢復 RaftStore.load();
  3. Raft選舉 GlobalExecutor.register(new MasterElection());
  4. Raft心跳 GlobalExecutor.register(new HeartBeat());
  5. Raft發布內容
  6. Raft保證內容一致性

選舉流程

其中,raft集群內部節點間是通過暴露的Restful接口,代碼在 RaftController 中。RaftController控制器是raft集群內部節點間通信使用的,具體的信息如下

POST HTTP://{ip:port}/v1/ns/raft/vote : 進行投票請求

POST HTTP://{ip:port}/v1/ns/raft/beat : Leader向Follower發送心跳信息

GET HTTP://{ip:port}/v1/ns/raft/peer : 獲取該節點的RaftPeer信息

PUT HTTP://{ip:port}/v1/ns/raft/datum/reload : 重新加載某日志信息

POST HTTP://{ip:port}/v1/ns/raft/datum : Leader接收傳來的數據并存入

DELETE HTTP://{ip:port}/v1/ns/raft/datum : Leader接收傳來的數據刪除操作

GET HTTP://{ip:port}/v1/ns/raft/datum : 獲取該節點存儲的數據信息

GET HTTP://{ip:port}/v1/ns/raft/state : 獲取該節點的狀態信息{UP or DOWN}

POST HTTP://{ip:port}/v1/ns/raft/datum/commit : Follower節點接收Leader傳來得到數據存入操作

DELETE HTTP://{ip:port}/v1/ns/raft/datum : Follower節點接收Leader傳來的數據刪除操作

GET HTTP://{ip:port}/v1/ns/raft/leader : 獲取當前集群的Leader節點信息

GET HTTP://{ip:port}/v1/ns/raft/listeners : 獲取當前Raft集群的所有事件監聽者
RaftPeerSet

心跳機制

Raft中使用心跳機制來觸發leader選舉。心跳定時任務是在GlobalExecutor 中,通過 GlobalExecutor.register(new HeartBeat())注冊心跳定時任務,具體操作包括:

  • 重置Leader節點的heart timeout、election timeout;
  • sendBeat()發送心跳包
 public class HeartBeat implements Runnable {
        @Override
        public void run() {
            try {

                if (!peers.isReady()) {
                    return;
                }

                RaftPeer local = peers.local();
                local.heartbeatDueMs -= GlobalExecutor.TICK_PERIOD_MS;
                if (local.heartbeatDueMs > 0) {
                    return;
                }

                local.resetHeartbeatDue();

                sendBeat();
            } catch (Exception e) {
                Loggers.RAFT.warn("[RAFT] error while sending beat {}", e);
            }

        }
}

簡單說明了下Nacos中的Raft一致性實現,更詳細的流程,可以下載源碼,查看 RaftCore 進行了解。源碼可以通過以下地址檢出:

git clone https://github.com/alibaba/nacos.git

Raft算法是什么?Nacos如何實現Raft算法?

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

三河市| 本溪| 盖州市| 上林县| 嘉祥县| 惠州市| 蓝山县| 哈尔滨市| 灵寿县| 岳池县| 肥西县| 泸西县| 台安县| 大英县| 吉木乃县| 鄱阳县| 吴旗县| 太保市| 宜兴市| 崇阳县| 安顺市| 行唐县| 饶阳县| 望江县| 太和县| 抚顺县| 同仁县| 天峻县| 青川县| 通许县| 年辖:市辖区| 孝昌县| 龙海市| 安国市| 左贡县| 邻水| 嘉定区| 巴青县| 新巴尔虎右旗| 曲沃县| 合作市|