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

揭秘 Nacos 的 AP 架構(gòu) 「Distro 一致性協(xié)議」

開發(fā) 架構(gòu)
每個 Nacos 節(jié)點(diǎn)雖然只負(fù)責(zé)屬于自己的客戶端,但是每個節(jié)點(diǎn)都是包含有所有的客戶端信息的,所以當(dāng)客戶端想要查詢注冊信息時,可以直接從請求的 Nacos 的節(jié)點(diǎn)拿到全量數(shù)據(jù)。

你好,我是悟空呀。

這次我們要進(jìn)入 Nacos 的一致性底層原理了,還是先來一張架構(gòu)圖,讓大家對 Nacos 的架構(gòu)有個整體的印象,本篇會主要講解一致性模塊中的 Distro 協(xié)議。

上篇留了兩個知識點(diǎn):

  • ① 服務(wù)實(shí)例注冊到 Nacos 節(jié)點(diǎn)后,通過 UDP 方式推送到所有服務(wù)實(shí)例。讓其他服務(wù)實(shí)例感知到服務(wù)列表的變化。
  • ② 如何復(fù)制數(shù)據(jù)到其他節(jié)點(diǎn):當(dāng)前 Nacos 節(jié)點(diǎn)開啟 1s 的延遲任務(wù),將數(shù)據(jù)同步給其他 Nacos 節(jié)點(diǎn)。(分區(qū)一致性)

第 ② 個知識點(diǎn)就是 Nacos 自研的 Distro 一致性協(xié)議的核心功能。

首先這個 Distro 協(xié)議是針對集群環(huán)境的,比如下面這三個集群節(jié)點(diǎn)組成了一個集群。服務(wù) A 和服務(wù) B 會往這個集群進(jìn)行注冊。

Nacos 集群節(jié)點(diǎn)

Nacos 集群環(huán)境

我們知道 Nacos 它是支持兩種分布式定理的:CP(分區(qū)一致性)和 AP(分區(qū)可用性) ,而 AP 是通過 Nacos 自研的 Distro 協(xié)議來保證的,CP 是通過 Nacos 的 JRaft 協(xié)議來保證的。

因?yàn)樽灾行淖鳛橄到y(tǒng)中很重要的的一個服務(wù),需要盡最大可能對外提供可用的服務(wù),所以選擇 AP 來保證服務(wù)的高可用,另外 Nacos 還采取了心跳機(jī)制來自動完成服務(wù)數(shù)據(jù)補(bǔ)償?shù)臋C(jī)制,所以說 Distro 協(xié)議是弱一致性的。

如果采用 CP 協(xié)議,則需要當(dāng)前集群可用的節(jié)點(diǎn)數(shù)過半才能工作。

問題:Nacos 哪些地方用到了 AP 和 CP?

  • 針對臨時服務(wù)實(shí)例,采用 AP 來保證注冊中心的可用性,Distro 協(xié)議。
  • 針對持久化服務(wù)實(shí)例,采用 CP 來保證各個節(jié)點(diǎn)的強(qiáng)一致性,JRaft 協(xié)議。(JRaft 是 Nacos 對 Raft 的一種改造)
  • 針對配置中心,無 Database 作為存儲的情況下,Nacos 節(jié)點(diǎn)之間的內(nèi)存數(shù)據(jù)為了保持一致,采用 CP。Nacos 提供這種模式只是為了方便用戶本機(jī)運(yùn)行,降低對存儲依賴,生產(chǎn)環(huán)境一般都是通過外置存儲組件來保證數(shù)據(jù)一致性。
  • 針對配置中心,有 Database 作為存儲的情況下,Nacos 通過持久化后通知其他節(jié)點(diǎn)到數(shù)據(jù)庫拉取數(shù)據(jù)來保證數(shù)據(jù)一致性,另外采用讀寫分離架構(gòu)來保證高可用,所以這里我認(rèn)為這里采用的 AP,歡迎探討。
  • 針對 異地多活,采用 AP 來保證高可用。

弦外音:

臨時服務(wù)實(shí)例就是我們默認(rèn)使用的 Nacos 注冊中心模式,客戶端注冊后,客戶端需要定時上報心跳信息來進(jìn)行服務(wù)實(shí)例續(xù)約。這個在注冊的時候,可以通過傳參設(shè)置是否是臨時實(shí)例。

持久化服務(wù)實(shí)例就是不需要上報心跳信息的,不會被自動摘除,除非手動移除實(shí)例,如果實(shí)例宕機(jī)了,Nacos 只會將這個客戶端標(biāo)記為不健康。

本篇會帶著大家從源碼角度來深入剖析下 Distro 協(xié)議。

知識點(diǎn)預(yù)告:

  • ① Distro 的設(shè)計(jì)思想和六大機(jī)制。
  • ② Nacos 如何同步數(shù)據(jù)到其他節(jié)點(diǎn)。(異步復(fù)制機(jī)制,本篇重點(diǎn)講解)
  • ③ Nacos 如何保證所有節(jié)點(diǎn)的數(shù)據(jù)一致性。(定期檢驗(yàn);健康檢查機(jī)制,下一篇重點(diǎn)講解)
  • ④ 新加入的 Nacos 節(jié)點(diǎn),如何進(jìn)行拉取數(shù)據(jù)。(新節(jié)點(diǎn)同步機(jī)制)

一、Distro 的設(shè)計(jì)思想和六大機(jī)制

Distro 協(xié)議是 Nacos 對于臨時實(shí)例數(shù)據(jù)開發(fā)的一致性協(xié)議。

Distro 協(xié)議是集 Gossip + Eureka 協(xié)議的優(yōu)點(diǎn)并加以優(yōu)化后出現(xiàn)的。

Gossip 協(xié)議有什么坑?由于隨機(jī)選取發(fā)送的節(jié)點(diǎn),不可避免地存在消息重復(fù)發(fā)送給同一節(jié)點(diǎn)的情況,增加了網(wǎng)絡(luò)的傳輸?shù)膲毫Γo消息節(jié)點(diǎn)帶來額外的處理負(fù)載。

Distro 協(xié)議的優(yōu)化:每個節(jié)點(diǎn)負(fù)責(zé)一部分?jǐn)?shù)據(jù),然后將數(shù)據(jù)同步給其他節(jié)點(diǎn),有效地降低了消息冗余的問題。

關(guān)于臨時實(shí)例數(shù)據(jù):臨時數(shù)據(jù)其實(shí)是存儲在內(nèi)存緩存中的,并且在其他節(jié)點(diǎn)在啟動時會進(jìn)行全量數(shù)據(jù)同步,然后節(jié)點(diǎn)也會定期進(jìn)行數(shù)據(jù)校驗(yàn)。

大家不要被這個協(xié)議嚇到,其實(shí)就是阿里自己實(shí)現(xiàn)的一套同步邏輯。

AP 中的 P 代表網(wǎng)絡(luò)分區(qū),所以 Distro 在分布式集群環(huán)境下才能真正發(fā)揮其作用。它保證了在多個 Nacos 節(jié)點(diǎn)組成的 Nacos 集群環(huán)境中,當(dāng)其中某個 Nacos 宕機(jī)后,整個集群還是能正常工作。

Distro 的設(shè)計(jì)機(jī)制:

  • 平等機(jī)制:Nacos 的每個節(jié)點(diǎn)是平等的,都可以處理寫的請求。(上一講已經(jīng)重點(diǎn)講解了?)
  • 異步復(fù)制機(jī)制:Nacos 把變更的數(shù)據(jù)異步復(fù)制到其他節(jié)點(diǎn)。(??重點(diǎn)講解)
  • 健康檢查機(jī)制:每個節(jié)點(diǎn)只存了部分?jǐn)?shù)據(jù),定期檢查客戶端狀態(tài)保持?jǐn)?shù)據(jù)一致性。
  • 本地讀機(jī)制: 每個節(jié)點(diǎn)獨(dú)立處理讀請求,及時從本地發(fā)出響應(yīng)。
  • 新節(jié)點(diǎn)同步機(jī)制:Nacos 啟動時,從其他節(jié)點(diǎn)同步數(shù)據(jù)。
  • 路由轉(zhuǎn)發(fā)機(jī)制:客戶端發(fā)送的寫請求,如果屬于自己則處理,否則路由轉(zhuǎn)發(fā)給其他節(jié)點(diǎn)。(上一講已經(jīng)重點(diǎn)講解了?)

Distro 的設(shè)計(jì)機(jī)制

二、異步復(fù)制機(jī)制:寫入數(shù)據(jù)后如何同步給其他節(jié)點(diǎn)

2.1 核心入口

核心源碼路徑:

/naming/consistency/ephemeral/distro/DistroConsistencyServiceImpl.java

這個類的名字就說明它是 Distro 一致性協(xié)議的接口實(shí)現(xiàn)類。

當(dāng)注冊請求交給 Nacos 節(jié)點(diǎn)來處理時,核心入口方法就是 put(),如下圖所示:

上一講我們已經(jīng)說過,這里面會做幾件事:

添加實(shí)例信息的流程

① 將實(shí)例信息存放到內(nèi)存緩存 concurrentHashMap 里面。

② 添加一個任務(wù)到 BlockingQueue 里面,這個任務(wù)就是將最新的實(shí)例列表通過 UDP 的方式推送給所有客戶端(服務(wù)實(shí)例),這樣客戶端就拿到了最新的服務(wù)實(shí)例列表,緩存到本地。

③ 開啟 1s 的延遲任務(wù),將數(shù)據(jù)通過給其他 Nacos 節(jié)點(diǎn)。

說明:第二件事是 Nacos 和 客戶端如何保持?jǐn)?shù)據(jù)一致性的,第三件事是 Nacos 集群間如何保持?jǐn)?shù)據(jù)一致性的,因本篇重點(diǎn)講解 Nacos 的 AP 原理,所以會針對第三件事來進(jìn)行闡述。而第二件事,會在后續(xù)文章中重點(diǎn)講解。

2.2 sync 方法的參數(shù)說明

首先我們來看下 distroProtocol.sync(),這個方法傳了哪些參數(shù):

第一個參數(shù) new DistroKey(),它里面?zhèn)髁?key 和一個常量。

key:就是客戶端的服務(wù)名,示例值如下:

com.alibaba.nacos.naming.iplist.ephemeral.public##DEFAULT_GROUP@@nacos.naming.serviceName

INSTANCE_LIST_KEY_PREFIX:就是 com.alibaba.nacos.naming.iplist.

然后這兩個參數(shù)組裝成一個 DistroKey。

第二個參數(shù)是同步數(shù)據(jù)的類型,這里為 change。

第三個參數(shù)是同步任務(wù)的延遲時間,1s。

2.3 sync 的核心邏輯:添加任務(wù)

先上一張?jiān)韴D幫助大家理解,流程圖如下所示。核心邏輯分為以下幾步。

  • 遍歷其他節(jié)點(diǎn),拿到節(jié)點(diǎn)信息。
  • 判斷這個任務(wù)在 map 中是否存在,如果存在則合并這個 task。
  • 如果不存在,則加到 map 中。
  • 后臺線程遍歷這個 map,拿到任務(wù)。

添加任務(wù)到 map 中

代碼的時序圖如下所示:

sync 的核心代碼時序圖

  • 第一個類 DistroConsistencyServiceImpl 把實(shí)例信息加入 map 中,后續(xù)通過 UDP方式推送給客戶端。
  • 第二個類 DistroProtocol 主要就是循環(huán)遍歷其他節(jié)點(diǎn)。
  • 第三個類 NacosDelayTaskExecuteEngine 是核心類,創(chuàng)建了一個同步的任務(wù)到 ConcurrentHashMap 中。

2.4 sync 的核心邏輯:后臺線程異步復(fù)制數(shù)據(jù)

先說下哈,這個核心邏輯極其復(fù)雜,我們看的時候需要抓主線,知道其中幾個關(guān)鍵點(diǎn)就可以了。

悟空在畫代碼邏輯圖的時候,內(nèi)心是崩潰的,Nacos 為什么寫這么復(fù)雜啊!大家不用細(xì)看,看了也會懵??,理解核心步驟就可以了。(圖中有個小細(xì)節(jié),我對不同的類進(jìn)行了顏色區(qū)分)

核心步驟:

  • 遍歷其他節(jié)點(diǎn),創(chuàng)建一個同步的任務(wù),加到 map 中。
  • 后臺線程不斷從 map 中拿到 task,然后移除這個 task。
  • 把這個 task 加到一個隊(duì)列里面。
  • 有個 worker 專門從隊(duì)列里面拿到 task 來執(zhí)行。

這個 task 就是發(fā)送 http 請求給其他節(jié)點(diǎn),請求參數(shù)中包含注冊的實(shí)例信息(序列化后的二進(jìn)制數(shù)據(jù))。拼接的請求 url 地址為:

http://192.168.0.101:8858/nacos/v1/ns/distro/datum

Nacos 異步復(fù)制數(shù)據(jù)到其他節(jié)點(diǎn)的流程圖如下:

Nacos 異步復(fù)制數(shù)據(jù)到其他節(jié)點(diǎn)的流程圖

2.5 其他節(jié)點(diǎn)如何處理同步請求

2.5.1 如何存儲注冊信息

處理同步請求的邏輯還是比較簡單的,就是把注冊信息存起來,然后同步到其他客戶端。

注冊信息會存放到一個 datum 中,然后 datum 放到一個 dataStore 中。datum 和 dataStore 的數(shù)據(jù)結(jié)構(gòu)如下圖所示:

  • datum 包含 value、key、timestamp。value 就是注冊的客戶端信息(是一個 ArrayList)
  • datastore 是一個 ConcurrentHashMap,包含多個 datum。

存儲注冊信息的數(shù)據(jù)結(jié)構(gòu)

2.5.2 源碼分析

根據(jù) 2.4 講到的請求的 URL:/nacos/v1/ns/distro/datum,處理這個請求的類為

com/alibaba/nacos/naming/controllers/DistroController.java

入口方法為 onSyncDatum,里面做的主要事情如下:

  • ① 把實(shí)例信息放入到一個 datum 內(nèi)存中,然后又存放到 DataStore 的結(jié)構(gòu)中,而 DataStore 的本質(zhì)就是一個 ConcurrentHashMap。
  • ② 將注冊信息通過 UDP 的方式推送給客戶端。

服務(wù)端處理注冊請求的源碼

三、定時同步:如何保持?jǐn)?shù)據(jù)一致性

3.1 為什么需要定時同步

在 Nacos 集群模式下,它作為一個完整的注冊中心,必須具有高可用特性。

在集群模式下,客戶端只需要和其中一個 Nacos 節(jié)點(diǎn)通信就可以了,但是每個節(jié)點(diǎn)其實(shí)是包含所有客戶端信息的,這樣做的好處是每個 Nacos 節(jié)點(diǎn)只需要負(fù)責(zé)自己的客戶端就可以(分?jǐn)倝毫?,而當(dāng)客戶端想要拉取全量注冊表到本地時,從任意節(jié)點(diǎn)都可以讀取到(數(shù)據(jù)一致性)。

那么 Nacos 集群之間是如何通過 Distro 協(xié)議來保持?jǐn)?shù)據(jù)一致性的呢?

3.2 定期檢驗(yàn)元數(shù)據(jù)

在版本 v1 中 ,采用的是定期檢驗(yàn)元信息的方式。元信息就是當(dāng)前節(jié)點(diǎn)包含的客戶端信息的 md5 值。

檢驗(yàn)的原理如下圖所示:

Nacos 各個節(jié)點(diǎn)會有一個心跳任務(wù),定期向其他機(jī)器發(fā)送一次數(shù)據(jù)檢驗(yàn)請求,在校驗(yàn)的過程中,當(dāng)某個節(jié)點(diǎn)發(fā)現(xiàn)其他機(jī)器上的數(shù)據(jù)的元信息和本地?cái)?shù)據(jù)的元信息不一致,則會發(fā)起一次全量拉取請求,將數(shù)據(jù)補(bǔ)齊。

請求 URL:

http://其他 Nacos 節(jié)點(diǎn)的 IP:port/nacos/v1/ns/distro/checksum?source = 
本機(jī)的IP地址:本機(jī)的端口號

參數(shù):DistroData,內(nèi)部包裝的是一個Map<服務(wù)名稱,服務(wù)下實(shí)例的驗(yàn)證字符串 checksum>

3.3 關(guān)于版本迭代的說明

在版本 v2 中,定期校驗(yàn)數(shù)據(jù)已經(jīng)不用了,采用的是健康檢查機(jī)制,來和其他節(jié)點(diǎn)來保持?jǐn)?shù)據(jù)的同步,由于涉及的內(nèi)容還挺多,放到下一講來專門講解 Nacos 的健康檢查機(jī)制:

客戶端與 Nacos 節(jié)點(diǎn)的健康檢查機(jī)制。

集群模式下的健康檢查機(jī)制。

四、新節(jié)點(diǎn)同步機(jī)制,如何保持?jǐn)?shù)據(jù)一致性

4.1 原理

新加入的 Distro 節(jié)點(diǎn)會進(jìn)行全量數(shù)據(jù)拉取,輪詢所有的 Distro 節(jié)點(diǎn),向其他節(jié)點(diǎn)發(fā)送請求拉取全量數(shù)據(jù)。

在全量拉取操作完成之后,每臺機(jī)器上都維護(hù)了當(dāng)前的所有注冊上來的非持久化實(shí)例數(shù)據(jù)。

4.2 源碼分析

DistroProtocol 類的構(gòu)造方法會啟動一個同步任務(wù),從其他 Nacos 節(jié)點(diǎn)全量拉取非持久化實(shí)例數(shù)據(jù)。

/nacos/core/distributed/distro/DistroProtocol.java
startDistroTask();
startLoadTask();
/nacos/core/distributed/distro/task/load/DistroLoadDataTask.java
run();
load();
loadAllDataSnapshotFromRemote();

五、本地讀機(jī)制

5.1 原理

每個 Nacos 節(jié)點(diǎn)雖然只負(fù)責(zé)屬于自己的客戶端,但是每個節(jié)點(diǎn)都是包含有所有的客戶端信息的,所以當(dāng)客戶端想要查詢注冊信息時,可以直接從請求的 Nacos 的節(jié)點(diǎn)拿到全量數(shù)據(jù)。

讀操作的原理

這樣設(shè)計(jì)的好處是保證了高可用(AP),分為兩個方面:

  • ① 讀操作都能進(jìn)行及時的響應(yīng),不需要到其他節(jié)點(diǎn)拿數(shù)據(jù)。
  • ② 當(dāng)腦裂發(fā)生時,Nacos 的節(jié)點(diǎn)也能正常返回?cái)?shù)據(jù),即使數(shù)據(jù)可能不一致,當(dāng)網(wǎng)絡(luò)恢復(fù)時,通過健康檢查機(jī)制或數(shù)據(jù)檢驗(yàn)也能達(dá)到數(shù)據(jù)一致性。

六、總結(jié)

本篇通過原理圖 + 源碼的方式講解了 Distro 協(xié)議的原理,其中又分為幾個機(jī)制,而這幾個機(jī)制共同保證了 Nacos 的 AP。

不足之處,本篇未針對源碼的設(shè)計(jì)進(jìn)行深入剖析,只是把主線捋出來了。如文中有問題,歡迎探討~

參考資料:

Nacos 官網(wǎng)

https://blog.csdn.net/qq_24768941/article/details/122420711

https://www.cnblogs.com/lukama/p/14984858.html

責(zé)任編輯:武曉燕 來源: 悟空聊架構(gòu)
相關(guān)推薦

2020-03-16 11:55:28

PaxosRaft協(xié)議

2017-07-25 14:38:56

數(shù)據(jù)庫一致性非鎖定讀一致性鎖定讀

2022-12-14 08:23:30

2017-07-02 16:28:06

MySQL數(shù)據(jù)庫集群

2017-05-19 15:00:05

session架構(gòu)web-server

2021-02-05 08:00:48

哈希算法?機(jī)器

2022-06-07 12:08:10

Paxos算法

2021-02-02 12:40:50

哈希算法數(shù)據(jù)

2021-02-04 06:30:26

Python編程語言

2021-07-26 06:33:42

CRDT數(shù)據(jù)CAP

2021-06-22 10:22:08

業(yè)務(wù)IT一致性首席信息官

2023-11-22 12:55:59

微服務(wù)架構(gòu)數(shù)據(jù)庫

2019-01-15 17:58:03

微服務(wù)架構(gòu)數(shù)據(jù)

2019-12-17 08:40:33

微服務(wù)架構(gòu)數(shù)據(jù)

2020-11-24 09:03:41

一致性MySQLMVCC

2020-05-12 10:43:22

Redis緩存數(shù)據(jù)庫

2022-03-22 09:54:22

Hash算法

2021-06-30 21:13:49

CPUCache數(shù)據(jù)

2022-10-19 12:22:53

并發(fā)扣款一致性

2020-05-11 10:30:57

2PC分布式協(xié)議
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 久草网站| 青青草华人在线视频 | 国产精品爱久久久久久久 | 一级一级一级毛片 | 综合成人在线 | 国产精品久久久久久久久久 | 日韩中文在线观看 | 亚洲最大av | 性xxxxx | 日本免费小视频 | 99久热在线精品视频观看 | 亚洲精品一区二区三区 | 免费视频一区二区 | 国产精品亚洲一区二区三区在线 | 久久国产欧美一区二区三区精品 | 中文字幕在线观看 | 成年免费大片黄在线观看一级 | 古装人性做爰av网站 | 色免费看 | 国产xxx在线观看 | 欧美亚洲一区二区三区 | 日屁网站| 精品久久久久久 | 欧美涩 | xxx.在线观看 | 美国a级毛片免费视频 | 欧美色综合 | 91精品中文字幕一区二区三区 | www.精品国产 | 亚洲一二三区精品 | 精品视频久久久 | 国产精品久久久久久久久久软件 | 视频在线观看一区二区 | 久久一区二区三区免费 | 亚洲成人av | 中文字幕在线电影观看 | 亚洲一区国产精品 | 久久网一区二区三区 | 欧美精品在线播放 | 精品自拍视频 | 欧美国产精品一区二区三区 |