從0到1,手把手教你入門 etcd

背景:近期 k8s 應用中 etcd 的功能存在一些困惑,對其進行來單獨的學習,能更深入理解 k8s 中的的一些特性。

一、概述

1.1 etcd 簡介

etcd 是 CoreOS 團隊於 2013 年 6月發起的開源項目,它的目標是構建一個高可用的分佈式鍵值(key-value)數據庫。etcd 內部採用raft協議作爲一致性算法,etcd 基於 Go 語言實現。

1.2 發展歷史

1.3 etcd 的特點

  • 簡單安裝配置簡單,而且提供了HTTP API進行交互,使用也很簡單

  • 安全支持SSL證書驗證

  • 快速根據官方提供的benchmark數據,單實例支持每秒2k+讀操作

  • 可靠採用raft算法,實現分佈式系統數據的可用性和一致性

1.4 概念術語

  • Raftetcd所採用的保證分佈式系統強一致性的算法。

  • Node一個Raft狀態機實例。

  • Member一個etcd實例。它管理着一個Node,並且可以爲客戶端請求提供服務。

  • Cluster由多個Member構成可以協同工作的etcd集羣。

  • Peer對同一個etcd集羣中另外一個Member的稱呼。

  • Client向etcd集羣發送HTTP請求的客戶端。

  • WAL預寫式日誌,etcd用於持久化存儲的日誌格式。

  • snapshotetcd防止WAL文件過多而設置的快照,存儲etcd數據狀態。

  • Proxyetcd的一種模式,爲etcd集羣提供反向代理服務。

  • LeaderRaft算法中通過競選而產生的處理所有數據提交的節點。

  • Follower競選失敗的節點作爲Raft中的從屬節點,爲算法提供強一致性保證。

  • Candidate當Follower超過一定時間接收不到Leader的心跳時轉變爲Candidate開始競選。

  • Term某個節點成爲Leader到下一次競選時間,稱爲一個Term。

  • Index數據項編號。Raft中通過Term和Index來定位數據。

1.5 數據讀寫順序

爲了保證數據的強一致性,etcd 集羣中所有的數據流向都是一個方向,從 Leader (主節點)流向 Follower,也就是所有 Follower 的數據必須與 Leader 保持一致,如果不一致會被覆蓋。

用戶對於 etcd 集羣所有節點進行讀寫

  • 讀取由於集羣所有節點數據是強一致性的,讀取可以從集羣中隨便哪個節點進行讀取數據

  • 寫入etcd 集羣有 leader,如果寫入往 leader 寫入,可以直接寫入,然後然後Leader節點會把寫入分發給所有 Follower,如果往 follower 寫入,然後Leader節點會把寫入分發給所有 Follower

1.6 leader 選舉

假設三個節點的集羣,三個節點上均運行 Timer(每個 Timer 持續時間是隨機的),Raft算法使用隨機 Timer 來初始化 Leader 選舉流程,第一個節點率先完成了 Timer,隨後它就會向其他兩個節點發送成爲 Leader 的請求,其他節點接收到請求後會以投票迴應然後第一個節點被選舉爲 Leader。

成爲 Leader 後,該節點會以固定時間間隔向其他節點發送通知,確保自己仍是Leader。有些情況下當 Follower 們收不到 Leader 的通知後,比如說 Leader 節點宕機或者失去了連接,其他節點會重複之前選舉過程選舉出新的 Leader。

1.7 判斷數據是否寫入

etcd 認爲寫入請求被 Leader 節點處理並分發給了多數節點後,就是一個成功的寫入。那麼多少節點如何判定呢,假設總結點數是 N,那麼多數節點 Quorum=N/2+1。關於如何確定 etcd 集羣應該有多少個節點的問題,上圖的左側的圖表給出了集羣中節點總數(Instances)對應的 Quorum 數量,用 Instances 減去 Quorom 就是集羣中容錯節點(允許出故障的節點)的數量。

所以在集羣中推薦的最少節點數量是3個,因爲1和2個節點的容錯節點數都是0,一旦有一個節點宕掉整個集羣就不能正常工作了。

二、etcd 架構及解析

2.1 架構圖

2.2 架構解析

從 etcd 的架構圖中我們可以看到,etcd 主要分爲四個部分。

  • HTTP Server:用於處理用戶發送的 API 請求以及其它 etcd 節點的同步與心跳信息請求。

  • Store:用於處理 etcd 支持的各類功能的事務,包括數據索引、節點狀態變更、監控與反饋、事件處理與執行等等,是 etcd 對用戶提供的大多數 API 功能的具體實現。

  • Raft:Raft 強一致性算法的具體實現,是 etcd 的核心。

  • WAL:Write Ahead Log(預寫式日誌),是 etcd 的數據存儲方式。除了在內存中存有所有數據的狀態以及節點的索引以外,etcd 就通過 WAL 進行持久化存儲。WAL 中,所有的數據提交前都會事先記錄日誌。

    • Snapshot 是爲了防止數據過多而進行的狀態快照;

    • Entry 表示存儲的具體日誌內容。

通常,一個用戶的請求發送過來,會經由 HTTP Server 轉發給 Store 進行具體的事務處理,如果涉及到節點的修改,則交給 Raft 模塊進行狀態的變更、日誌的記錄,然後再同步給別的 etcd 節點以確認數據提交,最後進行數據的提交,再次同步。

三、應用場景

3.1 服務註冊與發現

etcd 可以用於服務的註冊與發現

  • 前後端業務註冊發現

中間價已經後端服務在 etcd 中註冊,前端和中間價可以很輕鬆的從 etcd 中發現相關服務器然後服務器之間根據調用關係相關綁定調用

  • 多組後端服務器註冊發現

後端多個無狀態相同副本的 app 可以同事註冊到 etcd 中,前端可以通過 haproxy 從etcd 中獲取到後端的 ip 和端口組,然後進行請求轉發,可以用來故障轉移屏蔽後端端口已經後端多組app實例。

3.2 消息發佈與訂閱

etcd 可以充當消息中間件,生產者可以往 etcd 中註冊 topic 併發送消息,消費者從etcd 中訂閱 topic,來獲取生產者發送至 etcd 中的消息。

3.3 負載均衡

後端多組相同的服務提供者可以經自己服務註冊到 etcd 中,etcd 並且會與註冊的服務進行監控檢查,服務請求這首先從 etcd 中獲取到可用的服務提供者真正的 ip:port,然後對此多組服務發送請求,etcd 在其中充當了負載均衡的功能

3.4 分部署通知與協調

  • 當 etcd watch 服務發現丟失,會通知服務檢查

  • 控制器向 etcd 發送啓動服務,etcd通知服務進行相應操作

  • 當服務完成 work 會講狀態更新至 etcd,etcd 對應會通知用戶

3.5 分佈式鎖

當有多個競爭者 node 節點,etcd 作爲總控,在分佈式集羣中與一個節點成功分配 lock

3.6 分佈式隊列

有對個 node,etcd 根據每個 node 來創建對應 node 的隊列,根據不同的隊列可以在etcd 中找到對應的 competitor

3.7 集羣與監控與 Leader 選舉

etcd 可以根據 raft 算法在多個 node 節點來選舉出 leader。

四、安裝部署

4.1 單機部署

可以使用二進制或源碼下載安裝,但是危害需要自己寫配置文件,如何要啓動需要自己寫服務啓動文件,推薦使用 yum 安裝方式

hostnamectl set-hostname etcd-1
wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -ivh epel-release-latest-7.noarch.rpm
# yum 倉庫中的etcd版本爲3.3.11,如果需要最新版本的etcd可以進行二進制安裝
yum -y install etcd
systemctl enable etcd

可以查看 yum 安裝的 etcd 的有效配置文件,根據自己的需求來修改數據存儲目錄,已經監聽端口 url/etcd 的名稱等

  • etcd 默認將數據存放到當前路徑的 default.etcd/ 目錄下

  • 在 http://localhost:2380 和集羣中其他節點通信

  • 在 http://localhost:2379 提供 HTTP API 服務,供客戶端交互

  • 該節點的名稱默認爲 default

    • heartbeat 爲 100ms,後面會說明這個配置的作用

  • election 爲 1000ms,後面會說明這個配置的作用

  • snapshot count 爲 10000,後面會說明這個配置的作用

  • 集羣和每個節點都會生成一個 uuid

  • 啓動的時候,會運行 raft,選舉出 leader

[root@VM_0_8_centos tmp]# grep -Ev "^#|^$" /etc/etcd/etcd.conf
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS="http://localhost:2379"
ETCD_NAME="default"
ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379"
[root@VM_0_8_centos tmp]# systemctl status etcd

4.2 集羣部署

集羣部署最好部署奇數位,此能達到最好的集羣容錯

4.2.1 主機信息

4.2.2 host 配置

在此示例用三個節點來部署 etcd 集羣,各節點修改 hosts

cat >> /etc/hosts << EOF
172.16.0.8 etcd-0-8
172.16.0.14 etcd-0-14
172.16.0.17 etcd-0-17
EOF

4.2.3 etcd 安裝

三個節點均安裝 etcd

wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -ivh epel-release-latest-7.noarch.rpm
yum -y install etcd
systemctl enable etcd
mkdir -p /data/app/etcd/
chown etcd:etcd /data/app/etcd/

4.2.4 etcd 配置

  • etcd默認配置文件(略)

etcd-0-8配置:

[root@etcd-server ~]# hostnamectl set-hostname etcd-0-8
[root@etcd-0-8 ~]# egrep "^#|^$" /etc/etcd/etcd.conf -v
ETCD_DATA_DIR="/data/app/etcd/"
ETCD_LISTEN_PEER_URLS="http://172.16.0.8:2380"
ETCD_LISTEN_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.0.8:2379"
ETCD_NAME="etcd-0-8"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://172.16.0.8:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.0.8:2379"
ETCD_INITIAL_CLUSTER="etcd-0-8=http://172.16.0.8:2380,etcd-0-17=http://172.16.0.17:2380,etcd-0-14=http://172.16.0.14:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-token"
ETCD_INITIAL_CLUSTER_STATE="new"

etcd-0-14配置:

[root@etcd-server ~]# hostnamectl set-hostname etcd-0-14
[root@etcd-server ~]# mkdir -p /data/app/etcd/
[[email protected] ~]# egrep "^#|^$" /etc/etcd/etcd.conf -v
ETCD_DATA_DIR="/data/app/etcd/"
ETCD_LISTEN_PEER_URLS="http://172.16.0.14:2380"
ETCD_LISTEN_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.0.14:2379"
ETCD_NAME="etcd-0-14"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://172.16.0.14:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.0.14:2379"
ETCD_INITIAL_CLUSTER="etcd-0-8=http://172.16.0.8:2380,etcd-0-17=http://172.16.0.17:2380,etcd-0-14=http://172.16.0.14:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-token"
ETCD_INITIAL_CLUSTER_STATE="new"

etcd-0-7配置:

[root@etcd-server ~]# hostnamectl set-hostname etcd-0-17
[root@etcd-server ~]# mkdir -p /data/app/etcd/
[root@etcd-0-17 ~]# egrep "^#|^$" /etc/etcd/etcd.conf -v
ETCD_DATA_DIR="/data/app/etcd/"
ETCD_LISTEN_PEER_URLS="http://172.16.0.17:2380"
ETCD_LISTEN_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.0.17:2379"
ETCD_NAME="etcd-0-17"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://172.16.0.17:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.0.17:2379"
ETCD_INITIAL_CLUSTER="etcd-0-8=http://172.16.0.8:2380,etcd-0-17=http://172.16.0.17:2380,etcd-0-14=http://172.16.0.14:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-token"
ETCD_INITIAL_CLUSTER_STATE="new"

配置完成後啓動服務

systemctl start etcd

4.2.5 查看集羣狀態

  • 查看 etcd 狀態

[root@etcd-0-8 default.etcd]# systemctl status etcd
● etcd.service - Etcd Server
   Loaded: loaded (/usr/lib/systemd/system/etcd.service; enabled; vendor preset: disabled)
   Active: active (running) since 二 2019-12-03 15:55:28 CST; 8s ago
 Main PID: 24510 (etcd)
   CGroup: /system.slice/etcd.service
           └─24510 /usr/bin/etcd --name=etcd-0-8 --data-dir=/data/app/etcd/ --listen-client-urls=http://172.16.0.8:2379

12月 03 15:55:28 etcd-0-8 etcd[24510]: set the initial cluster version to 3.0
12月 03 15:55:28 etcd-0-8 etcd[24510]: enabled capabilities for version 3.0
12月 03 15:55:30 etcd-0-8 etcd[24510]: peer 56e0b6dad4c53d42 became active
12月 03 15:55:30 etcd-0-8 etcd[24510]: established a TCP streaming connection with peer 56e0b6dad4c53d42 (stream Message reader)
12月 03 15:55:30 etcd-0-8 etcd[24510]: established a TCP streaming connection with peer 56e0b6dad4c53d42 (stream Message writer)
12月 03 15:55:30 etcd-0-8 etcd[24510]: established a TCP streaming connection with peer 56e0b6dad4c53d42 (stream MsgApp v2 reader)
12月 03 15:55:30 etcd-0-8 etcd[24510]: established a TCP streaming connection with peer 56e0b6dad4c53d42 (stream MsgApp v2 writer)
12月 03 15:55:32 etcd-0-8 etcd[24510]: updating the cluster version from 3.0 to 3.3
12月 03 15:55:32 etcd-0-8 etcd[24510]: updated the cluster version from 3.0 to 3.3
12月 03 15:55:32 etcd-0-8 etcd[24510]: enabled capabilities for version 3.3

查看端口監聽(如果未在本地監聽環回地址,那麼在本地使用etcdctl不能正常連入進去)

[root@etcd-0-8 default.etcd]# netstat -lntup |grep etcd
tcp 0      0 172.16.0.8:2379   0.0.0.0:*     LISTEN 25167/etcd
tcp 0      0 127.0.0.1:2379    0.0.0.0:*     LISTEN 25167/etcd
tcp 0      0 172.16.0.8:2380   0.0.0.0:*    LISTEN 25167/etcd

查看集羣狀態(可以看到etcd-0-17)

[root@etcd-0-8 default.etcd]# etcdctl member list
2d2e457c6a1a76cb: name=etcd-0-8 peerURLs=http://172.16.0.8:2380 clientURLs=http://127.0.0.1:2379,http://172.16.0.8:2379 isLeader=false
56e0b6dad4c53d42: name=etcd-0-14 peerURLs=http://172.16.0.14:2380 clientURLs=http://127.0.0.1:2379,http://172.16.0.14:2379 isLeader=true
d2d2e9fc758e6790: name=etcd-0-17 peerURLs=http://172.16.0.17:2380 clientURLs=http://127.0.0.1:2379,http://172.16.0.17:2379 isLeader=false

[root@etcd-0-8 ~]# etcdctl cluster-health
member 2d2e457c6a1a76cb is healthy: got healthy result from http://127.0.0.1:2379
member 56e0b6dad4c53d42 is healthy: got healthy result from http://127.0.0.1:2379
member d2d2e9fc758e6790 is healthy: got healthy result from http://127.0.0.1:2379
cluster is healthy

五、簡單使用

5.1 增加

  • set

指定某個鍵的值。例如:

$ etcdctl set /testdir/testkey "Hello world"
Hello world

#支持的選項包括:
--ttl '0' 該鍵值的超時時間(單位爲秒),不配置(默認爲0)則永不超時
--swap-with-value value 若該鍵現在的值是value,則進行設置操作
--swap-with-index '0'   若該鍵現在的索引值是指定索引,則進行設置操作
  • mk

如果給定的鍵不存在,則創建一個新的鍵值。例如:

$ etcdctl mk /testdir/testkey "Hello world"
Hello world

#當鍵存在的時候,執行該命令會報錯,例如:
$ etcdctl mk /testdir/testkey "Hello world"
Error: 105: Key already exists (/testdir/testkey) [8]

#支持的選項爲:
--ttl '0' 超時時間(單位爲秒),不配置(默認爲 0)。則永不超時
  • mkdir

如果給定的鍵目錄不存在,則創建一個新的鍵目錄。例如:

$ etcdctl mkdir testdir2

#支持的選項爲:
--ttl '0' 超時時間(單位爲秒),不配置(默認爲0)則永不超時。
  • setdir

創建一個鍵目錄。如果目錄不存在就創建,如果目錄存在更新目錄TTL。

$ etcdctl setdir testdir3

#支持的選項爲:
--ttl '0' 超時時間(單位爲秒),不配置(默認爲0)則永不超時。

5.2 刪除

  • rm

刪除某個鍵值。例如:

$ etcdctl rm /testdir/testkey
PrevNode.Value: Hello

#當鍵不存在時,則會報錯。例如:
$ etcdctl rm /testdir/testkey
Error: 100: Key not found (/testdir/testkey) [7]

#支持的選項爲:
--dir 如果鍵是個空目錄或者鍵值對則刪除
--recursive 刪除目錄和所有子鍵
--with-value 檢查現有的值是否匹配
--with-index '0'檢查現有的index是否匹配
  • rmdir

刪除一個空目錄,或者鍵值對。

$ etcdctl setdir dir1
$ etcdctl rmdir dir1

#若目錄不空,會報錯:
$ etcdctl set /dir/testkey hi
hi
$ etcdctl rmdir /dir
Error: 108: Directory not empty (/dir) [17]

5.3 更新

  • update

當鍵存在時,更新值內容。例如:

$ etcdctl update /testdir/testkey "Hello"
Hello

#當鍵不存在時,則會報錯。例如:
$ etcdctl update /testdir/testkey2 "Hello"
Error: 100: Key not found (/testdir/testkey2) [6]

#支持的選項爲:
--ttl '0' 超時時間(單位爲秒),不配置(默認爲 0)則永不超時。
  • updatedir

更新一個已經存在的目錄。

$ etcdctl updatedir testdir2

#支持的選項爲:
--ttl '0' 超時時間(單位爲秒),不配置(默認爲0)則永不超時。

5.4 查詢

  • get

獲取指定鍵的值。例如:

$ etcdctl get /testdir/testkey
Hello world

#當鍵不存在時,則會報錯。例如:
$ etcdctl get /testdir/testkey2
Error: 100: Key not found (/testdir/testkey2) [5]

#支持的選項爲:
--sort 對結果進行排序
--consistent 將請求發給主節點,保證獲取內容的一致性。
  • ls

列出目錄(默認爲根目錄)下的鍵或者子目錄,默認不顯示子目錄中內容。

例如:

$ etcdctl ls
/testdir
/testdir2
/dir

$ etcdctl ls dir
/dir/testkey

#支持的選項包括:
--sort 將輸出結果排序
--recursive 如果目錄下有子目錄,則遞歸輸出其中的內容
-p 對於輸出爲目錄,在最後添加/進行區分

5.5 watch

  • watch

監測一個鍵值的變化,一旦鍵值發生更新,就會輸出最新的值並退出。
例如:用戶更新testkey鍵值爲Hello watch。

$ etcdctl get /testdir/testkey
Hello world
$ etcdctl set /testdir/testkey "Hello watch"
Hello watch
$ etcdctl watch testdir/testkey
Hello watch

複製代碼支持的選項包括:

--forever  一直監測直到用戶按CTRL+C退出
--after-index '0' 在指定index之前一直監測
--recursive 返回所有的鍵值和子鍵值
  • exec-watch

監測一個鍵值的變化,一旦鍵值發生更新,就執行給定命令。
例如:用戶更新testkey鍵值。

$ etcdctl exec-watch testdir/testkey -- sh -c 'ls'
config Documentation etcd etcdctl README-etcdctl.md README.md READMEv2-etcdctl.md

支持的選項包括:

--after-index '0' 在指定 index 之前一直監測
--recursive 返回所有的鍵值和子鍵值

5.6 備份

備份etcd的數據。

$ etcdctl backup --data-dir /var/lib/etcd --backup-dir /home/etcd_backup

支持的選項包括:

--data-dir  etcd的數據目錄
--backup-dir 備份到指定路徑

5.7 member

通過listaddremove命令列出、添加、刪除 etcd 實例到 etcd 集羣中。

查看集羣中存在的節點

$ etcdctl member list
8e9e05c52164694d: name=dev-master-01 peerURLs=http://localhost:2380 clientURLs=http://localhost:2379 isLeader=true

刪除集羣中存在的節點

$ etcdctl member remove 8e9e05c52164694d
Removed member 8e9e05c52164694d from cluster

向集羣中新加節點

$ etcdctl member add etcd3 http://192.168.1.100:2380
Added member named etcd3 with ID 8e9e05c52164694d to cluster

示例

# 設置一個key值
[root@etcd-0-8 ~]# etcdctl set /msg "hello k8s"
hello k8s

# 獲取key的值
[root@etcd-0-8 ~]# etcdctl get /msg
hello k8s

# 獲取key值的詳細信息
[root@etcd-0-8 ~]# etcdctl -o extended get /msg
Key: /msg
Created-Index: 12
Modified-Index: 12
TTL: 0
Index: 12

hello k8s

# 獲取不存在的key回報錯
[root@etcd-0-8 ~]# etcdctl get /xxzx
Error: 100: Key not found (/xxzx) [12]

# 設置key的ttl,過期後會被自動刪除
[root@etcd-0-8 ~]# etcdctl set /testkey "tmp key test" --ttl 5
tmp key test
[root@etcd-0-8 ~]# etcdctl get /testkey
Error: 100: Key not found (/testkey) [14]

# key 替換操作
[root@etcd-0-8 ~]# etcdctl get /msg
hello k8s
[root@etcd-0-8 ~]# etcdctl set --swap-with-value "hello k8s" /msg "goodbye"
goodbye
[root@etcd-0-8 ~]# etcdctl get /msg
goodbye

# mk 僅當key不存在時創建(set對同一個key會覆蓋)
[root@etcd-0-8 ~]# etcdctl get /msg
goodbye
[root@etcd-0-8 ~]# etcdctl mk /msg "mktest"
Error: 105: Key already exists (/msg) [18]
[root@etcd-0-8 ~]# etcdctl mk /msg1 "mktest"
mktest

# 創建自排序的key
[root@etcd-0-8 ~]# etcdctl mk --in-order /queue s1
s1
[root@etcd-0-8 ~]# etcdctl mk --in-order /queue s2
s2
[root@etcd-0-8 ~]# etcdctl ls --sort /queue
/queue/00000000000000000021
/queue/00000000000000000022
[root@etcd-0-8 ~]# etcdctl get /queue/00000000000000000021
s1

# 更新key值
[root@etcd-0-8 ~]# etcdctl update /msg1 "update test"
update test
[root@etcd-0-8 ~]# etcdctl get /msg1
update test

# 更新key的ttl及值
[root@etcd-0-8 ~]# etcdctl update --ttl 5 /msg "aaa"
aaa

# 創建目錄
[root@etcd-0-8 ~]# etcdctl mkdir /testdir

# 刪除空目錄
[root@etcd-0-8 ~]# etcdctl mkdir /test1
[root@etcd-0-8 ~]# etcdctl rmdir /test1

# 刪除非空目錄
[root@etcd-0-8 ~]# etcdctl get /testdir
/testdir: is a directory
[root@etcd-0-8 ~]#
[root@etcd-0-8 ~]# etcdctl rm --recursive /testdir

# 列出目錄內容
[root@etcd-0-8 ~]# etcdctl ls /
/tmp
/msg1
/queue
[root@etcd-0-8 ~]# etcdctl ls /tmp
/tmp/a
/tmp/b

# 遞歸列出目錄的內容
[root@etcd-0-8 ~]# etcdctl ls --recursive /
/msg1
/queue
/queue/00000000000000000021
/queue/00000000000000000022
/tmp
/tmp/b
/tmp/a

# 監聽key,當key發生改變的時候打印出變化
[root@etcd-0-8 ~]# etcdctl watch /msg1
xxx

[root@VM_0_17_centos ~]# etcdctl update /msg1 "xxx"
xxx

# 監聽某個目錄,當目錄中任何 node 改變的時候,都會打印出來
[root@etcd-0-8 ~]# etcdctl watch --recursive /
[update] /msg1
xxx

[root@VM_0_17_centos ~]# etcdctl update /msg1 "xxx"
xxx

# 一直監聽,除非 `CTL + C` 導致退出監聽
[root@etcd-0-8 ~]# etcdctl watch --forever /

# 監聽目錄,當發生變化時執行一條命令
[root@etcd-0-8 ~]# etcdctl exec-watch --recursive / -- sh -c "echo change"
change

# backup
[root@etcd-0-14 ~]# etcdctl backup --data-dir /data/app/etcd --backup-dir /root/etcd_backup
2019-12-04 10:25:16.113237 I | ignoring EntryConfChange raft entry
2019-12-04 10:25:16.113268 I | ignoring EntryConfChange raft entry
2019-12-04 10:25:16.113272 I | ignoring EntryConfChange raft entry
2019-12-04 10:25:16.113293 I | ignoring member attribute update on /0/members/2d2e457c6a1a76cb/attributes
2019-12-04 10:25:16.113299 I | ignoring member attribute update on /0/members/d2d2e9fc758e6790/attributes
2019-12-04 10:25:16.113305 I | ignoring member attribute update on /0/members/56e0b6dad4c53d42/attributes
2019-12-04 10:25:16.113310 I | ignoring member attribute update on /0/members/56e0b6dad4c53d42/attributes
2019-12-04 10:25:16.113314 I | ignoring member attribute update on /0/members/2d2e457c6a1a76cb/attributes
2019-12-04 10:25:16.113319 I | ignoring member attribute update on /0/members/d2d2e9fc758e6790/attributes
2019-12-04 10:25:16.113384 I | ignoring member attribute update on /0/members/56e0b6dad4c53d42/attributes

# 使用v3版本
[root@etcd-0-14 ~]# export ETCDCTL_API=3
[root@etcd-0-14 ~]# etcdctl --endpoints="http://172.16.0.8:2379,http://172.16.0.14:2379,http://172.16.0.17:2379" snapshot save mysnapshot.db
Snapshot saved at mysnapshot.db
[root@etcd-0-14 ~]# etcdctl snapshot status mysnapshot.db -w json
{"hash":928285884,"revision":0,"totalKey":5,"totalSize":20480}

六、總結

  • etcd 默認只保存 1000 個歷史事件,所以不適合有大量更新操作的場景,這樣會導致數據的丟失。etcd 典型的應用場景是配置管理和服務發現,這些場景都是讀多寫少的。

  • 相比於 zookeeper,etcd 使用起來要簡單很多。不過要實現真正的服務發現功能,etcd 還需要和其他工具(比如 registrator、confd 等)一起使用來實現服務的自動註冊和更新。

  • 目前 etcd 還沒有圖形化的工具。

作者:kaliarch
鏈接:https://juejin.im/post/5e02fb1f518825123b1aa341

end

最新整理的 2TB 乾貨資源,包括但不限於:架構師、大數據、Docker、運維、數據庫、redis、MongoDB、電子書、Java基礎、Java實戰項目、ELK Stack、機器學習、BAT面試精講視頻等。只需在公衆號對話框回覆關鍵字:1024 即可免費獲取全部資料。 

推薦閱讀  點擊標題可跳轉

1、B 站!你真的變了

2、再見!螞蟻金服

3、葵花寶典!一文搞定 Nginx 限流配置

4、Prometheus 如何做到“活學活用”,大牛總結的避坑指南

5、一文教你使用 Jenkins 設計多環境、多項目持續集成環境!

6、Redis性能指標監控!你知幾何?

看完本文有收穫,請分享給更多人

關注「民工哥技術之路」加星標,提升IT技能

好文章,朕在看」❤️↓↓↓

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