etcd工作原理和部署指南

etcd工作原理和部署指南

jianweixs

 

https://www.jianshu.com/p/8d22ad512a78

etcd-logo.png

​ etcd是由CoreOS團隊發的一個分佈式一致性的KV存儲系統,可用於服務註冊發現和共享配置,隨着CoreOS和Kubernetes等項目在開源社區日益火熱,它們項目中都用到的etcd組件作爲一個高可用強一致性的服務發現存儲倉庫,漸漸爲開發人員所關注。在雲計算時代,如何讓服務快速透明地接入到計算集羣中,如何讓共享配置信息快速被集羣中的所有機器發現,更爲重要的是,如何構建這樣一套高可用、安全、易於部署以及響應快速的服務集羣,已經成爲了迫切需要解決的問題。etcd爲解決這類問題帶來了福音,本文將從etcd的應用場景開始,深入解讀etcd的實現方式,以供開發者們更爲充分地享用etcd所帶來的便利。

特點:

使用場景

  • 配置管理
  • 服務註冊於發現
  • 選主
  • 應用調度
  • 分佈式隊列
  • 分佈式鎖

原理:

​ etcd推薦使用奇數作爲集羣節點個數。因爲奇數個節點和其配對的偶數個節點相比,容錯能力相同,卻可以少一個節點。綜合考慮性能和容錯能力,etcd官方文檔推薦的etcd集羣大小是3,5,7。由於etcd使用是Raft算法,每次寫入數據需要有2N+1個節點同意可以寫入數據,所以部分節點由於網絡或者其他不可靠因素延遲收到數據更新,但是最終數據會保持一致,高度可靠。隨着節點數目的增加,每次的寫入延遲會相應的線性遞增,除了節點數量會影響寫入數據的延遲,如果節點跟接節點之間的網絡延遲,也會導致數據的延遲寫入。
結論:
​ 1.節點數並非越多越好,過多的節點將會導致數據延遲寫入。
​ 2.節點跟節點之間的跨機房,專線之間網絡延遲,也將會導致數據延遲寫入。
​ 3.受網絡IO和磁盤IO的延遲
​ 4.爲了提高吞吐量,etcd通常將多個請求一次批量處理並提交Raft,
​ 5.增加節點,讀性能會提升,寫性能會下降,減少節點,寫性能會提升。

部署

單機節點(CentOS 7)

$ yum install etcd -y 
修改配置文件,通過yum 安裝的etcd,以下是etcd的配置文件:

$ vim /etc/etcd/etcd.conf 
#[Member]
#ETC D_CORS=""
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
#ETCD_WAL_DIR=""
#ETCD_LISTEN_PEER_URLS="http://localhost:2380"
ETCD_LISTEN_CLIENT_URLS="http://192.168.1.109:2379"
#ETCD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
ETCD_NAME="default"
#ETCD_SNAPSHOT_COUNT="100000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
#ETCD_QUOTA_BACKEND_BYTES="0"
#ETCD_MAX_REQUEST_BYTES="1572864"
#ETCD_GRPC_KEEPALIVE_MIN_TIME="5s"
#ETCD_GRPC_KEEPALIVE_INTERVAL="2h0m0s"
#ETCD_GRPC_KEEPALIVE_TIMEOUT="20s"
#
#[Clustering]
#ETCD_INITIAL_ADVERTISE_PEER_URLS="http://localhost:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.1.109:2379"
#ETCD_DISCOVERY=""
#ETCD_DISCOVERY_FALLBACK="proxy"
#ETCD_DISCOVERY_PROXY=""
#ETCD_DISCOVERY_SRV=""
#ETCD_INITIAL_CLUSTER="default=http://localhost:2380"
#ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
#ETCD_INITIAL_CLUSTER_STATE="new"
#ETCD_STRICT_RECONFIG_CHECK="true"
#ETCD_ENABLE_V2="true"
#
#[Proxy]
#ETCD_PROXY="off"
#ETCD_PROXY_FAILURE_WAIT="5000"
#ETCD_PROXY_REFRESH_INTERVAL="30000"
#ETCD_PROXY_DIAL_TIMEOUT="1000"
#ETCD_PROXY_WRITE_TIMEOUT="5000"
#ETCD_PROXY_READ_TIMEOUT="0"
#
#[Security]
#ETCD_CERT_FILE=""
#ETCD_KEY_FILE=""
#ETCD_CLIENT_CERT_AUTH="false"
#ETCD_TRUSTED_CA_FILE=""
#ETCD_AUTO_TLS="false"
#ETCD_PEER_CERT_FILE=""
#ETCD_PEER_KEY_FILE=""
#ETCD_PEER_CLIENT_CERT_AUTH="false"
#ETCD_PEER_TRUSTED_CA_FILE=""
#ETCD_PEER_AUTO_TLS="false"
#
#[Logging]
#ETCD_DEBUG="false"
#ETCD_LOG_PACKAGE_LEVELS=""
#ETCD_LOG_OUTPUT="default"
#
#[Unsafe]
#ETCD_FORCE_NEW_CLUSTER="false"
#
#[Version]
#ETCD_VERSION="false"
#ETCD_AUTO_COMPACTION_RETENTION="0"
#
#[Profiling]
#ETCD_ENABLE_PPROF="false"
#ETCD_METRICS="basic"
#
#[Auth]
#ETCD_AUTH_TOKEN="simple"

參數說明:

  • –data-dir:指定節點的數據存儲目錄,若不指定,則默認是當前目錄。這些數據包括節點ID,集羣ID,集羣初始化配置,Snapshot文件,若未指 定–wal-dir,還會存儲WAL文件
  • –wal-dir:指定節點的was文件存儲目錄,若指定了該參數,wal文件會和其他數據文件分開存儲
  • –name:節點名稱
  • –initial-advertise-peer-urls:告知集羣其他節點的URL,tcp2380端口用於集羣通信
  • –listen-peer-urls:監聽URL,用於與其他節點通訊
  • –advertise-client-urls:告知客戶端的URL, 也就是服務的URL,tcp2379端口用於監聽客戶端請求
  • –initial-cluster-token:集羣的ID
  • –initial-cluster:集羣中所有節點
  • –initial-cluster-state:集羣狀態,new爲新創建集羣,existing爲已存在的集羣
  • etcd 默認存儲大小限制是 2GB, 可以通過 --quota-backend-bytes 標記配置,最大支持 8GB.

啓動etcd服務

$ systemctl start etcd.service
$ systemctl status etcd.service
● etcd.service - Etcd Server
   Loaded: loaded (/usr/lib/systemd/system/etcd.service; disabled; vendor preset: disabled)
   Active: active (running) since 六 2018-06-02 22:17:34 CST; 9s ago
 Main PID: 2876 (etcd)
   CGroup: /system.slice/etcd.service
           └─2876 /usr/bin/etcd --name=default --data-dir=/var/lib/etcd/default.etcd --listen-client-urls=http://192.168.1.109:2379

多節點部署

自定義的 etcd discovery 服務

這種方式就是利用一個已有的 etcd 集羣來提供 discovery 服務,從而搭建一個新的 etcd 集羣。

假設已有的 etcd 集羣的一個訪問地址是:myetcd.local,那麼我們首先需要在已有 etcd 中創建一個特殊的 key,方法如下:

$ curl -X PUT https://myetcd.local/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83/_config/size -d value=3

其中 value=3 表示本集羣的大小,即: 有多少集羣節點。而 6c007a14875d53d9bf0ef5a6fc0257c817f0fb83 就是用來做 discovery 的 token。

接下來你在 3 個節點上分別啓動 etcd 程序,並加上剛剛的 token。
加 token 的方式同樣也有 命令行參數 和 環境變量 兩種。

命令行參數:

-discovery https://myetcd.local/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83

環境變量

ETCD_DISCOVERY=https://myetcd.local/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83

命令行參數啓動方式爲例:

$ etcd -name etcd0 -initial-advertise-peer-urls http://10.0.1.10:2380 \
  -listen-peer-urls http://10.0.1.10:2380 \
  -listen-client-urls http://10.0.1.10:2379,http://127.0.0.1:2379 \
  -advertise-client-urls http://10.0.1.10:2379 \
  -discovery https://myetcd.local/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83
$ etcd -name etcd1 -initial-advertise-peer-urls http://10.0.1.11:2380 \
  -listen-peer-urls http://10.0.1.11:2380 \
  -listen-client-urls http://10.0.1.11:2379,http://127.0.0.1:2379 \
  -advertise-client-urls http://10.0.1.11:2379 \
  -discovery https://myetcd.local/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83
$ etcd -name etcd2 -initial-advertise-peer-urls http://10.0.1.12:2380 \
  -listen-peer-urls http://10.0.1.12:2380 \
  -listen-client-urls http://10.0.1.12:2379,http://127.0.0.1:2379 \
  -advertise-client-urls http://10.0.1.12:2379 \
  -discovery https://myetcd.local/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83

測試

可以使用etcd附帶的基準 CLI工具完成基準測試etcd性能。

對於一些基準性能數字,我們考慮具有以下硬件配置的三個成員的etcd集羣:

  • Google雲計算引擎
  • 3臺8個vCPU + 16GB內存+ 50GB固態硬盤
  • 1臺機器(客戶端),16個vCPU + 30GB內存+ 50GB SSD
  • Ubuntu 17.04
  • etcd 3.2.0,去1.8.3

有了這個配置,etcd可以大致寫出:

密鑰數量 密鑰大小(字節) 值大小以字節爲單位 連接數 客戶數量 目標ETCD服務器 平均寫入QPS 每個請求的平均延遲 平均服務器RSS
8 256 1 1 只有領導者 583 1.6毫秒 48 MB
100000 8 256 100 1000 只有領導者 44341 22毫秒 124MB
100000 8 256 100 1000 所有成員 50104 20ms的 126MB

示例命令是:

# write to leader
benchmark --endpoints=${HOST_1} --target-leader --conns=1 --clients=1 \
    put --key-size=8 --sequential-keys --total=10000 --val-size=256
benchmark --endpoints=${HOST_1} --target-leader  --conns=100 --clients=1000 \
    put --key-size=8 --sequential-keys --total=100000 --val-size=256

# write to all members
benchmark --endpoints=${HOST_1},${HOST_2},${HOST_3} --conns=100 --clients=1000 \
    put --key-size=8 --sequential-keys --total=100000 --val-size=256

可線性讀取請求通過集羣成員的法定人數達成一致以獲取最新數據。可序列化的讀取請求比線性讀取要便宜,因爲它們由任何單個etcd成員提供,而不是成員法定人數,以換取可能的陳舊數據。etcd可以閱讀:

請求數 密鑰大小(字節) 值大小以字節爲單位 連接數 客戶數量 一致性 平均讀取QPS 每個請求的平均延遲
8 256 1 1 線性化 1,353 爲0.7ms
8 256 1 1 序列化 2909 0.3ms的
100000 8 256 100 1000 線性化 141578 5.5ms
100000 8 256 100 1000 序列化 185758 時間爲2.2ms

示例命令是:

# Single connection read requests
benchmark --endpoints=${HOST_1},${HOST_2},${HOST_3} --conns=1 --clients=1 \
    range YOUR_KEY --consistency=l --total=10000
benchmark --endpoints=${HOST_1},${HOST_2},${HOST_3} --conns=1 --clients=1 \
    range YOUR_KEY --consistency=s --total=10000

# Many concurrent read requests
benchmark --endpoints=${HOST_1},${HOST_2},${HOST_3} --conns=100 --clients=1000 \
    range YOUR_KEY --consistency=l --total=100000
benchmark --endpoints=${HOST_1},${HOST_2},${HOST_3} --conns=100 --clients=1000 \
    range YOUR_KEY --consistency=s --total=100000

我們鼓勵在新環境中首次安裝etcd集羣時運行基準測試,以確保集羣達到足夠的性能; 羣集延遲和吞吐量可能會對較小的環境差異敏感。

以上測試部分翻譯自官方文檔(https://coreos.com/etcd/docs/latest/op-guide/performance.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章