Nacos config原理


一、Nacos Config與Spring Cloud Config原理對比

  說到Nacos Config配置中心的原理,就不得不提一下Spring Cloud Config配置中心的原理,二者是如此的相似,但卻也有着很多不同的特點。

  1、Spring Cloud Config原理

      

    (1)提交配置觸發post請求給server端的bus/refresh接口

    (2)server端接收到請求並發送給Spring Cloud Bus總線

    (3)pring Cloud bus接到消息並通知給其它連接到總線的客戶端

    (4)其它客戶端接收到通知,請求Server端獲取最新配置

    (5)全部客戶端均獲取到最新的配置 

  2、Nacos Config工作原理

    

 

    (1)客戶端發起長輪訓請求

    (2)服務端收到請求以后,先比較服務端緩存中的數據是否相同

      如果不同,則直接返回

      如果相同,則通過schedule延遲30s之后再執行比較。3. 為了保證當服務端在30s之內發生數據變化能夠及時通知給客戶端,服務端采用事件訂閱的方式來監聽服務端本地數據變化的事件,一旦收到事件,則觸發通知把結果寫回到客戶端,完成一次數據的推送

    (3)為了保證當服務端在30s之內發生數據變化能夠及時通知給客戶端,服務端采用事件訂閱的方式來監聽服務端本地數據變化的事件,一旦收到事件,則觸發通知把結果寫回到客戶端,完成一次數據的推送

  3、兩種配置中心對比

    Nacos Config 無需消息總線系統,系統搭建成本與復雜度比 SpringCloud Config 低很多。

    Nacos Config 不會一窩蜂向配置中心索要配置信息,Nacos Config是定點更新。

    Nacos Config 有遠程配置更新后,會自動更新到 client。其采用了長輪詢 Pull 模型。而Spring Cloud Config 則需要 client 提交請求。 

二、Nacos Config中的長輪詢Pull模型

  配置中心Server和客戶端Client實現配置的動態感知一般無外乎兩種辦法:

    一種是Client發起,叫pull模式

    一種是Server發起,叫push模式

  長輪詢中Push模式和Pull模式的對比:

    若使用 Push 模型,需要在 Server 與 Client 間通過心跳機制維護一個長連接。這個長連接的維護成本是比較高的。其適合於 Client 數量不多,且 Server 端數據變化較頻繁的場景。優點:數據更新很及時。

    若使用 Pull 模型,其無需維護長連接【29.5s】,但其實時性不好。

  Nacos 采用的是長輪詢機制的 Pull 模型,但不單純是Pull模型。是一個HttpPost的長輪詢,過期時間默認是30S。

  Nacos 長輪詢 Pull 模型融合了 Push 與 Pull 模型的優勢。Client 仍定時發起 Pull 請求,查看 Server 微服務框架 端數據是否更新。若發生了更新,則 Server 立即將更新數據以響應的形式發送給 Client 端;若沒有發生更新,Server 端並不立即向 Client 返回響應,而是臨時性的保持住這個連接一段時間【29.5s】。若在此時間段內,Server 端數據發生了變更,則立即將變更數據返回給 Client【這里是動態感知的】。若仍未發生變更,則放棄這個連接。等待着下一次 Client 的 Pull 請求。

  長輪詢 Pull 模型,是 Push 與 Pull 模型的整合,既降低了 Push 模型中長連接的維護問題,又降低了 Push 模型實時性較低的問題。 

      

 

三、Nacos采用的Raft算法及集群選舉

  1、CAP

    目前應用的比較多的注冊中心,Eureka 是 AP 的,Zookeeper 是 CP 的。默認情況下,Nacos Discovery 集群是 AP的。但其也支持 CP 模式,需要進行轉換。若要轉換為 CP 的,可以提交如下 PUT 請求,完成 AP 到 CP 的轉換。

http://localhost:8848/nacos/v1/ns/operator/switches?entry=ServerMode&value=CP

 

  2、Raft算法

    Nacos Discovery 集群為了保證集群中數據的一致性,其采用了 Raft 算法。這是一種通過對日志進行管理來達到一致性的算法。Raft 通過選舉 Leader 並由 Leader 節點負責管理日志復制來實現各個節點間數據的一致性。

    Raft算法是一個最終一致性的算法,不是強一致性算法。Raft 算法動畫演示:http://thesecretlivesofdata.com/raft/

  3、Raft Leader選舉

    在 Raft 中,節點有三種角色:

      Leader【主】:唯一負責處理客戶端寫請求的節點;也可以處理客戶端讀請求;同時負責日志復制工作

      Candidate【候選人】:Leader 選舉的候選人,其可能會成為 Leader

      Follower【從】:可以處理客戶端讀請求;負責同步來自於 Leader 的日志;當接收到其它Cadidate 的投票請求后可以進行投票;當發現 Leader 掛了,其會轉變為 Candidate 發起Leader 選舉

    除了三種角色外,還有一個iterm,可以將其看為一個編號,在Leader選舉中發揮作用.

    leader選舉流程:

        

  (1)成為候選人

    若 follower 在心跳超時范圍內沒有接收到來自於 leader 的心跳,則認為 leader 掛了。此時其首先會使其本地 term 增一。然后 follower 會完成以下步驟:

      a、此時若接收到了其它 candidate 的投票請求,會根據以下兩種情況來判斷是否投票:

        如果在我當前 term 內,且我的選票還沒有投出去,則會投票給該節點。(發來投票請求候選人candidate 的節點 term 不能小於我的 term)

        如果當前Follower節點接收到多個 candidate 的請求,當前節點將采取,先到先得的方式投票

      b、由 follower 轉變為 candidate,本地 term 加一之前尚未投票,則向自己投一票,然后向其它節點發出投票請求,然后等待響應。響應結果可能有三種情況:

        收到過半選票,成為新的 leader。然后會將消息廣播給所有其它節點,以告訴大家我是新的 Leader 了,其中就包含新的 term

        接收到別的 candidate 發來的新 leader 通知,比較了新 leader 的 term 並不比的 term小,則自己轉變為 follower

        經過一段時間后,沒有收到過半選票,也沒有收到新 leader 通知,則重新發出選舉

  (2) 票數相同怎么處理

    若在選舉過程中出現了各個 candidate 票數相同的情況,是無法選舉出 Leader 的。當出現了這種情況時,其采用了 randomized election timeouts 策略來解決這個問題。其會讓這些candidate 重新發起選舉,只不過發起時間不同:各個 candidate的選舉發起時間是在一個給定范圍內等待隨機時長 timeout 之后開始的。timeout 較小的會先開始選舉,一般情況下其會優先獲取到過半選票成為新的leader。

四、Raft 算法下集群腦裂情況

    Raft 集群存在腦裂問題。在多機房部署中,由於網絡連接問題,很容易形成多個分區。而多分區的形成,很容易產生腦裂,從而導致數據不一致。由於三機房部署的容災能力最強,所以生產環境下,三機房部署是最為常見的。下面以三機房部署為例進行分析,根據機房斷網情況,可以分為五種情況:

  (1)情況一:不確定

        

     這種情況下,B 機房中的主機是感知不到 Leader 的存在的,所以 B 機房中的主機會發起新一輪的 Leader 選舉。由於 B 機房與 C 機房是相連的,雖然 C 機房中的Follower 能夠感知到 A 機房中的 Leader,但由於其接收到了更大 term 的投票請求,所以 C 機房的 Follower也就放棄了 A 機房中的 Leader,參與了新 Leader 的選舉。

    若新 Leader 出現在 B 機房,A 機房是感知不到新 Leader 的誕生的,其不會自動下課,所以會形成腦裂。但由於 A 機房 Leader 處理的寫操作請求無法獲取到過半響應,所以無法完成寫操作。但 B 機房 Leader 的寫操作處理是可以獲取到過半響應的,所以可以完成寫操作。故,A 機房與 B、C 機房中出現腦裂,且形成了數據的不一致。

    若新 Leader 出現在 C 機房,A 機房中的 Leader 則會自動下課,所以不會形成腦裂。 

  (2)情況二:會腦裂

        

 

 

    這種情況與情況一基本是一樣的。

  (3)情況三:不會腦裂
 
       

     A、C 可以正常對外提供服務,但 B 無法選舉出新的 Leader,無法提供服務,沒有形成腦裂。

  (4)情況四:不會腦裂

        

 

    A、B、C 均可以對外提供服務,不受影響。

  (5)情況五:不會腦裂

        

     A 機房無法處理寫操作請求,但可以對外提供讀服務。B、C 機房由於失去了Leader,均會發起選舉,但由於均無法獲取過半支持,所以均無法選舉出新的Leader。 

五、Leader宕機的四種情況處理

        

   client發送請求到Nacos Config集群,Leader會將請求同步到Follower,同步完成后,才會返回客戶端成功,但是存在各種情況,但是總的來說就是只有全部同步完成才會返回客戶端成功。

  (1) 情況1:請求到達前Leader掛了

    client 發送寫操作請求到達 Leader 之前 Leader 就掛了。因為請求還沒有到達集群,所以這個請求對於集群來說就沒有存在過,對集群數據的一致性沒有任何影響。Leader 掛了之后,會選舉產生新的 Leader。由於 StaleLeader 並未向 client 發送成功處理響應,所以 client 會重新發送該寫操作請求。

  (2) 情況2:未開始同步數據前Leader掛了

    client 發送寫操作請求給 Leader,請求到達 Leader 后,Leader 還沒有開始向Followers復制數據 Leader 就掛了。這時集群會選舉產生新的 Leader,前任Leader 重啟后會作為Follower 重新加入集群,並同步新 Leader 中的數據以保證數據一致性。之前接收到 client 的數據被丟棄。由於前任 Leader 並未向 client 發送成功處理響應,所以 client 會重新發送該寫操作請求。

  (3) 情況3:同步完部分后Leader掛了

    client 發送寫操作請求給 Leader,Leader 接收完數據后開始向 Follower 復制數據。在部分 Follower 復制完后 Leader 掛了(可能過半也可能不過半)。由於Leader 掛了,就會發起新的 Leader 選舉。

      若 Leader 產生於已經復制完日志的 Follower,其會繼續將前面接收到的寫操作請求完成,並向 client 進行響應。

      若 Leader 產生於尚未復制日志的 Follower,那么原來已經復制過日志的Follower 則會將這個沒有完成的日志放棄。由於 client 沒有接收到響應,所以client 會重新發送該寫操作請求。

  (4) 情況4:apply通知發出后Leader掛了

    client 發送寫操作請求給 Leader,Leader 接收完數據后開始向 Follower 復制數據。Leader成功接收到過半 Follower 復制完畢的響應后,Leader 將日志寫入到狀態機。此時 Leader 向Follower 發送 apply 通知。在發送通知的同時,也會向 client發出響應。此時 leader 掛了。由於 前任 Leader 已經向 client 發送成功接收響應,且 apply 通知已經發出,說明這個寫操作請求已經被 server 成功處理。 

  



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM