這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Etcd團隊剛剛興奮地公布了etcd 3.x系列中的最新成員——etcd 3.2.0。這套新版本迎來了代理改進、強化後端並發性、分布式協調服務、更為輕的Go用戶端以及JWT身分識別驗證等新的功能與特性。
在今天的文章中,我們將展示etcd 3.2.0當中的幾項全新功能,同時以此為基礎展開討論。首先要提到的是多租戶機制:即新的命名空間客戶與能夠提供完全隔離密鑰空間的代理。在此之後則要聊聊規模伸縮——gRPC代理現在能夠每秒支援上百萬個事件。最後,為了更好地協調各類系統,本次新版本引入了新的並發RPC服務,且其中內建有分布式鎖及對應選項,可供任意gRPC客戶進行輕鬆訪問。
命名空間
對於共用同一套etcd叢集的應用程式,為了避免彼此之間的相互幹擾,其需要保有僅屬於自己的密鑰。雖然etcd的驗證機制能夠利用許可權對個別使用者的密鑰加以保護,但卻無法阻止各密鑰之間因使用同一名稱而引發潛在衝突。相反,應用程式通常會採用首碼參數,而後將此首碼添加到所有應用程式的密鑰名稱當中以實現密鑰的有效命名。然而需要強調的是,這種首碼的正確實現流程往往枯燥且極易出錯,因此etcd現在將客戶命名空間與代理命名空間皆作為現成的可複用組件向使用者交付。
各命名空間負責將etcd密鑰組織為各自完全獨立的密鑰空間。一個命名空間屬於一套包含全部密鑰且具備一條首碼的視圖。一條命名空間內密鑰名稱在由基礎etcd密鑰空間進行查看時包含該首碼,但在通過命名空間查看時則不包含首碼。同樣的,任意接入命名空間內etcd代理的etcd用戶端(可選擇將該代理偽裝為獨立叢集以避免暴露核心端點)則只能訪問該代理命名空間首碼之下的各條密鑰。舉例來說,在以下etcd拓撲圖當中,某一客戶通過代理“/app-A/”訪問etcd,而該代理會將指向密鑰“abc”的請求翻譯為“/app-A/abc”。同樣的,“app-B”只能通過“/app-B/abc”訪問其“abc”;其中命名空間“/app-A/”與“/app-B/”彼此相互隔離。
包含兩套命名空間代理的etcd拓撲樣本圖
命名空間在配置方面亦非常簡單易行。我們可以利用以下命令對上述樣本中的拓撲結構進行測試:
# start etcd
$ etcd &
launch namespace proxies for /app-A/ and /app-B/
$ etcd grpc-proxy start --endpoints=http://localhost:2379 \
--listen-addr=127.0.0.1:23790 \
--namespace=/app-A/ &
$ etcd grpc-proxy start --endpoints=http://localhost:2379 \
--listen-addr=127.0.0.1:23791 \
--namespace=/app-B/ &
# write to /app-A/ and /app-B/
$ ETCDCTL_API=3 etcdctl --endpoints=http://localhost:23790 put abc a
$ ETCDCTL_API=3 etcdctl --endpoints=http://localhost:23791 put abc z
confirm the different keys were written
$ ETCDCTL_API=3 etcdctl --endpoints=http://locahost:2379 --prefix /app
每秒百萬個事件
對於密鑰的任何更改都會觸發etcd向一切對其加以關注的監視程式進行事件廣播。對於一套大規模etcd部署體系,其中往往包含成千上萬個並發監視程式。遺憾的是,這些監視程式的存在本身亦會帶來對應成本。
數量過於龐大的監視程式往往會引發etcd超載。以表所示為一套小型etcd執行個體在面向大量監視程式進行單一共用密鑰持續更新時的超載現象。這裡的etcd伺服器為一台較為孱弱的n1-standard-1(1vCPU + 3.75 GB記憶體)機器,而用戶端則使用更為強大的n1-standard-32(32vCPU + 120 GB記憶體)機器,後者能夠實現每秒500次寫入並通過監視程式佔滿伺服器資源。這意味著繼續添加監視程式將最終導致寫入速率下降,事件發生率亦將因此低於理想水平。
指向單一密鑰之監視程式過多時引發的etcd伺服器超載
etcd的gRPC代理能夠將來自某一伺服器監視程式的事件重播至多個其它用戶端監視程式。每個代理都能夠將相關輸入用戶端監視程式合并為單一etcd伺服器監視程式。具體來講,該代理能夠為多個用戶端提供經過合并的監視事件。這些用戶端將共用同一伺服器監視程式;而代理則將有效協助核心集中擺脫資源佔用壓力。
通過添加代理,etcd能夠實現每秒高達百萬個事件,具體如所示。使用與此前樣本相同的測試平台,我們為添加到該叢集中的每個代理附加100個新的監視程式。每個代理皆與etcd執行個體一樣運行有自己的n1-standard-1執行個體。當代理數量達到20個時,監視程式活動強度將線性提升至每秒1000個事件;與此同時,etcd叢集的每秒寫入事件仍低於500次——即未出現任何超載現象。
通過增加監視程式代理提升事件容納通量
大家可以使用etcd基準測試載入器在本地執行類似的實驗。以下為利用3個代理對100條分布串連進行測試所帶來的延遲變化結果:
$ etcd & $ etcd grpc-proxy start --endpoints=http://localhost:2379 --listen-addr=127.0.0.1:23790 & $ etcd grpc-proxy start --endpoints=http://localhost:2379 --listen-addr=127.0.0.1:23791 & $ etcd grpc-proxy start --endpoints=http://localhost:2379 --listen-addr=127.0.0.1:23792 & $ benchmark watch-latency \ --clients=100 --conns=100 --endpoints=http://localhost:23790,http://localhost:23791,http://localhost:23792
分布式協調服務
Etcd這類一致性分布式鍵-值儲存方案的一大優勢,在於其能夠對各分布式系統進行協調與同步。這種協調的一般性原則通常包括分布式共用鎖定以及領導節點選舉。在etcd 3.2當中,分布式共用鎖定與選舉皆被匯出為RPC服務,這不僅極大簡化了分布式協調流程,同時亦提高了其在高延遲環境下的效能表現。
Etcd v3 API的早期開發工作涉及到編寫分布式方法以進行“初步檢查”。根據相關經驗,行之有效協調演算法實際上非常罕見;我們無法指望每個etcd語言綁定皆擁有良好的鎖定協議。一般來講,擁有分布式鎖的第三方etcd綁定只能支援單一簡單定製化鎖,其負責實現自動等待(即利用調用休眠以限制請求數量),從而避免大量請求對於傳輸路徑的爭奪。而由於etcd的gRPC協議能夠帶來出色的移植易行性,我們自然有理由藉此實現更具實效的“鎖即服務”嘗試。
採用伺服器端鎖的最大優勢在於能夠避免網路條件不穩定引發的種種問題。對於用戶端鎖而言,其必須開啟一個監視程式並等待響應以瞭解該鎖是否已經被其它進程所佔用。而在另一方面,鎖RPC只需要進行一次傳輸往返,因此由網路延遲帶來的影響將得到有效控制;如果指向的鎖已經被佔用,etcd則會以內部方式分配監視程式,並在該RPC擷取鎖後再將其返回。所示為網路延遲對用戶端鎖及RPC鎖的具體影響。RPC鎖的平均延遲更低,而隨著網路傳輸往返用時的下降,二者的效能表現則逐步趨同。
爭用與延遲水平提升給鎖延遲帶來的影響(越低越好)。
各RPC複用etcd的用戶端協調代碼以實現交叉相容。要將etcd伺服器串連到自身以同時作為用戶端,各服務可利用一套新的嵌入式用戶端將etcd伺服器內部映射為一套etcd用戶端。對於負責聲明用戶端工作階段的伺服器,新版本亦帶來一項新的會話恢複功能,用於根據原有租約構建會話。通過這樣的代碼複用方式,伺服器端RPC鎖與選舉機制皆能夠在行為上與etcd的用戶端鎖及用戶端選舉機制保持一致。
另外,etcdctl命令列工具還能夠協助使用者快速使用etcd鎖。以下簡單樣本將在shell當中對檔案f進行持續增量;而鎖定機制則確保全部增量都切實得到疊加:
$ echo 0 >f
$ for `seq 1 100`; do
ETCDCTL_API=3 etcdctl lock mylock -- bash -c 'expr 1 + $(cat f) > f' &
pids="$pids $!"
done
$ wait $pids
$ cat f
該鎖服務端點通過etcd的grpc網關接收JSON請求。以下樣本展示了如何利用JSON擷取一套鎖並等待該鎖的實際釋放:
$ lid=$(ETCDCTL_API=3 etcdctl -w fields lease grant 5 | grep '"ID"' | awk ' { print $3 } ')
acquire lock by name "mylock" (base64 encoded) using JSON
$ curl localhost:2379/v3alpha/lock/lock -XPOST -d"{\"name\":\"bXlsb2Nr\", \"lease\" : $lid }" >/dev/null
$ date
lease expires in five seconds, unlocking "mylock" and letting etcdctl acquire the lock
$ ETCDCTL_API=3 etcdctl lock mylock date
瞭解更多
感興趣的朋友可以點擊此處瞭解etcd項目最新最重要的發展成果。該項目亦託管著3.2.0版本的簽名二進位庫以及etcd發佈頁面上的各曆史版本。此GitHub版本也包含與etcd叢集操作以及etcd應用程式開發相關的最新說明文檔。
與以往一樣,etcd團隊致力於打造出最出色的分布式一致性鍵-值儲存方案;如果您發現了任何bug、希望提出問題或者相關建議,請點擊此處訪問etcd問題追蹤頁面。
此次發布的etcd版本亦將被包含在未來的Tectonic版本當中。如果大家有興趣瞭解基於etcd、Kubernetes以及CoreOS的其它分散式運算解決方案,我們亦邀請您點擊此處免費體驗Tectonic。
原文連結:etcd 3.2 now with massive watch scaling and easy locks(翻譯:崔婧雯)