與etcd進行交互
用戶更多的是通過putting或者是getting從etcd獲取一個鍵對應的值。這一部分描述了如何通過etcdctl做這些工作。etcdctl是一個與etcd服務器進行交互的命令行工具.這里的描述適用於gRPC APIs或者是客戶端庫的APIs。
用於與etcd交互的API版本可以通過環境變量ETCDCTL_API
設置為2或者3.默認情況下,分支為(3.4)的主版本使用V3 的API,而早期的版本(3.3或者更早)默認使用V2 API。
注意使用V2 API所創建的任何Key不能夠通過V3 API進行訪問。而V3 API etcdctl get
獲取V2 的Key將返回0並退出,這是預料之中的情況。
export ETCDCTL_API=3
發現版本
使用合適的命令在執行不同版本的etcd時etcdctl和服務器API的版本將會有用。
這里的命令可用於發現版本信息:
$ etcdctl version
etcdctl version:3.1.0-alpha.0+git
API version:3.1
寫入一個KEY
應用程序通過向etcd集群寫入Keys來存儲Keys,每次存儲的Key將會通過Raft協議實現一致性與可擴展性復制到所有的etcd集群成員中。
這里的命令是將Keyfoo
的值存儲到bar
上:
$ etcdctl put foo bar
OK
給Key附上一個租約,Key將在一個具體的時間間隔被設置。
這里的命令是在10秒后將Keyfoo
的值存儲到bar
上:
$ etcdctl put foo1 bar1 --lease=1234abcd
注意:以上命令中租約ID為1234abcd將會在租約創建10秒后將id返回,這個id將附在Key上。
讀取Keys
應用程序可以從一個etcd集群中讀取Key,可能會查詢到單個Key,或者是一個范圍內的Key。
比如etcd集群中存儲以下Key:
foo = bar
foo1 = bar1
foo2 = bar2
foo3 = bar3
這里的命令是讀取Keyfoo
對應的值:
$ etcdctl get foo
foo
bar
這里的命令是讀取Keyfoo
對應的十六進制的值:
$ etcdctl get foo --hex
\x66\x6f\x6f #Key
\x62\x61\x72 #Value
這里的命令是只讀取Keyfoo
對應的值:
$ etcdctl get foo --print-value-only
bar
這里的命令是讀取從Keyfoo
到Keyfoo3
范圍內對應的值:
$ etcdctl get foo foo3
foo
bar
foo1
bar1
foo2
bar2
注意這里Key為foo3
不包括在內因為這里的范圍是半開區間[foo,foo3)
,不包括foo3
。
這里的命令是獲取前綴為foo
的Key的范圍內所有的值:
$ etcdctl get --prefix foo
foo
bar
foo1
bar1
foo2
bar2
foo3
bar3
這里的命令是獲取前綴為foo
的Key的范圍內所有的值,並且限制結果集為2:
$ etcdctl get --prefix --limit=2 foo
foo
bar
foo1
bar1
讀取之前版本的Keys:
應用程度可能希望讀取一個被替代的版本的Key。例如,一個應用程序可能想要通過讀取一個先前版本的Key來回滾到一個老的配置。另外,一個應用程序可能想要通過訪問Key的歷史記錄對多個Key通過多個請求獲取一致性的結果。由於對etcd集群中鍵值對的每一次修改都會增加對在etcd集群中的全局修訂存儲,應用程序可以通過提供一個老的版本來讀取被替代的Keys。
比如一個etcd集群中存在以下的Keys:
foo = bar # revision = 2
foo1 = bar1 # revision = 3
foo = bar_new # revision = 4
foo1 = bar1_new # revision = 5
這里的例子是訪問過去版本的Keys:
$ etcdctl get --prefix foo # access the most recent versions of keys
foo
bar_new
foo1
bar1_new
$ etcdctl get --prefix --rev=4 foo # access the versions of keys at revision 4
foo
bar_new
foo1
bar1
$ etcdctl get --prefix --rev=3 foo # access the versions of keys at revision 3
foo
bar
foo1
bar1
$ etcdctl get --prefix --rev=2 foo # access the versions of keys at revision 2
foo
bar
$ etcdctl get --prefix --rev=1 foo # access the versions of keys at revision 1
讀取大於或等於一個具體的Key的比特值的Key:
應用程序可能想要讀取大於或等於一個具體的Key的byte值的Key。
一個etcd集群中有以下的Keys:
a = 123
b = 456
z = 789
這里的命令是讀取大於或等於Key b
的byte值的Key:
$ etcdctl get --from-key b
b
456
z
789
刪除 Keys
應用程序可以從etcd集群中刪除一個Key或者刪除一個范圍內的Key:
一個etcd集群中有以下的Keys:
foo = bar
foo1 = bar1
foo3 = bar3
zoo = val
zoo1 = val1
zoo2 = val2
a = 123
b = 456
z = 789
這里的命令是刪除Keyfoo
:
$ etcdctl del foo
1 # 1 個 key 被刪除
這里的命令是刪除從Keyfoo
到Keyfoo9
范圍內的Key:
$ etcdctl del foo foo9
2 # 2 個 keys 被刪除
這里的命令是刪除Keyzoo
並將已刪除的鍵值對返回:
$ etcdctl del --prev-kv zoo
1 # 1 個 key 被刪除
zoo # 被刪除的Key
val # 被刪除的Key所對應的Value
這里的命令是刪除前綴為zoo
的Keys:
$ etcdctl del --prefix zoo
2 # 2 個 key 被刪除
這里的命令是讀取大於或等於Key b
的byte值的Keys:
$ etcdctl del --from-key b
2 # 2 個 key 被刪除
觀察key的變化
應用程序可以監視一個Key或者一個范圍內的Keys的每一次更新。
這里的命令是觀察keyfoo
:
$ etcdctl watch foo
# 在另一個終端執行: etcdctl put foo bar
PUT
foo
bar
這里的命令是觀察十六進制的keyfoo
:
$ etcdctl watch foo --hex
# 在另一個終端執行: etcdctl put foo bar
PUT
\x66\x6f\x6f # Key
\x62\x61\x72 # Value
這里的命令是觀察從Keyfoo
到Keyfoo9
范圍內的Key:
$ etcdctl watch foo foo9
# 在另一個終端執行: etcdctl put foo bar
PUT
foo
bar
# 在另一個終端執行: etcdctl put foo1 bar1
PUT
foo1
bar1
這里的命令是觀察前綴為foo
的Key的范圍內所有的值:
$ etcdctl watch --prefix foo
# 在另一個終端執行: etcdctl put foo bar
PUT
foo
bar
# 在另一個終端執行: etcdctl put fooz1 barz1
PUT
fooz1
barz1
這里的命令是觀察多個Keysfoo
和zoo
:
$ etcdctl watch -i
$ watch foo
$ watch zoo
# 在另一個終端執行: etcdctl put foo bar
PUT
foo
bar
# 在另一個終端執行: etcdctl put zoo val
PUT
zoo
val
觀察Keys的歷史版本
應用程序可能想要觀察etcd中Keys的更新歷史。例如,應用程序可能想獲取key的所有修改;如果應用程序保持與etcd的連接,那么命令watch
已經足夠。然而,如果應用程序或者etcd宕機,一次更新可能就會失敗,應用程序可能不能實時接收Key的更新。為了保證更新可以被交付,應用程序必須通過觀察到Keys的歷史更新。為了做到這些,應用程序要指定觀察的歷史版本,就像讀取歷史版本的Keys:
我們首先完成以下操作:
$ etcdctl put foo bar # revision = 2
OK
$ etcdctl put foo1 bar1 # revision = 3
OK
$ etcdctl put foo bar_new # revision = 4
OK
$ etcdctl put foo1 bar1_new # revision = 5
OK
這里有個例子觀察歷史更新:
# watch for changes on key `foo` since revision 2
$ etcdctl watch --rev=2 foo
PUT
foo
bar
PUT
foo
bar_new
# watch for changes on key `foo` since revision 3
$ etcdctl watch --rev=3 foo
PUT
foo
bar_new
這里有例子只觀察最后一次的更新:
# watch for changes on key `foo` and return last revision value along with modified value
$ etcdctl watch --prev-kv foo
# 在另一個終端執行 etcdctl put foo bar_latest
PUT
foo # key
bar_new # last value of foo key before modification
foo # key
bar_latest # value of foo key after modification
觀察進度
應用程序可能想要檢查觀察者進度以確定最新的觀察者流的狀態。例如,如果觀察者更新的緩存,那么就可以通過原子讀取與修改進度進行比較知道緩存內容是否已經過時。
進度請求可以通過progress
命令與觀察者session進行交互在一個觀察者流中告訴服務器發送一個進度提示更新.
$ etcdctl watch -i
$ watch a
$ progress
progress notify: 1
# 在另一個終端執行: etcdctl put x 0
# 在另一個終端執行: etcdctl put y 1
$ progress
progress notify: 3
注意,在進度提示響應中的修改號來自觀察者流連接到的本地etcd服務器。如果該節點被分區並且不是該分區的一部分,這個進度提示修改版本可能會低於由未分區的etcd服務器節點返回的修改版本。
壓縮修改
正如我們提到的,etcd保持修改信息所以應用可以讀取過去版本的Keys,然而,為了避免無數的修改歷史累積,對過去的修改進行壓縮是很重要的。在壓縮后,etcd移除了歷史修改,釋放資源為以后使用。在壓縮修改版本之前所有的被修改的替代版本數據將不能獲取。
這里的命令是對修改進行壓縮:
$ etcdctl compact 5
compacted revision 5
# any revisions before the compacted one are not accessible
$ etcdctl get --rev=4 foo
Error: rpc error: code = 11 desc = etcdserver: mvcc: required revision has been compacted
注意:etcd服務器的當前版本可以使用json格式的命令通過(存在或不存在的)key發現。例如下面的通過查看在etcd服務器中不存在的myKey:
$ etcdctl get mykey -w=json
{"header":{"cluster_id":14841639068965178418,"member_id":10276657743932975437,"revision":15,"raft_term":4}}
授予租約
應用程序可以為etcd集群上的Keys授予一個租約。當Key附上租約后,它的生命周期會綁定到租約的生命周期並由存活時間(TTL)進行管理。每一個租約都有一個由應用程序授予的最小的TTL值.這個租約實際的TTL值至少是最小的TTL值,由etcd集群決定。一旦超過租約的TTL,租約將會超時並刪除附上的所有的Keys。
這里有命令授予一個租約:
# grant a lease with 60 second TTL
$ etcdctl lease grant 60
lease 32695410dcc0ca06 granted with TTL(60s)
# attach key foo to lease 32695410dcc0ca06
$ etcdctl put --lease=32695410dcc0ca06 foo bar
OK
撤銷租約
應用程序可以根據租約ID撤銷租約,撤銷一個租約將刪除附上的所有的Keys。
例如我們完成下面的操作:
$ etcdctl lease grant 60
lease 32695410dcc0ca06 granted with TTL(60s)
$ etcdctl put --lease=32695410dcc0ca06 foo bar
OK
這里的命令可以撤銷該租約:
$ etcdctl lease revoke 32695410dcc0ca06
lease 32695410dcc0ca06 revoked
$ etcdctl get foo
# empty response since foo is deleted due to lease revocation
保持租約存活
應用程序可以通過刷新租約的TTL使它不會超時保證租約存活。
例如我們完成下面的操作:
$ etcdctl lease grant 60
lease 32695410dcc0ca06 granted with TTL(60s)
這里有命令保持租約存活:
$ etcdctl lease keep-alive 32695410dcc0ca06
lease 32695410dcc0ca06 keepalived with TTL(60)
lease 32695410dcc0ca06 keepalived with TTL(60)
lease 32695410dcc0ca06 keepalived with TTL(60)
...
獲取租約信息
應用程序可能想知道關於租約的信息,所以可以通過重新創建或者檢查租約是否仍然生存或已經超時。應用程序可能也想知道一個具體的租約上所附的Key。
例如我們完成下面的操作:
# grant a lease with 500 second TTL
$ etcdctl lease grant 500
lease 694d5765fc71500b granted with TTL(500s)
# attach key zoo1 to lease 694d5765fc71500b
$ etcdctl put zoo1 val1 --lease=694d5765fc71500b
OK
# attach key zoo2 to lease 694d5765fc71500b
$ etcdctl put zoo2 val2 --lease=694d5765fc71500b
OK
這里有命令獲取關於租約的信息:
$ etcdctl lease timetolive 694d5765fc71500b
lease 694d5765fc71500b granted with TTL(500s), remaining(258s)
這里有命令獲取租約上所依附的關於Keys的信息:
$ etcdctl lease timetolive --keys 694d5765fc71500b
lease 694d5765fc71500b granted with TTL(500s), remaining(132s), attached keys([zoo2 zoo1])
# if the lease has expired or does not exist it will give the below response:
Error: etcdserver: requested lease not found