日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

etcd 笔记(07)— 键值对读写操作过程

發(fā)布時(shí)間:2023/11/28 生活经验 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 etcd 笔记(07)— 键值对读写操作过程 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. 讀寫總體概述

etcd 各個(gè)模塊交互的總覽,如下圖所示:

總體上的請求流程從上至下依次為客戶端 → API 接口層 → etcd Serveretcd raft 算法庫。

  • 讀請求

客戶端通過負(fù)載均衡選擇一個(gè) etcd 節(jié)點(diǎn)發(fā)出讀請求,API 接口層提供了 Range RPC 方法,etcd 服務(wù)端攔截到 gRPC 讀請求后,調(diào)用相應(yīng)的處理器處理請求。

  • 寫請求

客戶端通過負(fù)載均衡選擇一個(gè) etcd 節(jié)點(diǎn)發(fā)起寫請求,etcd 服務(wù)端攔截到 gRPC 寫請求,涉及一些校驗(yàn)和監(jiān)控,之后 KVServerraft 模塊發(fā)起提案,內(nèi)容即為寫入數(shù)據(jù)的命令。經(jīng)過網(wǎng)絡(luò)轉(zhuǎn)發(fā),當(dāng)集群中的多數(shù)節(jié)點(diǎn)達(dá)成一致并持久化數(shù)據(jù)后,狀態(tài)變更且 MVCC 模塊執(zhí)行提案內(nèi)容。

2. 讀操作整體流程

將整個(gè)讀操作劃分成如下幾個(gè)步驟:

  • etcdctl 會創(chuàng)建一個(gè) clientv3 庫對象,選取一個(gè)合適的 etcd 節(jié)點(diǎn);

  • 調(diào)用 KVServer 模塊的 Range RPC 方法,發(fā)送請求;

  • 攔截器攔截,主要做一些校驗(yàn)和監(jiān)控;

  • 調(diào)用 KVServer 模塊的 Range 接口獲取數(shù)據(jù);

接著就進(jìn)入了讀請求的核心步驟,會經(jīng)過線性讀 ReadIndex 模塊、MVCC(包含 treeIndexBlotDB)模塊。

線性讀是相對串行讀來講的概念。集群模式下會有多個(gè) etcd 節(jié)點(diǎn),不同節(jié)點(diǎn)之間可能存在一致性問題,串行讀直接返回狀態(tài)數(shù)據(jù),不需要與集群中其他節(jié)點(diǎn)交互。這種方式速度快,開銷小,但是會存在數(shù)據(jù)不一致的情況。

線性讀則需要集群成員之間達(dá)成共識,存在開銷,響應(yīng)速度相對慢。但是能夠保證數(shù)據(jù)的一致性,etcd 默認(rèn)讀模式是線性讀。

繼續(xù)往下,看看如何讀取 etcd 中的數(shù)據(jù)。etcd 中查詢請求,查詢單個(gè)鍵或者一組鍵,以及查詢數(shù)量,到了底層實(shí)際都會調(diào)用 Range keys 方法。

Range 請求的結(jié)構(gòu)圖如下所示:

從上至下,查詢鍵值對的流程包括:

  • treeIndex 中根據(jù)鍵利用 BTree 快速查詢該鍵對應(yīng)的索引項(xiàng) keyIndex,索引項(xiàng)中包含 Revision

  • 根據(jù)查詢到的版本號信息 Revision,在 Backend 的緩存 Buffer 中利用二分法查找,如果命中則直接返回;

  • 若緩存中不符合條件,在 BlotDB 中查找(基于 BlotDB 的索引),查詢之后返回鍵值對信息。

圖中 ReadTxBatchTx 是兩個(gè)接口,用于讀寫請求。在創(chuàng)建 Backend 結(jié)構(gòu)體時(shí),默認(rèn)也會創(chuàng)建 readTxbatchTxreadTx 實(shí)現(xiàn)了 ReadTx ,負(fù)責(zé)處理只讀請求;batchTx 實(shí)現(xiàn)了 BatchTx 接口,負(fù)責(zé)處理讀寫請求。

總結(jié)客戶端發(fā)起讀請求之后的處理流程,如下圖所示:

  • 客戶端發(fā)起請求之后,clientv3 首先會根據(jù)負(fù)載均衡算法選擇一個(gè)合適的 etcd 節(jié)點(diǎn),接著調(diào)用 KVServer 模塊對應(yīng)的 RPC 接口,發(fā)起 Range 請求的 gRPC 遠(yuǎn)程調(diào)用;

  • gRPC Server 上注冊的攔截器攔截到 Range 請求,實(shí)現(xiàn) Metrics 統(tǒng)計(jì)、日志記錄等功能;

  • 然后進(jìn)入讀的主要過程,etcd 模式實(shí)現(xiàn)了線性讀,使得任何客戶端通過線性讀都能及時(shí)訪問到鍵值對的更新;

  • 線性讀獲取到 Leader 已提交日志索引構(gòu)造的最新 ReadState 對象,實(shí)現(xiàn)本節(jié)點(diǎn)狀態(tài)機(jī)的同步;

  • 接著就是調(diào)用 MVCC 模塊,根據(jù) treeIndex 模塊 B-tree 快速查找 key 對應(yīng)的版本號;

  • 通過獲取的版本號作為 key,查詢存儲在 boltdb 中的鍵值對;

3. 寫操作整體流程

將整個(gè)寫操作劃分成如下幾個(gè)步驟:

  • 客戶端通過負(fù)載均衡算法選擇一個(gè) etcd 節(jié)點(diǎn),發(fā)起 gRPC 調(diào)用;

  • etcd Server 收到客戶端請求;

  • 經(jīng)過 gRPC 攔截、Quota 校驗(yàn),Quota 模塊用于校驗(yàn) etcd db 文件大小是否超過了配額;

  • 接著 KVServer 模塊將請求發(fā)送給本模塊中的 raft,這里負(fù)責(zé)與 etcd raft 模塊進(jìn)行通信,發(fā)起一個(gè)提案,命令為 put foo bar,即使用 put 方法將 foo 更新為 bar

  • 提案經(jīng)過轉(zhuǎn)發(fā)之后,半數(shù)節(jié)點(diǎn)成功持久化;

  • MVCC 模塊更新狀態(tài)機(jī);

put 接口的執(zhí)行過程:

調(diào)用 putetcd 寫入數(shù)據(jù)時(shí),首先會使用傳入的鍵構(gòu)建 keyIndex 結(jié)構(gòu)體,基于 currentRevision 自增生成新的 Revision{1,0} ,并從 treeIndex 中獲取相關(guān)版本 Revision 等信息;寫事務(wù)提交之后,將本次寫操作的緩存 buffer 合并(merge)到讀緩存上(圖中 ReadTx 中的緩存)。

revision{1,0} 是生成的全局版本號,作為 BoltDBkey,經(jīng)過序列化包括 key 名稱、key 創(chuàng)建時(shí)的版本號(create_revision)、value 值和租約等信息為二進(jìn)制數(shù)據(jù)之后,將填充到 BoltDBvalue 中,同時(shí)將該鍵和 Revision 等信息存儲到 Btree

根據(jù) etcd 讀寫流程圖,可以知道讀寫操作依賴 MVCC 模塊的 treeIndexBoltDBtreeIndex 用來保存鍵的歷史版本號信息,而 BoltDB 用來保存 etcd 的鍵值對數(shù)據(jù)。通過這兩個(gè)模塊之間的協(xié)作,實(shí)現(xiàn)了 etcd 數(shù)據(jù)的讀取和存儲。

寫請求的處理流程,如下圖所示:

  • 客戶端發(fā)送寫請求,通過負(fù)載均衡算法選取合適的 etcd 節(jié)點(diǎn),發(fā)起 gRPC 調(diào)用。
  • etcd server 的 gRPC Server 收到這個(gè)請求,經(jīng)過 gRPC 攔截器攔截,實(shí)現(xiàn) Metrics 統(tǒng)計(jì)和日志記錄等功能。
  • Quota 模塊配額檢查 db 的大小,如果超過會報(bào)etcdserver: mvcc: database space exceeded的告警,通過 Raft 日志同步給集群中的節(jié)點(diǎn) db 空間不足,同時(shí)告警也會持久化到 db 中。etcd 服務(wù)端拒絕寫入,對外提供只讀的功能。
  • 配額檢查通過,KVServer 模塊經(jīng)過限速、鑒權(quán)、包大小判斷之后,生成唯一的編號,這時(shí)才會將寫請求封裝為提案消息,提交給 Raft 模塊。
  • 寫請求的提案只能由 Leader 處理,獲取到 Raft 模塊的日志條目之后,Leader 會廣播提案內(nèi)容。WAL 模塊完成 Raft 日志條目內(nèi)容封裝,當(dāng)集群大多數(shù)節(jié)點(diǎn)完成日志條目的持久化,即將提案的狀態(tài)變更為已提交,可以執(zhí)行提案內(nèi)容。
  • Apply 模塊用于執(zhí)行提案,首先會判斷該提案是否被執(zhí)行過,如果已經(jīng)執(zhí)行,則直接返回結(jié)束;未執(zhí)行過的情況下,將會進(jìn)入 MVCC 模塊執(zhí)行持久化提案內(nèi)容的操作。
  • MVCC 模塊中的 treeIndex 保存了 key 的歷史版本號信息,treeIndex 使用 B-tree 結(jié)構(gòu)維護(hù)了 key 對應(yīng)的版本信息,包含了全局版本號、修改次數(shù)等屬性。版本號代表著 etcd 中的邏輯時(shí)鐘,啟動(dòng)時(shí)默認(rèn)的版本號為 1。鍵值對的修改、寫入和刪除都會使得版本號全局單調(diào)遞增。寫事務(wù)在執(zhí)行時(shí),首先根據(jù)寫入的 key 獲取或者更新索引,如果不存在該 key,則會給予當(dāng)前最大的 currentRevision 自增得到 revision;否則直接根據(jù) key 獲取 revision。
  • 根據(jù)從 treeIndex 中獲取到 revision 、修改次數(shù)等屬性,以及 put 請求傳遞的 key-value 信息,作為寫入到 boltdb 的 value,而將 revision 作為寫入到 boltdb 的 key。同時(shí)為了讀請求能夠獲取最新的數(shù)據(jù),etcd 在寫入 boltdb 時(shí)也會同步數(shù)據(jù)到 buffer。因此上文介紹 etcd 讀請求的過程時(shí),會優(yōu)先從 buffer 中讀取,讀取不到的情況下才會從 boltdb 讀取,以此來保證一致性和性能。為了提高吞吐量,此時(shí)提案數(shù)據(jù)并未提交保存到 db 文件,而是由 backend 異步 goroutine 定時(shí)將批量事務(wù)提交。
  • Server 通過調(diào)用網(wǎng)絡(luò)層接口返回結(jié)果給客戶端。

總的來說,這個(gè)過程為客戶端發(fā)起寫請求,由 Leader 節(jié)點(diǎn)處理,經(jīng)過攔截器、Quota 配額檢查之后,KVServer 提交一個(gè)寫請求的提案給 Raft 一致性模塊,經(jīng)過 RaftHTTP 網(wǎng)絡(luò)轉(zhuǎn)發(fā),集群中的其他節(jié)點(diǎn)半數(shù)以上持久化成功日志條目,提案的狀態(tài)將會變成已提交。接著 Apply 通過 MVCC 的 treeIndex、boltdb 執(zhí)行提案內(nèi)容,成功之后更新狀態(tài)機(jī)。

原文:
https://kaiwu.lagou.com/course/courseInfo.htm?courseId=613#/detail/pc?id=6411

總結(jié)

以上是生活随笔為你收集整理的etcd 笔记(07)— 键值对读写操作过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。