05、etcd 讀請求執行流程

来源:https://www.cnblogs.com/huageyiyangdewo/archive/2023/07/06/17530678.html
-Advertisement-
Play Games

> 本篇內容主要來源於自己學習的視頻,如有侵權,請聯繫刪除,謝謝。 ### 1、etcd讀請求概覽 etcd是典型的`讀多寫少`存儲,在我們實際業務場景中,讀一般占據2/3以上的請求。一個讀 請求從client通過`Round-robin(輪詢)`負載均衡演算法,選擇一個etcd server節點,發 ...


本篇內容主要來源於自己學習的視頻,如有侵權,請聯繫刪除,謝謝。

1、etcd讀請求概覽

etcd是典型的讀多寫少存儲,在我們實際業務場景中,讀一般占據2/3以上的請求。一個讀 請求從client通過Round-robin(輪詢)負載均衡演算法,選擇一個etcd server節點,發出 gRPC請 求,經過etcd server的 KVServer模塊、線性讀模塊、MVCC的treelndex和 boltdb模塊緊 密協作,完成了一個讀請求。

思考:通過etcdctl執行如下命令etcd是如何工作的?

etcdctl get hello ‐‐endpoints 192.168.65.210:2379,192.168.65.211:2379,19 2.168.65.212:2379

2、詳細步驟解讀

2.1 Client 層

主要是對應到步驟 1

1、首先,etcdctl 會對命令中的參數進行解析。

  • get 是請求的方法,它是 KVServer 模塊的 提供的API;
  • hello是 我們查詢的 key 名;
  • endpoints 是我們後端的 etcd 地址。通常,生產環境下中需要配置多個endpoints,這樣在 etcd 節點出現故障後,client 就可以自動重連到其它正常的節點,從而保證請求的正常執行。

2、在解析完請求中的參數後,etcdctl 會創建一個 clientv3 庫對象,使用 KVServer 模塊 的 API 來訪問 etcd server。
etcd clientv3 庫採用的負載均衡演算法為 Round-robin。針對每一個請求,Round-robin 演算法通過輪詢的方式依次從 endpoint 列表中選擇一個 endpoint 訪問 (長連接),使 etcd server 負載儘量均衡。

2.2 KVServer 與 攔截器

主要是對應到步驟 2

client 發送 Range RPC 請求到了 server 後就進入了 KVServer 模塊。
etcd 通過攔截器以非侵入式的方式實現了許多特性,例如:豐富的 metrics、日誌、請求行為檢查、所有請求的執行耗時及錯誤碼、來源IP 等。攔截器提供了在執行一個請求前後 的 hook 能力,除了 debug 日誌、metrics 統計、對 etcd Learner 節點請求介面和參數限制等能力,etcd 還基於它實現了以下特性:

  • 要求執行一個操作前集群必須有 Leader;

  • 請求延時超過指定閾值的,列印包含來源 IP 的慢查詢日誌 (3.5 版本)。

server 收到 client 的 Range RPC 請求後,根據 ServiceName 和 RPC Method 將請求轉 發到對應的 handler 實現,handler 首先會將上面描述的一系列攔截器串聯成一個攔截器再執行,在攔截器邏輯中,通過調用 KVServer 模塊的 Range 介面獲取數據。

2.3 串列讀與線性讀

流程三和四.

etcd 為了保證服務高可用,生產環境一般部署多個節點,多節點之間的數據由於延遲等關係可能會存在不一致的情況。

當 client 發起一個寫請求後分為以下幾個步驟:

1、Leader 收到寫請求,它會將此請求持久化到 WAL 日誌,並廣播給各個節點;

只有 Leader 節點能處理寫請求。

2、若一半以上節點持久化成功,則該請求對應的日誌條目被標識為已提交;

3、etcdserver 模塊非同步從 Raft 模塊獲取已提交的日誌條目,應用到狀態機 (boltdb 等)。

此時若client 發起一個讀取 hello 的請求,假設此請求直接從狀態機中讀取,如果連接到的是C節點,若C節點磁碟I/O出現波動,可能導致它應用已提交的日誌條目很慢,則會出現更新 hello 為 world 的寫命令,在client讀 hello 的時候還未被提交到狀態機,因此就可能讀取到舊數據,如上圖查詢hello流程所示。

所以在多節點etcd集群中,各個節點的狀態機數據一致性存在差異。而我們不同業務場景 的讀請求對數據是否最新的容忍度是不一樣的,有的場景它可以容忍數據落後幾秒甚至幾分 鐘,有的場景要求必須讀到反映集群共識的最新數據。根據業務場景對數據一致性差異的接受程度。

**etcd 中有兩種讀模式: **

1、串列 (Serializable) 讀:

直接讀狀態機數據返回、無需通過 Raft 協議與集群進行交互, 它具有低延時、高吞吐量的特點,適合對數據一致性要求不高的場景。

2、線性讀:

etcd 預設讀模式是線性讀,需要經過 Raft 協議模塊,反應的是集群共識,因 此在延時和吞吐量上相比串列讀略差一點,適用於對數據一致性要求高的場景。

對數據敏感度較低的場景:

  • 直接讀狀態機數據返回、無需通過 Raft 協議與集群進行交互的模式,在 etcd 里叫做串列 (Serializable) 讀,它具有低延時、高吞吐量的特點,適合對數據一致性要求不高的場景。

對數據敏感性高的場景:

  • 在 etcd 裡面,提供了一種線性讀模式來解決對數據一致性要求高的場景。

什麼是線性讀呢?

你可以理解一旦一個值更新成功,隨後任何通過線性讀的 client 都能及時訪問到。雖然集群中有多個節點,但 client 通過線性讀就如訪問一個節點一樣。etcd 預設讀模式是線性讀,因為它需要經過 Raft 協議模塊,反應的是集群共識,因此在延時和吞吐量上相比串列讀略差一點,適用於對數據一致性要求高的場景。

2.4 ReadIndex

在 etcd 3.1 引入了 ReadIndex 機制,保證在串列讀的時候,也能讀到最新的數據。

接下來看看線性讀的執行流程

具體流程如下:

  • 當收到一個線性讀請求時,它首先會從Leader獲取集群最新的已提交的日誌索引(committed index),如上圖中的流程二所示。

  • Leader收到ReadIndex請求時,為防止腦裂等異常場景,會向Follower節點發送心跳確認,一半以上節點確認Leader身份後才能將已提交的索引(committed index)返回給節點C(上圖中的流程三)。

  • 節點則會等待,直到狀態機已應用索引 (applied index)大於等於Leader的已提交索引時(committed Index)(上圖中的流程四),然後去通知讀請求,數據已趕上 Leader,你可以去狀態機中訪問數據了(上圖中的流程五)。

以上就是線性讀通過ReadIndex機制保證數據一致性原理,當然還有其它機制也能實現線性讀,如在早期etcd 3.0中讀請求通過走一遍Raft 協議保證一致性,這種Raft log read機制 依賴磁碟IO,性能相比 ReadIndex較差。

總體而言,KVServer模塊收到線性讀請求後,通過架構圖中流程三向Raft模塊發起 ReadIndex請求,Raft模塊將Leader最新的已提交日誌索引封裝在流程四的ReadState結構體,通過channel層層返回給線性讀模塊,線性讀模塊等待本節點狀態機追趕上Leader進度,追趕完成後,就通知KVServer模塊,進行架構圖中流程五,與狀態機中的 MVCC模塊進行進行交互了。

2.5 MVCC

流程五中的多版本併發控制(Multiversion concurrency control)模塊為瞭解決etcd v2不支持保存key的歷史版本、不支持多key事務等問題而產生的。它核心由記憶體樹形索引模塊 (treelndex)和嵌入式的KV持久化存儲庫 boltdb 組成。boltdb是個基於B+ tree實現的 key-value鍵值庫,支持事務,提供Get/Put等簡易API給etcd操作。

etcd MVCC 具體方案如下:

  • 每次修改操作,生成一個新的版本號 (revision),以版本號為 key, value 為用戶 key-value 等信息組成的結構體存儲到 blotdb。
  • 讀取時·先從 treeIndex 中獲取 key 的版本號·,再以版本號作為 boltdb 的 key,從 boltdb 中獲取其 value 信息。

2.6 treelndex

treelndex模塊是基於Google開源的記憶體版btree 庫實現的,treeIndex模塊只會保存用戶的key和相關版本號信息,用戶 key 的value數據存儲在boltdb裡面,相比ZooKeeper和 etcd v2全記憶體存儲,etcd v3對記憶體要求更低。

簡單介紹了etcd如何保存 key的歷史版本後,架構圖中流程六也就非常容易理解了,它需要從treelndex模塊中獲取 hello這個 key對應的版本號信息。treeIndex模塊基於 B-tree快速查找此 key,返回此 key對應的索引項keyIndex即可。索引項中包含版本號等信息。

2.7 buffer

在獲取到版本號信息後,就可從boltdb模塊中獲取用戶的key-value數據了。不過並不是所有請求都—定要從 boltdb 獲取數據。etcd出於數據一致性、性能等考慮,在訪問boltdb前,首先會從一個記憶體讀事務 buffer中,二分查找你要訪問key是否在 buffer裡面,若命中則直接返回。

2.8 boltdb

若buffer未命中,此時就真正需要向boltdb模塊查詢數據了,進入了流程七。 我們知道MySQL通過 table 實現不同數據邏輯隔離,那麼在boltdb是如何隔離集群元數據 與用戶數據的呢?答案是bucket

boltdb 里每個 bucket 類似對應 MySQL 一個表,用戶的 key 數據存放的 bucket 名字的是 key,etcd MVCC 元數據存放的 bucket 是 meta。

我猜測這裡的意思是每個key都當做一個 bucket,然後bucket的名字是 key。這裡是猜測的,待驗證,若有知道的朋友,請不吝賜教,十分感謝。

因boltdb使用B+ tree來組織用戶的key-value數據,獲取 bucket key對象後,通過boltdb 的游標Cursor可快速在B+ tree找到 key hello對應的value數據,返回給client。 到這裡,一個讀請求之路執行完成。

文章來源:

etcd讀請求執行流程-視頻教程


etcd教程(七)---讀請求執行流程分析


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 學習記錄,不喜勿噴 什麼是OkHttp 一般在Java平臺上,我們會使用Apache HttpClient作為Http客戶端,用於發送 HTTP 請求,並對響應進行處理。比如可以使用http客戶端與第三方服務(如SSO服務)進行集成,當然還可以爬取網上的數據等。OKHttp與HttpClient類似 ...
  • > 作者:小牛呼嚕嚕 | [https://xiaoniuhululu.com](https://xiaoniuhululu.com/) > 電腦內功、源碼解析、科技故事、項目實戰、面試八股等更多硬核文章,首發於公眾號「[小牛呼嚕嚕](https://www.xiaoniuhululu.com/i ...
  • BeanDefinition在Spring初始化階段保存Bean的元數據信息,包括Class名稱、Scope、構造方法參數、屬性值等信息,本文將介紹一下BeanDefinition介面、重要的實現類,以及在Spring中的使用示例。 # BeanDefinition介面 用於描述了一個Bean實例, ...
  • 遠程調用百度AI開放平臺的web服務,快速完成人臉識別 ### 歡迎訪問我的GitHub > 這裡分類和彙總了欣宸的全部原創(含配套源碼):[https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) ### ...
  • 個人認為百度地圖開放平臺確實很好用但就是C#的SN校驗會出現以下幾個問題 一、官方的示例代碼說的不清不楚 獲取SN函數的Uri應該使用不帶功能變數名稱的Uri 比如:最終請求地址為https://api.map.baidu.com/location/ip?ip=119.126.10.15&coor=gcj0 ...
  • ## 一:背景 ### 1. 講故事 前段時間有位朋友找到我,說他們的工業視覺軟體僵死了,讓我幫忙看下到底是什麼情況,哈哈,其實卡死的問題相對好定位,無非就是看主線程棧嘛,然後就是具體問題具體分析,當然難度大小就看運氣了。 前幾天看一篇文章說現在的 .NET程式員 不需要學習**WinDbg** , ...
  • 記憶體“泄露”是開發中常見的問題之一,它會導致應用程式占用越來越多的記憶體資源,最終可能導致系統性能下降甚至崩潰。軟體開發者需要瞭解在程式中出現記憶體泄露的情況,以避免軟體出現該的問題。 **什麼是記憶體“泄露”?** 記憶體泄露是申請了記憶體空間的變數一直在占用,無法釋放。比如申請了一塊記憶體空間,沒有回收一直 ...
  • # lvm邏輯捲 ## 前言 > raid磁碟陣列技術,提高硬碟的讀寫效率,以及數據的安全,raid的缺點在於: > 1.當你配置好了raid磁碟陣列組,容量的大小,已經是限定了,如果你存儲的業務非常多,磁碟容量不夠用的問題就會出現,你想要擴容磁碟的空間,就會非常麻煩。 > 2.不同的磁碟分區,相對 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...