主頁 > 資料庫 > 06、etcd 寫請求執行流程

06、etcd 寫請求執行流程

2023-07-10 08:13:01 資料庫

本篇內容主要來源于自己學習的視頻,如有侵權,請聯系洗掉,謝謝,

上一節我們學習了 etcd 讀請求執行流程,這一節,我們來學習 etcd 寫請求執行流程,

1、etcd寫請求概覽

etcd 一個寫請求執行流程又是怎樣的呢?

etcdctl 	put	 hello	world	‐‐endpoints	192.168.65.210:2379

執行流程:

  • 1、首先 client 端通過負載均衡演算法選擇一個 etcd 節點,發起 gRPC 呼叫;

  • 2、然后 etcd 節點收到請求后經過 gRPC 攔截器、Quota 模塊后,進入 KVServer 模塊;

  • 3、KVServer 模塊向 Raft 模塊提交一個提案,提案內容為“大家好,請使用 put 方法執行一個 key 為 hello,value 為 world 的命令”,

  • 4、隨后此提案通過 Raft HTTP 網路模塊轉發、經過集群多數節點持久化后,狀 態會變成已提交;

  • 5、etcdserver 從 Raft 模塊獲取已提交的日志條目,傳遞給 Apply 模塊

  • 6、Apply 模塊通過 MVCC 模塊執行提案內容,更新狀態機,

與讀流程不一樣的是,寫流程還涉及 Quota、WAL、Apply 三個模塊,etcd 的 crash-safe 及冪等性也正是基于 WAL 和 Apply 流程的 consistent index 等實作的,

2、詳細步驟解讀

2.1、Quota 模塊

流程二

Quota 模塊主要用于檢查下當前 etcd db 大小加上你請求的 key-value 大小之和是否超過 了配額(quota-backend-bytes), 如果超過了配額,它會產生一個告警(Alarm)請求,告警型別是 NO SPACE,并通過 Raft 日志同步給其它節點,告知 db 無空間了,并將告警持久化存盤到 db 中,最終,無論 是 API 層 gRPC 模塊還是負責將 Raft 側已提交的日志條目應用到狀態機的 Apply 模塊, 都拒絕寫入,集群只讀

常見的 etcdserver: mvcc: database space exceeded 錯誤就是因為Quota 模塊檢測到 db 大小超限導致的,哪些情況會觸發這個錯誤:

  • 一方面默認 db 配額僅為 2G,當你的業務資料、寫入 QPS、Kubernetes 集群規模增大后,你的 etcd db 大小就可能會超過 2G,

  • 另一方面 etcd 是個 MVCC 資料庫,保存了 key 的歷史版本,當你未配置壓縮策略的時候,隨著資料不斷寫入,db 大小會不斷增大,導致超限,

解決辦法:

1、首先當然是調大配額,etcd 社區建議不超過 8G,

如果填的是個小于 0 的數,就會禁用配額功能,這可能會讓db 大小處于失控,導致性能下降,不建議你禁用配額,

2、檢查 etcd 的壓縮(compact)配置是否開啟、配置是否合理,

壓縮時只會給舊版本Key打上空閑(Free)標記,后續新的資料寫入的時候可復用這塊空間,db大小并不會減小,

如果需要回收空間,減少 db 大小,得使用碎片整理 (defrag), 它會遍歷舊的 db 檔案資料,寫入到一個新的 db 文 件,但是它對服務性能有較大影響,不建議你在生產集群頻繁使 用,

調整后還需要手動發送一個取消告警(etcdctl alarm disarm)的命令,以消除所有告警, 否則因為告警的存在,集群還是無法寫入,

這個注意別忘記了!!!

查看狀態
etcdctl --endpoints=192.168.91.68:2379,192.168.91.68:12379,192.168.91.68:22379 endpoint status -w table

壓縮
etcdctl --endpoints=192.168.91.68:2379,192.168.91.68:12379,192.168.91.68:22379 compact 1

碎片整理
etcdctl --endpoints=192.168.91.68:2379,192.168.91.68:12379,192.168.91.68:22379 defrag


etcdctl alarm disarm

2.2、KVServer 模塊

流程3

通過流程二的配額檢查后,請求就從 API 層轉發到了流程三的 KVServer 模塊的 put 方 法

KVServer 模塊主要功能為:
1、打包提案: 將 put 寫請求內容打包成一個提案訊息,提交給 Raft 模塊

2、請求限速、檢查: 不過在提交提案前,還有限速、鑒權和大包檢查

2.2.1、Preflight Check

為了保證集群穩定性,避免雪崩,任何提交到 Raft 模塊的請求,都會做一些簡單的限速判斷,

限速

  • 如果 Raft 模塊已提交的日志索引(committed index)已應用到狀態機的日志索引 (applied index)超過了 5000,那么它就回傳一個etcdserver: too many requests錯誤給 client,

鑒權

  • 然后它會嘗試去獲取請求中的鑒權資訊,若使用了密碼鑒權、請求中攜帶了 token,如果 token 無效,則回傳auth: invalid auth token 錯誤給 client,

大包檢查

  • 其次它會檢查你寫入的包大小是否超過默認的 1.5MB, 如果超過了會回傳etcdserver: request is too large錯誤給 client,

2.3、Propose

流程4

通過檢查后會生成一個唯一的 ID,將此請求關聯到一個對應的訊息通知 channel(用于接收結果),然后向 Raft 模塊發起(Propose)一個提案(Proposal), Raft 模塊發起提案后,KVServer 模塊會等待此 put 請求,等待寫入結果通過訊息通知 channel 回傳或者超時,

etcd 默認超時時間是 7 秒(5 秒磁盤 IO 延時 +2*1 秒競選超時 時間),如果一個請求超時未回傳結果,則可能會出現你熟悉的etcdserver: request timed out 錯誤,

2.4 WAL 模塊

流程5

Raft 模塊收到提案后,如果當前節點是 Follower,它會轉發給 Leader,只有 Leader 才能 處理寫請求

Leader 收到提案后,通過 Raft 模塊輸出待轉發給 Follower 節點的訊息和待持久化的日志 條目,日志條目則封裝了我們上面所說的 put hello 提案內容,

etcdserver 從 Raft 模塊獲取到以上訊息和日志條目后,作為 Leader,它會將 put 提案消 息廣播給集群各個節點,同時需要把集群 Leader 任期號、投票資訊、已提交索引、提案內 容持久化到一個 WAL(Write Ahead Log)日志檔案中,用于保證集群的一致性、可恢復 性,也就是我們圖中的流程五模塊,

2.4.1、WAL 日志結構

WAL 日志結構如下:

WAL 檔案它由多種型別的 WAL 記錄順序追加寫入組成,每個記錄由型別、資料、回圈冗 余校驗碼組成不同型別的記錄通過 Type 欄位區分,Data 為對應記錄內容,CRC 為回圈 校驗碼資訊

WAL 記錄型別目前支持 5 種,分別是檔案元資料記錄、日志條目記錄、狀態資訊記錄、 CRC 記錄、快照記錄:

  • 檔案元資料記錄:包含節點 ID、集群 ID 資訊,它在 WAL 檔案創建的時候 寫入;

  • 日志條目記錄:包含 Raft 日志資訊,如 put 提案內容;

  • 狀態資訊記錄:包含集群的任期號、節點投票資訊等,一個日志檔案中會有 多條,以最后的記錄為準;

  • CRC 記錄:包含上一個 WAL 檔案的最后的 CRC(回圈冗余校驗碼)資訊, 在創建、切割 WAL 檔案時,作為第一條記錄寫入到新的 WAL 檔案, 用于校驗資料 檔案的完整性、準確性等;

  • 快照記錄:包含快照的任期號、日志索引資訊,用于檢查快照檔案的準確性,

2.4.2、WAL 持久化

首先會將 put 請求封裝成一個 Raft 日志條目,Raft 日志條目的資料結構資訊如下:

type Entry struct {
   Term             uint64    `protobuf:"varint,2,opt,name=Term" json:"Term"`
   Index            uint64    `protobuf:"varint,3,opt,name=Index" json:"Index"`
   Type             EntryType `protobuf:"varint,1,opt,name=Type,enum=Raftpb.EntryType" json:"Type"`
   Data             []byte    `protobuf:"bytes,4,opt,name=Data" json:"Data,omitempty"`
}

它由以下欄位組成:

  • Term 是 Leader 任期號,隨著 Leader 選舉增加;
  • Index 是日志條目的索引,單調遞增增加;
  • Type 是日志型別,比如是普通的命令日志(EntryNormal),還是集群配置變更日志(EntryConfChange);
  • Data 保存我們上面描述的 put 提案內容,

具體持久化程序如下:
1、它首先先將 Raft 日志條目內容(含任期號、索引、提案內容)序列化后保存到 WAL 記錄的 Data 欄位, 然后計算 Data 的 CRC 值,設定 Type 為 Entry Type, 以上資訊就組成了一個完整的 WAL 記錄,

2、最后計算 WAL 記錄的長度,順序先寫入 WAL 長度(Len Field),然后寫 入記錄內容,呼叫 fsync 持久化到磁盤,完成將日志條目保存到持久化存盤中,

3、當一半以上節點持久化此日志條目后, Raft 模塊就會通過 channel 告知 etcdserver 模塊,put 提案已經被集群多數節點確認,提案狀態為已提交,你可以執 行此提案內容了,

4、于是進入流程六,etcdserver 模塊從 channel 取出提案內容,添加到先進 先出(FIFO)調度佇列,隨后通過 Apply 模塊按入隊順序,異步、依次執行提案內 容,

2.5、Apply 模塊

流程 7

Apply 模塊主要用于執行處于 已提交狀態的提案,將其更新到狀態機

Apply 模塊在執行提案內容前,首先會判斷當前提案是否已經執行過了,如果執行了則直 接回傳,若未執行同時無 db 配額滿告警,則進入到 MVCC 模塊,開始與持久化存盤模塊 打交道,

如果執行程序中 crash,重啟后如何找回例外提案,再次執行的呢?

主要依賴 WAL 日志,因為提交給 Apply 模塊執行的提案已獲得多數節點確認、持久化, etcd 重啟時,會從 WAL 中決議出 Raft 日志條目內容,追加到 Raft 日志的存盤中,并重 放已提交的日志提案給 Apply 模塊執行,

重啟恢復時,如何確保冪等性,防止提案重復執行導致資料混亂呢?

etcd 通過引入一個 consistent index 的欄位,來存盤系統當前已經執行過的日志條目索 引,實作冪等性,

因為 Raft 日志條目中的索引(index)欄位,而且是全域單調遞增的,每個日志條目索引 對應一個提案, 如果一個命令執行后,我們在 db 里面也記錄下當前已經執行過的日志條 目索引,就可以解決冪等性問題了,當然還需要將執行命令和記錄index這兩個操作作為原子性事務提交,才能實作冪等

2.6、MVCC 模塊

流程 8 和 9

MVCC 主要由兩部分組成,一個是記憶體索引模塊 treeIndex,保存 key 的歷史版本號信 息,另一個是 boltdb 模塊,用來持久化存盤 key-value 資料

MVCC 模塊執行 put hello 為 world 命令時,它是如何構建記憶體索引和保存哪些資料到 db呢?

2.6.1、treeIndex

MVCC 寫事務在執行 put hello 為 world 的請求時,會基于 currentRevision 自增生成新 的 revision, 如{2,0},然后從 treeIndex 模塊中查詢 key 的創建版本號、修改次數資訊,這 些資訊將填充到 boltdb 的 value 中,同時將用戶的 hello key 和 revision 等資訊存盤到 B-tree,也就是下面簡易寫事務圖的流程一,整體架構圖中的流程八,

hello: revision{2,0}

這里的 2,0 具體指的是什么呢?

這里不太懂,有清楚的朋友,請不吝賜教,

2.6.2、boltdb

MVCC 寫事務自增全域版本號后生成的 revision{2,0},它就是 boltdb 的 key,通過它就 可以往 boltdb 寫資料了,進入了整體架構圖中的流程九,

那么寫入 boltdb 的 value 含有哪些資訊呢?

寫入 boltdb 的 value, 并不是簡單的"world",如果只存一個用戶 value,索引又是保存 在易失的記憶體上,那重啟 etcd 后,我們就丟失了用戶的 key 名,無法構建 treeIndex 模塊 了,

因此為了構建索引和支持 Lease(租約) 等特性,etcd 會持久化以下資訊:

  • key 名稱;

  • key 創建時的版本號(create_revision)、最后一次修改時的版本號 (mod_revision)、key 自身修改的次數(version);

  • value 值;

  • 租約資訊,

boltdb value 的值就是將含以上資訊的結構體序列化成的二進制資料,然后通過 boltdb 提供的 put 介面,etcd 就快速完成了將你的資料寫入 boltdb,

注意: 在以上流程中,etcd 并未提交事務(commit),因此資料只更新在 boltdb 所管理 的記憶體資料結構中,

事務提交的程序,包含 B+tree 的平衡、分裂,將 boltdb 的臟資料(dirty page)、元數 據資訊重繪到磁盤,因此事務提交的開銷是昂貴的,

如果我們每次更新都提交事務,etcd寫性能就會較差,

etcd 的解決方案是合并再合并:

  • 首先 boltdb key 是版本號,put/delete 操作時,都會基于當前版本號遞增生成新的版本 號,因此屬于順序寫入,可以調整 boltdb 的 bucket.FillPercent 引數,使每個 page 填充 更多資料,減少 page 的分裂次數并降低 db 空間,
  • 其次 etcd 通過合并多個寫事務請求,通常情況下,是異步機制定時(默認每隔 100ms) 將批量事務一次性提交(pending 事務過多才會觸發同步提交), 從而大大提高吞吐量,但是這優化又引發了另外的一個問題, 因為事務未提交,讀請求可能無法從 boltdb 獲取 到最新資料
  • 為了解決這個問題,etcd 引入了一個 bucket buffer 來保存暫未提交的事務資料,在更新 boltdb 的時候,etcd 也會同步資料到 bucket buffer,因此 etcd 處理讀請求的時候會優 先從 bucket buffer 里面讀取,其次再從 boltdb 讀,通過 bucket buffer 實作讀寫性能提 升,同時保證資料一致性,

以上就是 etcd 寫請求執行的流程,自己還是有蠻多地方不太懂,常看常新吧,

學習鏈接

b站-etcd寫請求執行流程-圖靈教程

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/556897.html

標籤:NoSQL

上一篇:華為云河圖KooMap:夯實數字孿生底座,點燃燎原星火

下一篇:返回列表

標籤雲
其他(162293) Python(38272) JavaScript(25528) Java(18293) C(15239) 區塊鏈(8275) C#(7972) AI(7469) 爪哇(7425) MySQL(7292) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5876) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4615) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2438) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) HtmlCss(1994) .NET技术(1986) 功能(1967) Web開發(1951) C++(1942) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1882) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • 06、etcd 寫請求執行流程

    > 本篇內容主要來源于自己學習的視頻,如有侵權,請聯系洗掉,謝謝。 上一節我們學習了 etcd 讀請求執行流程,這一節,我們來學習 etcd 寫請求執行流程。 ### 1、etcd寫請求概覽 **etcd 一個寫請求執行流程又是怎樣的呢?** ``` sh etcdctl put hello wor ......

    uj5u.com 2023-07-10 08:13:01 more
  • 華為云河圖KooMap:夯實數字孿生底座,點燃燎原星火

    摘要:7月8日,華為開發者大會2023(Cloud)華為云河圖KooMap技術分論壇在東莞溪村順利舉辦。 7月8日,華為開發者大會2023(Cloud)華為云河圖KooMap技術分論壇在東莞溪村順利舉辦。本次分論壇以“夯實數字孿生底座,點燃燎原星火”為主題,邀請了來自華為的技術專家和產學研領域的行業 ......

    uj5u.com 2023-07-10 08:11:45 more
  • 選讀SQL經典實體筆記03_DML和元資料

    ![](https://img2023.cnblogs.com/blog/3076680/202307/3076680-20230706135746797-1984903730.png) # 1. 復制資料到另一個表 ## 1.1. sql ```sql insert into dept_east ......

    uj5u.com 2023-07-09 08:00:22 more
  • 資料庫系統概論—恢復與并發

    # 資料庫概論系統—系統篇 ## 一、關系查詢處理和查詢優化 ### 1.1關系資料庫的查詢處理 查詢處理可分為四個階段:查詢分析、檢查檢查、查詢優選和查詢執行(其中查詢優化可分為代數和物理優化) ### 1.2關系資料庫系統的查詢優化 查詢優化的優點不僅在于用戶不必考慮如何最好地表達查詢以獲得較高 ......

    uj5u.com 2023-07-09 08:00:05 more
  • 選讀SQL經典實體筆記03_DML和元資料

    ![](https://img2023.cnblogs.com/blog/3076680/202307/3076680-20230706135746797-1984903730.png) # 1. 復制資料到另一個表 ## 1.1. sql ```sql insert into dept_east ......

    uj5u.com 2023-07-09 07:58:54 more
  • 資料庫系統概論—恢復與并發

    # 資料庫概論系統—系統篇 ## 一、關系查詢處理和查詢優化 ### 1.1關系資料庫的查詢處理 查詢處理可分為四個階段:查詢分析、檢查檢查、查詢優選和查詢執行(其中查詢優化可分為代數和物理優化) ### 1.2關系資料庫系統的查詢優化 查詢優化的優點不僅在于用戶不必考慮如何最好地表達查詢以獲得較高 ......

    uj5u.com 2023-07-09 07:57:08 more
  • 選讀SQL經典實體筆記02_多表查詢

    ![](https://img2023.cnblogs.com/blog/3076680/202307/3076680-20230706135034978-826621908.png) # 1. 除非有必要,否則不要用UNION代替UNION ALL # 2. 查找兩個表中相同的行 ## 2.1.  ......

    uj5u.com 2023-07-08 08:13:51 more
  • 社區星力量 | 平等、包容、耐性,這對貢獻小白來說很重要

    ![file](https://img2023.cnblogs.com/other/2685289/202307/2685289-20230707145108418-723743542.png) 截至今天,Apache DolphinScheduler 專案在 GitHub 上的 Star 數已突破 ......

    uj5u.com 2023-07-08 08:13:37 more
  • 選讀SQL經典實體筆記02_多表查詢

    ![](https://img2023.cnblogs.com/blog/3076680/202307/3076680-20230706135034978-826621908.png) # 1. 除非有必要,否則不要用UNION代替UNION ALL # 2. 查找兩個表中相同的行 ## 2.1.  ......

    uj5u.com 2023-07-08 08:12:36 more
  • 社區星力量 | 平等、包容、耐性,這對貢獻小白來說很重要

    ![file](https://img2023.cnblogs.com/other/2685289/202307/2685289-20230707145108418-723743542.png) 截至今天,Apache DolphinScheduler 專案在 GitHub 上的 Star 數已突破 ......

    uj5u.com 2023-07-08 08:12:13 more