1. 程式人生 > 其它 >基於etcd實現大規模服務治理應用實戰

基於etcd實現大規模服務治理應用實戰

基於etcd實現大規模服務治理應用實戰 https://mp.weixin.qq.com/s/1VmMZlMEv-In9QKYeYOjiA

基於etcd實現大規模服務治理應用實戰

百度小程式團隊百度Geek說2021-11-10 收錄於話題 百度Geek說 關注我們,帶你瞭解更多百度技術乾貨。 65篇原創內容 公眾號

導讀:服務治理目前越來越被企業建設所重視,特別現在雲原生,微服務等各種技術被更多的企業所應用,本文內容是百度小程式團隊基於大模型服務治理實戰經驗的一些總結,同時結合當前較火的分散式開源kv產品etcd,不僅會深入剖析ectd兩大核心技術Raft與boltdb的實現原理,也會披露服務治理真實實踐的經驗,希望幫助大家在服務治理的道路上獲得更多幫助。


全文8243字,預計閱讀時間21分鐘。

一、服務治理概念介紹

服務治理是IT治理的一部分,它關注服務生命週期中的相關要素,其重點環節包括服務註冊和發現、服務平滑升級、流量監控、流量管控、故障定位、安全性等。

服務是需要"治理"的,但是治理是需要成本的,如果一個服務的業務邏輯簡單,執行流程清晰,出現問題也能及時定位和回滾,那麼該服務治理的成本可能非常低,甚至只需要人工處理就行,但是在複雜業務中,服務的提供者和服務的使用者可能分別執行在不同的程序中(甚至在不同的物理節點上),並由不同的團隊開發和維護。團隊協作和服務協同,都需要進行大量的協調工作。協調工作越多,複雜度越高,這樣就有了服務治理的需求,通過建設統一的服務治理平臺,就可以有有效的提升業務的服務治理能力,包括協同的規範化、實時監控,不斷優化呼叫鏈路的效率,以及輔助降低依賴複雜度,規避風險等。在大型業務系統中,服務治理已經是技術架構中必不可缺的一部分,也是整個業務系統最重要的基礎設施之一。

上圖是網上流傳的netflix的服務拓撲圖,圖中密密麻麻的白色小點就是netflix的服務節點,節點之間的連線表明服務之間有呼叫,節點和連線構成了複雜的服務呼叫鏈,如此龐大的應用系統必須要通過一個強力的服務治理平臺來進行管理。

服務治理本質上是對服務生命週期的管控,因而服務治理平臺的核心需求就是如何解決服務生命週期中的痛點問題,其包括以下幾個方面:
1、註冊和發現服務呼叫方在呼叫服務之前必須要得到服務提供方的地址,也就是呼叫方需要通過一種方式“發現“服務提供方,這就是服務發現。而要完成服務發現,就需要將服務提供方的資訊儲存到某個載體,這個儲存的動作即是”服務註冊“,而儲存的載體則稱為”服務註冊中心“。在任何一個服務治理平臺中,"註冊中心"是必不可少的一個模組。服務註冊和發現是服務治理中最基礎的功能,在服務生命週期中,它負責服務的初始環節。


2、流量監控
在服務註冊發現之後,就是服務的呼叫,大量的服務呼叫,形成了流量。流量監控就是對眾多服務間的呼叫關係、狀態的清晰掌控。其主要包括了呼叫拓撲關係、呼叫追蹤、日誌、監控告警等,服務治理通過呼叫拓撲來整體監控服務呼叫關係,通過建立監控體系來快速發現、定位問題,從而在整體上感知業務系統的執行狀況。在服務生命週期中,流量監控負責服務的執行態感知。

3、流量排程
在業務系統執行過程中,經常會有比如促銷、秒殺、明星緋聞等熱點問題,或者機房斷網、斷電、系統大範圍升級等突發事件,帶來業務系統中區域性服務的流量突增突降,這樣就需要對服務的流量進行排程和管理。流量管理包括兩個方面:從微觀的單個服務來說,就是服務呼叫過程的管理,包括在何時採用何種均衡負載策略、路由策略以及熔斷限流策略,這些策略統稱為呼叫策略;從巨集觀上來說,就是流量分發的管理,可以根據某些流量特徵和流量佔比進行灰度釋出、藍綠髮布等,這些稱為流量分發策略。服務呼叫策略、流量分發策略,都需要通過流量監控收集的呼叫資料進行分析,從而制定出決策,然後在服務治理平臺上落地。流量排程負責服務的執行態管理。

4、服務控制
流量排程的策略如何在服務的提供方和呼叫方生效,可以重啟生效,也可以在執行態實時生效,這就是看服務治理平臺對服務的控制力度,服務治理平臺在充分建設服務治理能力後,能實時把服務治理的策略向服務進行分發並立即生效。

5、服務安全
每個服務都承載自身的業務職責,一些業務敏感的服務,需要對其他服務的訪問進行認證與鑑權,也就是安全問題。
本文把擁有成千上萬的服務稱之為大型應用系統,該系統的特徵是大量的服務、大量的服務例項、以及海量的服務呼叫,服務治理平臺在管理這類業務系統的服務時,需要面對以下巨大的挑戰:1. 高可靠性
大型業務系統,海量的服務呼叫,錯綜複雜的呼叫關係,對服務的可靠性要求很高,很多基層的服務都要求99.99%的可靠性,因而維護這些服務的服務治理平臺,其可靠性的要求也非常高,而要達到這麼高的可靠性,服務治理平臺本身也需要做到多級部署、多地熱備、降級隔離、平滑上線等方案。

2. 高效能
在保證可靠性的前提下,服務治理還必須有很高的效能,比如在監控資料中,快速準確的感知到某個服務的出現了單點故障,從而能夠將流量分發到該服務的其他程序上去。如果業務系統的服務數不多,呼叫量不高,那麼監控資料量也不會很大,服務的單點故障很容易就能查到,但是在實時的海量呼叫資料中,一些常規的查詢手段要花費大量的時間,等感知到單點故障時,可能已經造成了不可挽回的業務損失。所以效能是考量服務治理平臺治理能力的一項重要指標,如何保證高效能,高速的儲存、多級快取、線性部署都是必不可少的。

3. 高擴充套件
高擴充套件包含兩個方面:大型應用系統的服務,可能是由多個團隊在開發運維,其水平和技術能力也是參差不齊的,因而服務治理平臺需要提供相容和擴充套件的能力,通過擴充套件性,儘可能的把不同的服務治理起來;同時,在業務系統服務量增長時,服務治理平臺也應該具備同步擴充套件的能力,來保證其高可靠和高效能。

面對海量服務的治理挑戰,服務治理平臺也需要有一個強大好用的儲存工具來應對,etcd就是一個不錯的選擇。

二、etcd介紹

2.1 etcd發展背景與相關競品介紹

2013年CoreOS創業團隊在構建一款開源,輕量級的作業系統ContainerLinux時,為了應對使用者服務多副本之間協調的問題,自研開發的一款用於配置共享和服務發現的高可用KV分散式儲存元件——ETCD。
下面我們也針對Zookeeper和Consul兩個選型做了一下對比:· ZooKeeper
ZooKeeper從高可用性,資料一致性,功能這三個方面而言是完全符合需求的,但CoreOS還是堅持自研etcd的原因總結有以下兩點:
1. ZooKeeper不支援通過API安全地變更成員,需要人工修改節點配置並重啟程序.如果操作有誤,有可能導致腦裂等線上故障,同時CoreOS對適配雲環境,叢集規模的平滑調整,執行時配置的線上變更都是有期望目標的,這方面ZooKeeper的維護成本比較高。2.高負載讀寫效能,ZooKeeper在大規模的例項連線情況下效能表現並不佳。
etcd名字是由/etc”資料夾和”d”分散式系統組成。“/etc”資料夾是用來儲存單系統配置資料的,而etcd”用於儲存大規模分散式系統的配置資料,etcd叢集可提供高穩定性,高可靠性,高伸縮性和高效能的分散式KV儲存服務。etcd是基於複製狀態機實現的,由Raft一致性模組,日誌模組,基於boltdb持久化儲存的狀態機組成,可應用於分散式系統的配置管理,服務發現,分散式一致性等等。
ZooKeeper與etcd一樣,可解決分散式系統一致性和元資料儲存等問題,但是etcd相較於ZooKeeper有以下幾點優勢:1. 動態叢集成員關係重新配置2. 高負載下穩定的讀寫能力3. 多版本併發控制資料模型4. 可靠的鍵監控5. Lease(租約)原語將連線和會話分離6. 分散式鎖保證API安全性7. ZooKeeper使用自己的RPC協議,使用受限;而etcd客戶端協議是基於gRPC的,可支援多種語言。· ConsulConsul與etcd解決的是不同的問題,etcd用於分散式一致性KV儲存,而Consul側重於端到端的服務發現,它提供了內建的健康檢查,失敗檢測和DNS服務等等,另外Consul通過RESTfulHTTPAPIs提供KV儲存能力.但是當KV使用量達到百萬級時,會出現高延遲和記憶體壓力等問題。
一致性演算法方面,etcd、Consul基於Raft演算法實現資料複製,ZooKeeper則是基於Zab演算法實現。Raft演算法由Leader選舉,日誌同步,安全性組成,而Zab協議則由Leader選舉、發現、同步、廣播組成。分散式CAP方面,etcd、Consul和ZooKeeper都是CP系統,發生網路分割槽時,無法寫入新資料。
下表是針對三者的關鍵能力做了一下對比分析:


2.2 etcd核心技術介紹

基於Raft協議實現資料高可用和強一致性

早期資料儲存服務引入多副本複製技術方案來解決單點問題,但是無論是主從複製還是去中性化複製,都存在一定的缺陷。主從複製運維困難,且一致性與可用性難以兼顧;去中心化複製,存在各種寫入衝突問題需要業務處理。而分散式一致性演算法,正是解決多副本複製存在問題的關鍵。分散式一致性演算法,又稱為共識演算法,最早是基於複製狀態機背景下提出來的。Paxos作為第一個共識演算法,過於複雜,不容易理解,難以在工程上落地。斯坦福大學的Diego提出的Raft演算法,通過將問題拆解為三個子問題,易於理解,降低了工程落地難度。這三個子問題是:Leader選舉,日誌複製,安全性。

Leader選舉

etcd(版本3.4+)中Raft協議定義叢集節點有4種狀態:Leader、Follower、Candidate、PreCandidate。
正常情況下,Leader節點會按照心跳間隔時間,定時廣播心跳訊息給Follower節點,以維持Leader身份。Follower收到後回覆心跳應答包訊息給Leader。Leader都會帶有一個任期號(term),任期表示從一次選舉開始,贏得選舉的節點在該任期內擔當Leader。任期號單調遞增,在Raft演算法中充當邏輯時鐘,用於比較各個節點資料新舊,識別過期Leader等等。
當Leader節點異常時,Follower節點會接收Leader的心跳訊息超時,當超時時間大於競選超時時間後,會進入PreCandidate狀態,不自增任期號,僅發起預投票(民意調查,防止由於節點資料遠遠落後於其他節點而發起無效選舉),獲得大多數節點認可後,進入Candidate狀態.進入Candidate狀態的節點,會等待一個隨機時間,然後發起選舉流程,自增任期號,投票給自己,並向其他節點發送競選投票資訊。
當節點B收到節點A競選訊息後,有2種情況:1. 節點B判斷節點A的資料至少和自己一樣新,節點A任期號大於節點B任期號,並且節點B未投票給其他候選者,即可投票給節點A,節點A獲得叢集大多數節點支援,可成為新Leader。2. 如果節點B也發起了選舉,並投票給自己,那麼它將拒絕投票給節點A。此時若沒有節點可以得到大多數投票支援,則只能等待競選超時,開啟新一輪選舉。


日誌複製

Raft日誌結構如下圖所示:
Raft日誌由有序索引的一個個條目組成,每個日誌條目包含了任期號和提案內容.Leader通過維護兩個欄位來追蹤各個Follower的進度資訊.一個是NextIndex,表示Leader傳送給該Follower節點的下一個日誌條目索引;另一個是MatchIndex,表示該Follower節點已複製的最大日誌條目索引。
本文以Client提交“hello=world”提案,至接收到響應的整個流程為例,簡單介紹etcd日誌複製流程:1. 當Leader接收到Client提交的提案資訊後,生成日誌條目,同時遍歷各個Follower的日誌進度,生成對各個Follower追加日誌的RPC訊息;2. 通過網路模組將追加日誌的RPC訊息廣播給各個Follower;3. Follower接收到追加日誌訊息並持久化之後,回覆Leader已複製最大日誌條目索引,即MatchIndex;4. Leader接收到Follower應答後,更新對應Follower的MatchIndex;5. Leader根據各個Follower提交的MatchIndex資訊,計算出日誌條目已提交索引位置,該位置代表日誌條目被一半以上節點持久化;6. Leader通過心跳告知各個Follower已提交日誌索引位置;7. 當Client的提案,被標識為已提交後,Leader回覆Client該提案通過。通過以上流程,Leader同步日誌條目給各個Follower,保證etcd叢集的資料一致性。

安全性

etcd通過給選舉和日誌複製增加了一系列規則,來保證Raft演算法的安全性。選舉規則:1. 一個任期號,只能有一個Leader被選舉,Leader選舉需要叢集一半以上節點支援;2. 節點收到選舉投票時,如果候選者最新日誌條目的任期號小於自己,拒絕投票,任期號相同但是日誌比自己短,同樣拒絕投票。日誌複製規則:1. Leader完全特性,如果某個日誌條目在某個任期號中已被提交,則這個日誌條目必然出現在更大任期號的所有Leader中;2. 只附加原則,Leader只能追加日誌條目,不能刪除已持久化的日誌條目;3. 日誌匹配特性,Leader傳送日誌追加資訊時,會帶上前一個日誌條目的索引位置(用P表示)和任期號,Follower接收到Leader的日誌追加資訊後,會校驗索引位置P的任期號與Leader是否一致,一致才能追加。

boltdb儲存技術

ectd的另一個核心技術是boltdb儲存,提供高效的b+樹的檢索能力,同時支援事務操作,他是支撐etcd高效能讀寫的關鍵能力之一。boltdb的實現參見了LMDB(LightningMemory-MappedDatabase)設計思路,基於高效快速的記憶體對映資料庫方案.基於B+樹的結構設計。資料檔案設計上bolt使用一個單獨的記憶體對映的檔案,實現一個寫入時拷貝的B+樹,這能讓讀取更快。而且,BoltDB的載入時間很快,特別是在從crash恢復的時候,因為它不需要去通過讀log(其實它壓根也沒有)去找到上次成功的事務,它僅僅從兩個B+樹的根節點讀取ID。

檔案儲存設計

由於採用了單檔案對映儲存,所以bolt對檔案按指定長度進行分塊處理,每塊儲存不同的內容型別。預設使用4096位元組的長度進行分塊。每一塊的開頭有單獨的pageid(int64)標識。
檔案塊的型別有以下幾種:

型別

Flag標識

個數

長度

說明

meta

0x04

2

80位元組。其餘為空

元資料資訊。包含儲存B+樹root buck位置,可用塊的數量freelist,當前最大塊的offset等。分為metaA與metaB, 用來控制進行中的事務與已完成的事務(寫事務只有一個進行中). 根據meta中的txid的值的大小來判斷當前生效的是哪個meta。(txid會根據事務操作遞增)

freelist

0x10

1或多個

Overflow引用

變長

Freelist用於管理當前可用的pageid列表。由Meta元資料資訊中的freelist欄位來定位所在的pageid位置。

【data】bucket

0x01

1或多個

Overflow引用

變長

儲存bucket名稱資料,bucket名稱也是採用B+樹結構儲存。根root bucket的pageid由meat的root欄位指定

【data】branch

0x01

1或多個

Overflow引用

變長

儲存分支資料內容。分支資料結構中只有key資訊,沒有value資訊。指向的都是下一級節點的pageid資訊

【data】leaf

0x02

1或多個

Overflow引用

變長

儲存葉子資料內容。

資料檔案全景結構


說明:
  • metapage固定在page0與page1位置
  • Pagesize大小固定在4096位元組
  • bolt的檔案寫入採用了本地序(小端序)的模式,比如16進位制0x0827(2087)寫入的內容為2708000000000000
單檔案方案的優勢就是不需要做檔案的合併刪除等操作,只需要在原檔案上追加擴充套件長度就可以了。

查詢設計

boltdb提供了非常高效的查詢能力,可以先看一下它的物件設計:


從物件設計上,boltdb在載入時,會先loadmeta資料進記憶體,然後根據bucket,來定位資料塊所在的位置,然後再根據key的值,來定位branchnode的位置,然後定位到葉子值節點。我們以查詢為例,來講解一下,下面是一個基本的查詢示例程式碼:
tx, err := db.Begin(true) // 開啟事務  if err != nil {      return  }  b := tx.Bucket([]byte("MyBucket")) // 根據名稱查詢bucket  v := b.Get([]byte("answer20")) // 根據key進行查詢   fmt.Println(string(v))  tx.Commit()

對應上面的程式碼,下面的序列圖,可以更詳細的瞭解一次查詢的操作流程:

上面最關鍵的程式碼就是search方法,下面是主要的程式碼片斷,已添加了註釋說明方便閱讀。
func (c *Cursor) search(key []byte, pgid pgid) {    p, n := c.bucket.pageNode(pgid)    if p != nil && (p.flags&(branchPageFlag|leafPageFlag)) == 0 {        panic(fmt.Sprintf("invalid page type: %d: %x", p.id, p.flags))    }    // 把當前查詢節點(page,node)壓入棧    e := elemRef{page: p, node: n}    c.stack = append(c.stack, e)    // If we're on a leaf page/node then find the specific node.    if e.isLeaf() {        c.nsearch(key)        return    }    // if node cached seach by node's inodes field    if n != nil {        c.searchNode(key, n)        return}    // recursively to load branch page and call search child node again    c.searchPage(key, p)}

三、百度基於etcd打造大規模服務治理建設思路

3.1 具體的挑戰

天路是百度小程式團隊開發打造的面向大型業務服務治理需求的一套解決方案,其目標之一就是打造成百度的服務治理規範樣板。天路由註冊中心、視覺化管理平臺、SDK框架、統一閘道器、tianlu-mesher五個部分組成,目前已經接入了150+產品線,例項數已達數十萬級別。隨著接入平臺的團隊數增多、以及服務例項的快速增長,大量團隊間如何輕鬆的協作以及實現大規模服務治理平臺的高可用、高效能一直是天路持續面臨的挑戰。

3.2 整體架構建設思路與方案

天路作為一個服務治理平臺,核心理念是為所有的服務提供便捷的呼叫,統一的服務監控管理,簡化服務的開發和維護成本。我們從以下不同的方面思考基於etcd打造大規模服務治理平臺:高可用、高效能、高擴充套件、易用性。· 高可用
  • 考慮到etcd跨機房呼叫的高網路延時,我們採用單機房部署,同時我們也實現了主備叢集切換的方案,解決在單機房例項全部宕機的情況下,etcd叢集不可用的問題。

  • 為了降低平臺對etcd的強依賴,我們做了etcd降級使用快取的方案。在監控到etcd叢集的效能無法支援當前平臺的時候,使用快取儲存例項資料,能夠讓運維人員在恢復etcd之前,系統不受影響正常執行;etcd恢復之後,切換回etcd叢集繼續工作。


· 高效能
  • etcd叢集的kv查詢效能很高,qps能達到10000以上。為了解決在極端併發下的效能問題,註冊中心採用多級快取提升查詢效率,降低對etcd的訪問壓力。

  • 服務間呼叫使用直連的方式,請求不需要經過註冊中心進行轉發,呼叫基本沒有時間損耗。


· 高擴充套件
  • 考慮到將來服務例項數達到百萬級別,我們需要考慮架構的高擴充套件性。


· 易用性
  • 使用者通過視覺化的管理平臺可以檢視已註冊的服務,也可通過管理平臺實時更新服務治理策略的配置,實時調整服務治理策略。

  • 將呼叫日誌接入trace平臺,使用者可通過traceId在trace平臺查到整個呼叫鏈的記錄,便於出錯時進行快速的問題定位。

  • 多語言 SDK,支援多種rpc技術,包括百度自研的rpc技術brpc(https://github.com/baidu/Jprotobuf-rpc-socket【java/go sdk】)和http jsonrpc協議等

架構方案圖

3.3 關鍵的指標與運維目標

此外針對更好的實施服務治理平臺的運維,還需要以下的關鍵考核指標與運維要求。

關鍵指標:

· 可用性達99.99以上;· 平響100ms以下。

運維目標:

  • 故障發現早

· 配置監控告警,包括註冊中心例項健康、etcd平響、記憶體和cpu監控。
  • 故障處理快

· 自動處理:通過noah的回撥機制,自動處理一些故障,提高處理速度。· 手動處理:值班機制。

四、總結

服務治理目前越來越被企業建設所重視,特別現在雲原生,微服務等各種技術被更多的企業所應用,但是要真正在應用好,融合好,還是有非常多的挑戰,除了一套成熟的服務治理產品外,包括團隊整體對服務治理的認知,技術經驗的深澱,遵循服務化的設計能力水平的能力等,都會影響到最終的實施效果。本文也僅在服務治理產品選型上給大家一些啟發,希望在服務治理的道路上幫大家走得更好更穩。

基於etcd實現大規模服務治理應用實戰

百度小程式團隊百度Geek說2021-11-10 收錄於話題 百度Geek說 關注我們,帶你瞭解更多百度技術乾貨。 65篇原創內容 公眾號

導讀:服務治理目前越來越被企業建設所重視,特別現在雲原生,微服務等各種技術被更多的企業所應用,本文內容是百度小程式團隊基於大模型服務治理實戰經驗的一些總結,同時結合當前較火的分散式開源kv產品etcd,不僅會深入剖析ectd兩大核心技術Raft與boltdb的實現原理,也會披露服務治理真實實踐的經驗,希望幫助大家在服務治理的道路上獲得更多幫助。

全文8243字,預計閱讀時間21分鐘。

一、服務治理概念介紹

服務治理是IT治理的一部分,它關注服務生命週期中的相關要素,其重點環節包括服務註冊和發現、服務平滑升級、流量監控、流量管控、故障定位、安全性等。

服務是需要"治理"的,但是治理是需要成本的,如果一個服務的業務邏輯簡單,執行流程清晰,出現問題也能及時定位和回滾,那麼該服務治理的成本可能非常低,甚至只需要人工處理就行,但是在複雜業務中,服務的提供者和服務的使用者可能分別執行在不同的程序中(甚至在不同的物理節點上),並由不同的團隊開發和維護。團隊協作和服務協同,都需要進行大量的協調工作。協調工作越多,複雜度越高,這樣就有了服務治理的需求,通過建設統一的服務治理平臺,就可以有有效的提升業務的服務治理能力,包括協同的規範化、實時監控,不斷優化呼叫鏈路的效率,以及輔助降低依賴複雜度,規避風險等。在大型業務系統中,服務治理已經是技術架構中必不可缺的一部分,也是整個業務系統最重要的基礎設施之一。

上圖是網上流傳的netflix的服務拓撲圖,圖中密密麻麻的白色小點就是netflix的服務節點,節點之間的連線表明服務之間有呼叫,節點和連線構成了複雜的服務呼叫鏈,如此龐大的應用系統必須要通過一個強力的服務治理平臺來進行管理。

服務治理本質上是對服務生命週期的管控,因而服務治理平臺的核心需求就是如何解決服務生命週期中的痛點問題,其包括以下幾個方面:
1、註冊和發現服務呼叫方在呼叫服務之前必須要得到服務提供方的地址,也就是呼叫方需要通過一種方式“發現“服務提供方,這就是服務發現。而要完成服務發現,就需要將服務提供方的資訊儲存到某個載體,這個儲存的動作即是”服務註冊“,而儲存的載體則稱為”服務註冊中心“。在任何一個服務治理平臺中,"註冊中心"是必不可少的一個模組。服務註冊和發現是服務治理中最基礎的功能,在服務生命週期中,它負責服務的初始環節。

2、流量監控
在服務註冊發現之後,就是服務的呼叫,大量的服務呼叫,形成了流量。流量監控就是對眾多服務間的呼叫關係、狀態的清晰掌控。其主要包括了呼叫拓撲關係、呼叫追蹤、日誌、監控告警等,服務治理通過呼叫拓撲來整體監控服務呼叫關係,通過建立監控體系來快速發現、定位問題,從而在整體上感知業務系統的執行狀況。在服務生命週期中,流量監控負責服務的執行態感知。

3、流量排程
在業務系統執行過程中,經常會有比如促銷、秒殺、明星緋聞等熱點問題,或者機房斷網、斷電、系統大範圍升級等突發事件,帶來業務系統中區域性服務的流量突增突降,這樣就需要對服務的流量進行排程和管理。流量管理包括兩個方面:從微觀的單個服務來說,就是服務呼叫過程的管理,包括在何時採用何種均衡負載策略、路由策略以及熔斷限流策略,這些策略統稱為呼叫策略;從巨集觀上來說,就是流量分發的管理,可以根據某些流量特徵和流量佔比進行灰度釋出、藍綠髮布等,這些稱為流量分發策略。服務呼叫策略、流量分發策略,都需要通過流量監控收集的呼叫資料進行分析,從而制定出決策,然後在服務治理平臺上落地。流量排程負責服務的執行態管理。

4、服務控制
流量排程的策略如何在服務的提供方和呼叫方生效,可以重啟生效,也可以在執行態實時生效,這就是看服務治理平臺對服務的控制力度,服務治理平臺在充分建設服務治理能力後,能實時把服務治理的策略向服務進行分發並立即生效。

5、服務安全
每個服務都承載自身的業務職責,一些業務敏感的服務,需要對其他服務的訪問進行認證與鑑權,也就是安全問題。
本文把擁有成千上萬的服務稱之為大型應用系統,該系統的特徵是大量的服務、大量的服務例項、以及海量的服務呼叫,服務治理平臺在管理這類業務系統的服務時,需要面對以下巨大的挑戰:1. 高可靠性
大型業務系統,海量的服務呼叫,錯綜複雜的呼叫關係,對服務的可靠性要求很高,很多基層的服務都要求99.99%的可靠性,因而維護這些服務的服務治理平臺,其可靠性的要求也非常高,而要達到這麼高的可靠性,服務治理平臺本身也需要做到多級部署、多地熱備、降級隔離、平滑上線等方案。

2. 高效能
在保證可靠性的前提下,服務治理還必須有很高的效能,比如在監控資料中,快速準確的感知到某個服務的出現了單點故障,從而能夠將流量分發到該服務的其他程序上去。如果業務系統的服務數不多,呼叫量不高,那麼監控資料量也不會很大,服務的單點故障很容易就能查到,但是在實時的海量呼叫資料中,一些常規的查詢手段要花費大量的時間,等感知到單點故障時,可能已經造成了不可挽回的業務損失。所以效能是考量服務治理平臺治理能力的一項重要指標,如何保證高效能,高速的儲存、多級快取、線性部署都是必不可少的。

3. 高擴充套件
高擴充套件包含兩個方面:大型應用系統的服務,可能是由多個團隊在開發運維,其水平和技術能力也是參差不齊的,因而服務治理平臺需要提供相容和擴充套件的能力,通過擴充套件性,儘可能的把不同的服務治理起來;同時,在業務系統服務量增長時,服務治理平臺也應該具備同步擴充套件的能力,來保證其高可靠和高效能。

面對海量服務的治理挑戰,服務治理平臺也需要有一個強大好用的儲存工具來應對,etcd就是一個不錯的選擇。

二、etcd介紹

2.1 etcd發展背景與相關競品介紹

2013年CoreOS創業團隊在構建一款開源,輕量級的作業系統ContainerLinux時,為了應對使用者服務多副本之間協調的問題,自研開發的一款用於配置共享和服務發現的高可用KV分散式儲存元件——ETCD。
下面我們也針對Zookeeper和Consul兩個選型做了一下對比:· ZooKeeper
ZooKeeper從高可用性,資料一致性,功能這三個方面而言是完全符合需求的,但CoreOS還是堅持自研etcd的原因總結有以下兩點:
1. ZooKeeper不支援通過API安全地變更成員,需要人工修改節點配置並重啟程序.如果操作有誤,有可能導致腦裂等線上故障,同時CoreOS對適配雲環境,叢集規模的平滑調整,執行時配置的線上變更都是有期望目標的,這方面ZooKeeper的維護成本比較高。2.高負載讀寫效能,ZooKeeper在大規模的例項連線情況下效能表現並不佳。
etcd名字是由/etc”資料夾和”d”分散式系統組成。“/etc”資料夾是用來儲存單系統配置資料的,而etcd”用於儲存大規模分散式系統的配置資料,etcd叢集可提供高穩定性,高可靠性,高伸縮性和高效能的分散式KV儲存服務。etcd是基於複製狀態機實現的,由Raft一致性模組,日誌模組,基於boltdb持久化儲存的狀態機組成,可應用於分散式系統的配置管理,服務發現,分散式一致性等等。
ZooKeeper與etcd一樣,可解決分散式系統一致性和元資料儲存等問題,但是etcd相較於ZooKeeper有以下幾點優勢:1. 動態叢集成員關係重新配置2. 高負載下穩定的讀寫能力3. 多版本併發控制資料模型4. 可靠的鍵監控5. Lease(租約)原語將連線和會話分離6. 分散式鎖保證API安全性7. ZooKeeper使用自己的RPC協議,使用受限;而etcd客戶端協議是基於gRPC的,可支援多種語言。· ConsulConsul與etcd解決的是不同的問題,etcd用於分散式一致性KV儲存,而Consul側重於端到端的服務發現,它提供了內建的健康檢查,失敗檢測和DNS服務等等,另外Consul通過RESTfulHTTPAPIs提供KV儲存能力.但是當KV使用量達到百萬級時,會出現高延遲和記憶體壓力等問題。
一致性演算法方面,etcd、Consul基於Raft演算法實現資料複製,ZooKeeper則是基於Zab演算法實現。Raft演算法由Leader選舉,日誌同步,安全性組成,而Zab協議則由Leader選舉、發現、同步、廣播組成。分散式CAP方面,etcd、Consul和ZooKeeper都是CP系統,發生網路分割槽時,無法寫入新資料。
下表是針對三者的關鍵能力做了一下對比分析:


2.2 etcd核心技術介紹

基於Raft協議實現資料高可用和強一致性

早期資料儲存服務引入多副本複製技術方案來解決單點問題,但是無論是主從複製還是去中性化複製,都存在一定的缺陷。主從複製運維困難,且一致性與可用性難以兼顧;去中心化複製,存在各種寫入衝突問題需要業務處理。而分散式一致性演算法,正是解決多副本複製存在問題的關鍵。分散式一致性演算法,又稱為共識演算法,最早是基於複製狀態機背景下提出來的。Paxos作為第一個共識演算法,過於複雜,不容易理解,難以在工程上落地。斯坦福大學的Diego提出的Raft演算法,通過將問題拆解為三個子問題,易於理解,降低了工程落地難度。這三個子問題是:Leader選舉,日誌複製,安全性。

Leader選舉

etcd(版本3.4+)中Raft協議定義叢集節點有4種狀態:Leader、Follower、Candidate、PreCandidate。
正常情況下,Leader節點會按照心跳間隔時間,定時廣播心跳訊息給Follower節點,以維持Leader身份。Follower收到後回覆心跳應答包訊息給Leader。Leader都會帶有一個任期號(term),任期表示從一次選舉開始,贏得選舉的節點在該任期內擔當Leader。任期號單調遞增,在Raft演算法中充當邏輯時鐘,用於比較各個節點資料新舊,識別過期Leader等等。
當Leader節點異常時,Follower節點會接收Leader的心跳訊息超時,當超時時間大於競選超時時間後,會進入PreCandidate狀態,不自增任期號,僅發起預投票(民意調查,防止由於節點資料遠遠落後於其他節點而發起無效選舉),獲得大多數節點認可後,進入Candidate狀態.進入Candidate狀態的節點,會等待一個隨機時間,然後發起選舉流程,自增任期號,投票給自己,並向其他節點發送競選投票資訊。
當節點B收到節點A競選訊息後,有2種情況:1. 節點B判斷節點A的資料至少和自己一樣新,節點A任期號大於節點B任期號,並且節點B未投票給其他候選者,即可投票給節點A,節點A獲得叢集大多數節點支援,可成為新Leader。2. 如果節點B也發起了選舉,並投票給自己,那麼它將拒絕投票給節點A。此時若沒有節點可以得到大多數投票支援,則只能等待競選超時,開啟新一輪選舉。


日誌複製

Raft日誌結構如下圖所示:
Raft日誌由有序索引的一個個條目組成,每個日誌條目包含了任期號和提案內容.Leader通過維護兩個欄位來追蹤各個Follower的進度資訊.一個是NextIndex,表示Leader傳送給該Follower節點的下一個日誌條目索引;另一個是MatchIndex,表示該Follower節點已複製的最大日誌條目索引。
本文以Client提交“hello=world”提案,至接收到響應的整個流程為例,簡單介紹etcd日誌複製流程:1. 當Leader接收到Client提交的提案資訊後,生成日誌條目,同時遍歷各個Follower的日誌進度,生成對各個Follower追加日誌的RPC訊息;2. 通過網路模組將追加日誌的RPC訊息廣播給各個Follower;3. Follower接收到追加日誌訊息並持久化之後,回覆Leader已複製最大日誌條目索引,即MatchIndex;4. Leader接收到Follower應答後,更新對應Follower的MatchIndex;5. Leader根據各個Follower提交的MatchIndex資訊,計算出日誌條目已提交索引位置,該位置代表日誌條目被一半以上節點持久化;6. Leader通過心跳告知各個Follower已提交日誌索引位置;7. 當Client的提案,被標識為已提交後,Leader回覆Client該提案通過。通過以上流程,Leader同步日誌條目給各個Follower,保證etcd叢集的資料一致性。

安全性

etcd通過給選舉和日誌複製增加了一系列規則,來保證Raft演算法的安全性。選舉規則:1. 一個任期號,只能有一個Leader被選舉,Leader選舉需要叢集一半以上節點支援;2. 節點收到選舉投票時,如果候選者最新日誌條目的任期號小於自己,拒絕投票,任期號相同但是日誌比自己短,同樣拒絕投票。日誌複製規則:1. Leader完全特性,如果某個日誌條目在某個任期號中已被提交,則這個日誌條目必然出現在更大任期號的所有Leader中;2. 只附加原則,Leader只能追加日誌條目,不能刪除已持久化的日誌條目;3. 日誌匹配特性,Leader傳送日誌追加資訊時,會帶上前一個日誌條目的索引位置(用P表示)和任期號,Follower接收到Leader的日誌追加資訊後,會校驗索引位置P的任期號與Leader是否一致,一致才能追加。

boltdb儲存技術

ectd的另一個核心技術是boltdb儲存,提供高效的b+樹的檢索能力,同時支援事務操作,他是支撐etcd高效能讀寫的關鍵能力之一。boltdb的實現參見了LMDB(LightningMemory-MappedDatabase)設計思路,基於高效快速的記憶體對映資料庫方案.基於B+樹的結構設計。資料檔案設計上bolt使用一個單獨的記憶體對映的檔案,實現一個寫入時拷貝的B+樹,這能讓讀取更快。而且,BoltDB的載入時間很快,特別是在從crash恢復的時候,因為它不需要去通過讀log(其實它壓根也沒有)去找到上次成功的事務,它僅僅從兩個B+樹的根節點讀取ID。

檔案儲存設計

由於採用了單檔案對映儲存,所以bolt對檔案按指定長度進行分塊處理,每塊儲存不同的內容型別。預設使用4096位元組的長度進行分塊。每一塊的開頭有單獨的pageid(int64)標識。
檔案塊的型別有以下幾種:

型別

Flag標識

個數

長度

說明

meta

0x04

2

80位元組。其餘為空

元資料資訊。包含儲存B+樹root buck位置,可用塊的數量freelist,當前最大塊的offset等。分為metaA與metaB, 用來控制進行中的事務與已完成的事務(寫事務只有一個進行中). 根據meta中的txid的值的大小來判斷當前生效的是哪個meta。(txid會根據事務操作遞增)

freelist

0x10

1或多個

Overflow引用

變長

Freelist用於管理當前可用的pageid列表。由Meta元資料資訊中的freelist欄位來定位所在的pageid位置。

【data】bucket

0x01

1或多個

Overflow引用

變長

儲存bucket名稱資料,bucket名稱也是採用B+樹結構儲存。根root bucket的pageid由meat的root欄位指定

【data】branch

0x01

1或多個

Overflow引用

變長

儲存分支資料內容。分支資料結構中只有key資訊,沒有value資訊。指向的都是下一級節點的pageid資訊

【data】leaf

0x02

1或多個

Overflow引用

變長

儲存葉子資料內容。

資料檔案全景結構


說明:
  • metapage固定在page0與page1位置
  • Pagesize大小固定在4096位元組
  • bolt的檔案寫入採用了本地序(小端序)的模式,比如16進位制0x0827(2087)寫入的內容為2708000000000000
單檔案方案的優勢就是不需要做檔案的合併刪除等操作,只需要在原檔案上追加擴充套件長度就可以了。

查詢設計

boltdb提供了非常高效的查詢能力,可以先看一下它的物件設計:


從物件設計上,boltdb在載入時,會先loadmeta資料進記憶體,然後根據bucket,來定位資料塊所在的位置,然後再根據key的值,來定位branchnode的位置,然後定位到葉子值節點。我們以查詢為例,來講解一下,下面是一個基本的查詢示例程式碼:
tx, err := db.Begin(true) // 開啟事務  if err != nil {      return  }  b := tx.Bucket([]byte("MyBucket")) // 根據名稱查詢bucket  v := b.Get([]byte("answer20")) // 根據key進行查詢   fmt.Println(string(v))  tx.Commit()

對應上面的程式碼,下面的序列圖,可以更詳細的瞭解一次查詢的操作流程:

上面最關鍵的程式碼就是search方法,下面是主要的程式碼片斷,已添加了註釋說明方便閱讀。
func (c *Cursor) search(key []byte, pgid pgid) {    p, n := c.bucket.pageNode(pgid)    if p != nil && (p.flags&(branchPageFlag|leafPageFlag)) == 0 {        panic(fmt.Sprintf("invalid page type: %d: %x", p.id, p.flags))    }    // 把當前查詢節點(page,node)壓入棧    e := elemRef{page: p, node: n}    c.stack = append(c.stack, e)    // If we're on a leaf page/node then find the specific node.    if e.isLeaf() {        c.nsearch(key)        return    }    // if node cached seach by node's inodes field    if n != nil {        c.searchNode(key, n)        return}    // recursively to load branch page and call search child node again    c.searchPage(key, p)}

三、百度基於etcd打造大規模服務治理建設思路

3.1 具體的挑戰

天路是百度小程式團隊開發打造的面向大型業務服務治理需求的一套解決方案,其目標之一就是打造成百度的服務治理規範樣板。天路由註冊中心、視覺化管理平臺、SDK框架、統一閘道器、tianlu-mesher五個部分組成,目前已經接入了150+產品線,例項數已達數十萬級別。隨著接入平臺的團隊數增多、以及服務例項的快速增長,大量團隊間如何輕鬆的協作以及實現大規模服務治理平臺的高可用、高效能一直是天路持續面臨的挑戰。

3.2 整體架構建設思路與方案

天路作為一個服務治理平臺,核心理念是為所有的服務提供便捷的呼叫,統一的服務監控管理,簡化服務的開發和維護成本。我們從以下不同的方面思考基於etcd打造大規模服務治理平臺:高可用、高效能、高擴充套件、易用性。· 高可用
  • 考慮到etcd跨機房呼叫的高網路延時,我們採用單機房部署,同時我們也實現了主備叢集切換的方案,解決在單機房例項全部宕機的情況下,etcd叢集不可用的問題。

  • 為了降低平臺對etcd的強依賴,我們做了etcd降級使用快取的方案。在監控到etcd叢集的效能無法支援當前平臺的時候,使用快取儲存例項資料,能夠讓運維人員在恢復etcd之前,系統不受影響正常執行;etcd恢復之後,切換回etcd叢集繼續工作。


· 高效能
  • etcd叢集的kv查詢效能很高,qps能達到10000以上。為了解決在極端併發下的效能問題,註冊中心採用多級快取提升查詢效率,降低對etcd的訪問壓力。

  • 服務間呼叫使用直連的方式,請求不需要經過註冊中心進行轉發,呼叫基本沒有時間損耗。


· 高擴充套件
  • 考慮到將來服務例項數達到百萬級別,我們需要考慮架構的高擴充套件性。


· 易用性
  • 使用者通過視覺化的管理平臺可以檢視已註冊的服務,也可通過管理平臺實時更新服務治理策略的配置,實時調整服務治理策略。

  • 將呼叫日誌接入trace平臺,使用者可通過traceId在trace平臺查到整個呼叫鏈的記錄,便於出錯時進行快速的問題定位。

  • 多語言 SDK,支援多種rpc技術,包括百度自研的rpc技術brpc(https://github.com/baidu/Jprotobuf-rpc-socket【java/go sdk】)和http jsonrpc協議等

架構方案圖

3.3 關鍵的指標與運維目標

此外針對更好的實施服務治理平臺的運維,還需要以下的關鍵考核指標與運維要求。

關鍵指標:

· 可用性達99.99以上;· 平響100ms以下。

運維目標:

  • 故障發現早

· 配置監控告警,包括註冊中心例項健康、etcd平響、記憶體和cpu監控。
  • 故障處理快

· 自動處理:通過noah的回撥機制,自動處理一些故障,提高處理速度。· 手動處理:值班機制。

四、總結

服務治理目前越來越被企業建設所重視,特別現在雲原生,微服務等各種技術被更多的企業所應用,但是要真正在應用好,融合好,還是有非常多的挑戰,除了一套成熟的服務治理產品外,包括團隊整體對服務治理的認知,技術經驗的深澱,遵循服務化的設計能力水平的能力等,都會影響到最終的實施效果。本文也僅在服務治理產品選型上給大家一些啟發,希望在服務治理的道路上幫大家走得更好更穩。