etcd的簡單使用
ETCD安裝配置
安裝
去https://github.com/coreos/etcd/releases/下載想要的版本解壓etcd包
解壓后進入目錄,增加x權限
chmod +x etcd chmod +x etcdctl
並將etcd和etcdctl 復制到 /bin
配置啟動
簡單啟動
./bin/etcd 這樣就可以啟動使用
集群配置
在兩台機器上部署了簡單的集群
192.168.231.130 192.168.231.132
在配置文件/etc/defalut/etcd 中增加:
ETCD_OPTS="-name infra0 -initial-advertise-peer-urls http://192.168.231.130:2380 -listen-peer-urls http://192.168.231.130:2380 -initial-cluster- token etcd-cluster-1 -initial-cluster infra0=http://192.168.231.130:2380,infra1=http://192.168.231.132:2380 -initial-cluster-state new"
也可用參數的方法
ETCD_INITIAL_CLUSTER="infra0=http://192.168.231.130:2380,infra1=http://192.168.231.132:2380" ETCD_INITIAL_CLUSTER_STATE=new
192.168.231.132機器上
ETCD_OPTS="-name infra1 -initial-advertise-peer-urls http://192.168.231.132:2380 -listen-peer-urls http://192.168.231.132:2380 -initial-cluster-token etcd-cluster-1 -initial-cluster infra0=http://192.168.231.130:2380,infra1=http://192.168.231.132:2380 -initial-cluster-state new"
參數解釋
啟動etcd進程后查看集群
etcdctl member list 27e6981eec74137d: name=infra0 peerURLs=http://192.168.231.130:2380 clientURLs=http://localhost:2379,http://localhost:4001 3955a9b061e52de1: name=infra1 peerURLs=http://192.168.231.132:2380 clientURLs=http://localhost:2379,http://localhost:4001
判斷leader和followers
curl http://127.0.0.1:2379/v2/stats/leader {"leader":"27e6981eec74137d","followers":{"3955a9b061e52de1":{"latency":{"current":0.178536,"average":0.26406266231884085,"standardDeviation":0.3787246458449882,"minimum":0.084328,"maximum":10.527117},"counts":{"fail":0,"success":1380}}}}
協議
簡單發送一個請求設置key值的請求
# curl -vvv http://127.0.0.1:2379/v2/keys/mykey -XPUT -d value="this is test" * Hostname was NOT found in DNS cache * Trying 127.0.0.1... * Connected to 127.0.0.1 (127.0.0.1) port 2379 (#0) > PUT /v2/keys/mykey HTTP/1.1 > User-Agent: curl/7.35.0 > Host: 127.0.0.1:2379 > Accept: */* > Content-Length: 18 > Content-Type: application/x-www-form-urlencoded > * upload completely sent off: 18 out of 18 bytes < HTTP/1.1 200 OK < Content-Type: application/json < X-Etcd-Cluster-Id: 69bc358c20384a4c < X-Etcd-Index: 16333 < X-Raft-Index: 87030 < X-Raft-Term: 117 < Date: Fri, 14 Aug 2015 01:39:39 GMT < Content-Length: 201 < {"action":"set","node":{"key":"/mykey","value":"this is test","modifiedIndex":16333,"createdIndex":16333},"prevNode":{"key":"/mykey","value":"this is test","modifiedIndex":14840,"createdIndex":14840}} * Connection #0 to host 127.0.0.1 left intact
http接口是rest api的風格
body里面字段詳解:
- action: set 操作對應的是url的put,rest api的風格
- node.key: 設置的key值
- node.value: 設置的value值
- node.createdIndex: 唯一的整數,每當etcd有改變時,這個值也會發生變化. 不僅限於key值操作,包括增加和同步服務改變。這里要修改
- node.modifiedIndex: 和createdIndex類似,也是一個唯一證整數 set , delete , update , create , - compareAndSwap , compareAndDelete 這些操作都會改變這個值,而get和watch 命令不會修改改變這個值
header字段詳解:
X-Etcd-Cluster-Id: 69bc358c20384a4c
X-Etcd-Index: 16333
X-Raft-Index: 87030
X-Raft-Term: 117
- X-Etcd-Index 等同於createdIndex.
- X-Etcd-Index is the current etcd index when the watch starts, which means that the watched event may happen after X-Etcd-Index
- X-Raft-Index 類似etcd index,但是用於raft protocol
- X-Raft-Term is an integer that will increase whenever an etcd master election happens in the cluster. If this number is increasing rapidly, you may need to tune the election timeout. See the tuning section for details.
可以使用etcdctl簡化操作
# etcdctl get mykey
this is test
基本操作
可以使用etcdctl或者url去執行手動操作
etcdctl幾個有用的附加命令
- –debug 將指令的url顯示出來
# etcdctl --debug get mykey Cluster-Endpoints: http://localhost:2379, http://localhost:2379, http://localhost:4001, http://localhost:4001 Curl-Example: curl -X GET http://localhost:2379/v2/keys/mykey?consistent=true&recursive=false&sorted=false this is test
- –output /-o 將輸出以指定的方式顯示出來
# etcdctl -o json get mykey {"action":"get","node":{"key":"/mykey","value":"12345","modifiedIndex":18134,"createdIndex":18134},"etcdIndex":18168,"raftIndex":96532,"raftTerm":124} # etcdctl get mykey 12345
查看版本
curl -L http://127.0.0.1:2379/version etcdctl –version # etcdctl --version etcdctl version 2.0.13
設定鍵值
etcdctl set key value curl -X PUT http://localhost:2379/v2/keys/key -d value=value
如想要創建一個{mykey,kkkkk}的鍵值
# etcdctl --debug -o json set mykey kkkkk Curl-Example: curl -X PUT http://localhost:2379/v2/keys/mykey -d value=kkkkk {"action":"set","node":{"key":"/mykey","value":"kkkkk","modifiedIndex":21283,"createdIndex":21283},"prevNode":{"key":"/mykey","value":"kkkkk","modifiedIndex":20087,"createdIndex":20087},"etcdIndex":21283,"raftIndex":112958,"raftTerm":149} # etcdctl --debug -o json get mykey Curl-Example: curl -X GET http://localhost:2379/v2/keys/mykey?consistent=true&recursive=false&sorted=false {"action":"get","node":{"key":"/mykey","value":"kkkkk","modifiedIndex":21283,"createdIndex":21283},"etcdIndex":21283,"raftIndex":112963,"raftTerm":149}
這里顯示了前一個值,設置后再get返回的是最新的值
etcdctl mk key value也能起到創建並設置鍵值的作用,和set操作的區別主要是,不能對已存在的key進行創建的操作
# etcdctl --debug -o json mk aa 11 Curl-Example: curl -X PUT http://localhost:2379/v2/keys/aa?prevExist=false -d value=11 {"action":"create","node":{"key":"/aa","value":"11","modifiedIndex":21093,"createdIndex":21093},"etcdIndex":21093,"raftIndex":112010,"raftTerm":149} # etcdctl --debug -o json mk aa 22 Curl-Example: curl -X PUT http://localhost:2379/v2/keys/aa?prevExist=false -d value=22 Error: 105: Key already exists (/aa) [21098]
查看鍵值
etcdctl get key curl -X GET http://localhost:2379/v2/keys/key? etcdctl --debug -o json get mykey Cluster-Endpoints: http://localhost:2379, http://localhost:2379, http://localhost:4001, http://localhost:4001 Curl-Example: curl -X GET http://localhost:2379/v2/keys/mykey?consistent=true&recursive=false&sorted=false {"action":"get","node":{"key":"/mykey","value":"12345","modifiedIndex":18134,"createdIndex":18134},"etcdIndex":18661,"raftIndex":99095,"raftTerm":126}
查看鍵值
etcdctl rm key curl -X DELETE http://localhost:2379/v2/keys/key? # etcdctl --debug -o json rm mykey Cluster-Endpoints: http://localhost:2379, http://localhost:2379, http://localhost:4001, http://localhost:4001 Curl-Example: curl -X DELETE http://localhost:2379/v2/keys/mykey?dir=false&recursive=false {"action":"delete","node":{"key":"/mykey","modifiedIndex":18766,"createdIndex":18701},"prevNode":{"key":"/mykey","value":"kkkkk","modifiedIndex":18701,"createdIndex":18701},"etcdIndex":18766,"raftIndex":99607,"raftTerm":127} # etcdctl --debug -o json get mykey Cluster-Endpoints: http://localhost:2379, http://localhost:2379, http://localhost:4001, http://localhost:4001 Curl-Example: curl -X GET http://localhost:2379/v2/keys/mykey?consistent=true&recursive=false&sorted=false Error: 100: Key not found (/mykey) [18766]
設置鍵值的TTL
etcdctl set key value –ttl time
curl -X PUT http://localhost:2379/v2/keys/key -d value=value -d ttl=time
通過設置TTL可以讓key值在規定時間過期,比如設置這個key的ttl為100
etcdctl --debug -o json set mykey ok --ttl 100 Cluster-Endpoints: http://localhost:2379, http://localhost:2379, http://localhost:4001, http://localhost:4001 Curl-Example: curl -X PUT http://localhost:2379/v2/keys/mykey -d value=ok -d ttl=100 {"action":"set","node":{"key":"/mykey","value":"ok","expiration":"2015-08-14T03:15:14.665295244Z","ttl":100,"modifiedIndex":19036,"createdIndex":19036},"etcdIndex":19036,"raftIndex":100957,"raftTerm":129}
過了幾十秒查看,ttl減為23
# etcdctl --debug -o json get mykey Cluster-Endpoints: http://localhost:2379, http://localhost:2379, http://localhost:4001, http://localhost:4001 Curl-Example: curl -X GET http://localhost:2379/v2/keys/mykey?consistent=true&recursive=false&sorted=false {"action":"get","node":{"key":"/mykey","value":"ok","expiration":"2015-08-14T03:15:14.665295244Z","ttl":23,"modifiedIndex":19036,"createdIndex":19036},"etcdIndex":19077,"raftIndex":101148,"raftTerm":129}
當ttl減為0,這個key值就查詢不到了
Error: 100: Key not found (/mykey) [19084]
目錄的ttl設置方法和key的類似
監控鍵值的改動
etcdctl watch key curl -X GET http://localhost:2379/v2/keys/key?consistent=true&wait=true
監聽鍵值的改動,然后輸出信息, –after-index可以根據etcd-index來獲取后續index對應的改動
etcdctl --debug watch mykey Cluster-Endpoints: http://localhost:2379, http://localhost:2379, http://localhost:4001, http://localhost:4001 Curl-Example: curl -X GET http://localhost:2379/v2/keys/mykey?consistent=true&wait=true
當監測到鍵值設置為kkkkk時打印
kkkkk
若etcdctl watch 帶上–forever參數則會不退出一直監測鍵值的改動,比如這里檢測到了set和delete操作
# etcdctl --debug -o json watch mykey --forever Curl-Example: curl -X GET http://localhost:2379/v2/keys/mykey?consistent=true&wait=true {"action":"set","node":{"key":"/mykey","value":"kkkkk","modifiedIndex":19656,"createdIndex":19656},"prevNode":{"key":"/mykey","value":"kkkkk","modifiedIndex":19645,"createdIndex":19645},"etcdIndex":19655,"raftIndex":104107,"raftTerm":131} Curl-Example: curl -X GET http://localhost:2379/v2/keys/mykeyconsistent=true&wait=true&waitIndex=19657 {"action":"delete","node":{"key":"/mykey","modifiedIndex":19661,"createdIndex":19656},"prevNode":{"key":"/mykey","value":"kkkkk","modifiedIndex":19656,"createdIndex":19656},"etcdIndex":19656,"raftIndex":104115,"raftTerm":131} Curl-Example: curl -X GET http://localhost:2379/v2/keys/mykey?consistent=true&wait=true&waitIndex=19662
對於目錄類型的key可以用–recursive 來檢測目錄下的子keys的改動
同樣可以用作監測的命令是exec-watch,相比watch,增加了監測到改動可以執行自定義的操作
etcdctl watch key command
# etcdctl exec-watch mykey -- sh -c 'echo hit' hit
目錄相關的操作
etcdctl mkdir dirname
創建一個目錄可以關聯多個子keys,比如先建立一個名叫mydir的dir
etcdctl --debug -o json mkdir mydir Curl-Example: curl -X PUT http://localhost:2379/v2/keys/mydir?dir=true&prevExist=false
在這個dir下面可以建立多個keys
# etcdctl --debug -o json set /mydir/key1 11111 Curl-Example: curl -X PUT http://localhost:2379/v2/keys/mydir/key1 -d value=11111 {"action":"set","node":{"key":"/mydir/key1","value":"11111","modifiedIndex":20850,"createdIndex":20850},"etcdIndex":20850,"raftIndex":110723,"raftTerm":148} # etcdctl --debug -o json set /mydir/key2 22222 Curl-Example: curl -X PUT http://localhost:2379/v2/keys/mydir/key2 -d value=22222 {"action":"set","node":{"key":"/mydir/key2","value":"22222","modifiedIndex":20855,"createdIndex":20855},"etcdIndex":20855,"raftIndex":110747,"raftTerm":148}
可以用etcdctl ls dirname進行查看,得到該dir下面的2個key
# etcdctl --debug -o json ls /mydir Curl-Example: curl -X GET http://localhost:2379/v2/keys/mydir?consistent=true&recursive=false&sorted=false /mydir/key2 /mydir/key1
如果向目錄名的路徑 post一個value,那么在這個目錄下面會自動用createdIndex創建一個key
# curl -X POST http://localhost:2379/v2/keys/mydir -d value=33333 {"action":"create","node":{"key":"/mydir/21442","value":"33333","modifiedIndex":21442,"createdIndex":21442}} # etcdctl --debug -o json ls /mydir Curl-Example: curl -X GET http://localhost:2379/v2/keys/mydir?consistent=true&recursive=false&sorted=false /mydir/key1 /mydir/key2 /mydir/21442
用rmdir 刪除目錄要保證目錄下沒有keys,不然會失敗
# etcdctl --debug -o json rmdir mydir Curl-Example: curl -X DELETE http://localhost:2379/v2/keys/mydir?dir=true&recursive=false Error: 108: Directory not empty (/mydir) [21682]
若要將目錄和keys都刪除可以用rm指令
# etcdctl --debug -o json rm mydir --recursive=true Curl-Example: curl -X DELETE http://localhost:2379/v2/keys/mydir?dir=false&recursive=true # etcdctl --debug -o json ls /mydir Curl-Example: curl -X GET http://localhost:2379/v2/keys/mydir?consistent=true&recursive=false&sorted=false Error: 100: Key not found (/mydir) [21883]
狀態查看
etcd分別提供了查看leader、自己以及store狀態的接口
- 查看leader的狀態
curl http://127.0.0.1:2379/v2/stats/leader {"leader":"27e6981eec74137d","followers":{"3955a9b061e52de1":{"latency":{"current":0.158241,"average":0.22540039942528703,"standardDeviation":0.17653730983599686,"minimum":0.087808,"maximum":1.988291},"counts":{"fail":0,"success":348}}}}
- 查看自己的狀態
curl http://127.0.0.1:2379/v2/stats/self # curl http://127.0.0.1:2379/v2/stats/self {"name":"infra0","id":"27e6981eec74137d","state":"StateLeader","startTime":"2015-08-14T12:52:39.624477849+08:00","leaderInfo":{"leader":"27e6981eec74137d","uptime":"2m37.095030303s","startTime":"2015-08-14T12:55:31.332765166+08:00"},"recvAppendRequestCnt":429,"sendAppendRequestCnt":1064,"sendPkgRate":6.896118337343223,"sendBandwidthRate":1170.6850489473857}
- 查看store的狀態
curl http://127.0.0.1:2379/v2/stats/store {"getsSuccess":13,"getsFail":2152,"setsSuccess":120,"setsFail":2,"deleteSuccess":6,"deleteFail":0,"updateSuccess":0,"updateFail":0,"createSuccess":961,"createFail":186,"compareAndSwapSuccess":19631,"compareAndSwapFail":296,"compareAndDeleteSuccess":0,"compareAndDeleteFail":0,"expireCount":849,"watchers":0}
其他接口以及更詳盡的接口說明可以看官網說明