1、etcd API
etcdctl
用于与etcd
交互的控制台程序。API
版本可以通过ETCDCTL_API
环境变量设置为2或3版本。默认情况
下,v3.4
以上的etcdctl
使用v3 API
,v3.3
及更早的版本默认使用v2 API
。
注意:用
v2 API
创建的任何key将不能通过v3 API
查询。同样,用v3 API
创建的任何key将不能通过
v2 API
查询。
1.1 启动服务
输入命令etcd
,即可启动一个单节点的etcd服务,ctrl+c
即可停止服务。
运行etcd
,在终端输入etcd
。
[root@zsx ~]# etcd
{"level":"info","ts":"2023-02-13T13:39:49.847+0800","caller":"etcdmain/etcd.go:73","msg":"Running: ","args":["etcd"]}
{"level":"warn","ts":"2023-02-13T13:39:49.847+0800","caller":"etcdmain/etcd.go:105","msg":"'data-dir' was empty; using default","data-dir":"default.etcd"}
{"level":"info","ts":"2023-02-13T13:39:49.848+0800","caller":"embed/etcd.go:124","msg":"configuring peer listeners","listen-peer-urls":["http://localhost:2380"]}
{"level":"info","ts":"2023-02-13T13:39:49.850+0800","caller":"embed/etcd.go:132","msg":"configuring client listeners","listen-client-urls":["http://localhost:2379"]}
{"level":"info","ts":"2023-02-13T13:39:49.850+0800","caller":"embed/etcd.go:306","msg":"starting an etcd server","etcd-version":"3.5.5","git-sha":"19002cfc6","go-version":"go1.16.15","go-os":"linux","go-arch":"amd64","max-cpu-set":1,"max-cpu-available":1,"member-initialized":false,"name":"default","data-dir":"default.etcd","wal-dir":"","wal-dir-dedicated":"","member-dir":"default.etcd/member","force-new-cluster":false,"heartbeat-interval":"100ms","election-timeout":"1s","initial-election-tick-advance":true,"snapshot-count":100000,"snapshot-catchup-entries":5000,"initial-advertise-peer-urls":["http://localhost:2380"],"listen-peer-urls":["http://localhost:2380"],"advertise-client-urls":["http://localhost:2379"],"listen-client-urls":["http://localhost:2379"],"listen-metrics-urls":[],"cors":["*"],"host-whitelist":["*"],"initial-cluster":"default=http://localhost:2380","initial-cluster-state":"new","initial-cluster-token":"etcd-cluster","quota-backend-bytes":2147483648,"max-request-bytes":1572864,"max-concurrent-streams":4294967295,"pre-vote":true,"initial-corrupt-check":false,"corrupt-check-time-interval":"0s","compact-check-time-enabled":false,"compact-check-time-interval":"1m0s","auto-compaction-mode":"periodic","auto-compaction-retention":"0s","auto-compaction-interval":"0s","discovery-url":"","discovery-proxy":"","downgrade-check-interval":"5s"}
{"level":"info","ts":"2023-02-13T13:39:49.852+0800","caller":"etcdserver/backend.go:81","msg":"opened backend db","path":"default.etcd/member/snap/db","took":"716.361µs"}
......
{"level":"info","ts":"2023-02-13T13:39:50.557+0800","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"8e9e05c52164694d became leader at term 2"}
{"level":"info","ts":"2023-02-13T13:39:50.557+0800","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"raft.node: 8e9e05c52164694d elected leader 8e9e05c52164694d at term 2"}
......
-
"name":"default"
:name表示节点名称,默认为default。 -
"data-dir":"default.etcd"
:data-dir 保存日志和快照的目录,默认为当前工作目录default.etcd/目录下。
-
在
http://localhost:2380
和集群中其他节点通信。 -
在
http://localhost:2379
提供客户端交互。 -
"heartbeat-interval":"100ms"
:heartbeat-interval为100ms,该参数的作用是leader多久发送一次心跳到followers,默认值是100ms。
-
"election-timeout":"1s"
:election-timeout为1000ms,该参数的作用是重新投票的超时时间,如果follow在该时间间隔没有收到心跳包,会触发重新投票,默认为1000ms。
-
"snapshot-count":100000
:snapshot-count为10000,该参数的作用是指定有多少事务被提交时,触发截取快照保存到磁盘。
-
集群和每个节点都会生成一个
uuid
。 -
启动的时候会运行raft,选举出leader。
1.2 查看客户端版本
在另一个终端运行etcdctl version
测试。
# 查看默认API版本
[root@zsx ~]# etcdctl version
etcdctl version: 3.5.5
API version: 3.5
1.3 查看帮助文档
[root@zsx ~]# etcdctl -h
etcdctl是一个命令行客户端,可以对etcd服务进行测试或者手动修改数据库内容。另外,etcdctl还支持HTTP
API。 etcdctl支持的命令大体上分为数据库操作和非数据库操作两类。
1.4 写入key
# 写入key
# --sort对结果进行排序
# --consistent将请求发给主节点,保证获取内容的一致性
# etcdctl put /test/foo hello etcd(双引号可去掉)
$ etcdctl put /test/foo "hello etcd"
OK
$ etcdctl get /test/foo
/test/foo
hello etcd
# 手动切换到v2 API
# set ETCDCTL_API=2
$ export ETCDCTL_API=2
$ etcdctl --version
etcdctl version: 3.5.5
API version: 2
# 查询不到/test/foo的值
$ etcdctl get /test/foo
Error: client: response is invalid json. The endpoint is probably not valid etcd cluster endpoint
1.5 读取key值
$ etcdctl get /test/foo
/test/foo
hello etcd
# 只是获取值
$ etcdctl get /test/foo --print-value-only
hello etcd
# 获取从foo1到foo3的值,不包括foo3
$ etcdctl put foo1 bar1
$ etcdctl put foo2 bar2
$ etcdctl put foo3 bar3
$ etcdctl get foo1 foo3 --print-value-only
bar1
bar2
# 获取前缀为foo的值
$ etcdctl get --prefix foo --print-value-only
bar1
bar2
bar3
# 获取符合前缀的前两个值
$ etcdctl get --prefix --limit=2 foo --print-value-only
bar1
bar2
1.6 删除key
# 删除foo1
$ etcdctl del foo1
1
# 删除foo2到foo3,不包括foo3
$ etcdctl del foo2 foo3
1
# 删除key前缀为foo的
# 返回值是删除的个数
$ etcdctl del --prefix foo
1
1.7 监视值变化
# 监视foo单个key
$ etcdctl watch foo
# 另一个控制台执行
$ etcdctl put foo bar
OK
# 第一个控制台输出
PUT
foo
bar
# 同时监视多个值
$ etcdctl watch -i
$ watch foo
$ watch zoo
# 另一个控制台执行
$ etcdctl put foo bar
OK
# 另一个控制台执行
$ etcdctl put zoo val
OK
# 第一个控制台输出
PUT
foo
bar
PUT
zoo
val
# 监视foo前缀的key
$ etcdctl watch --prefix foo
# 另一个控制台执行
$ etcdctl put foo1 bar1
OK
# 另一个控制台执行
$ etcdctl put fooz1 barz1
OK
# 第一个控制台输出
PUT
foo1
bar1
PUT
fooz1
barz1
1.8 设置租约(Grant leases)
当一个key
被绑定到一个租约上时,它的生命周期与租约的生命周期绑定。
# 设置60秒后过期时间
# lease grant为命令参数
$ etcdctl lease grant 60
lease 32695410dcc0ca06 granted with TTL(60s)
# 把foo和租约绑定,设置成60秒后过期
$ etcdctl put --lease=32695410dcc0ca06 foo bar
OK
$ etcdctl get foo
foo
bar
# 60秒后,获取不到foo
$ etcdctl get foo
# 返回空
1.9 主动撤销租约(Revoke leases)
通过租赁ID(此处指:32695410dcc0ca06
)撤销租约。撤销租约将删除其所有绑定的key
。
$ etcdctl lease grant 60
lease 32695410dcc0ca06 granted with TTL(60s)
$ etcdctl put foo bar --lease=32695410dcc0ca06
OK
# 主动撤销租约
$ etcdctl lease revoke 32695410dcc0ca06
lease 32695410dcc0ca06 revoked
$ etcdctl get foo
# 返回空
1.10 续租约(Keep leases alive)
通过刷新其TTL
来保持租约的有效,使其不会过期。
# 设置60秒后过期租约
$ etcdctl lease grant 60
lease 32695410dcc0ca06 granted with TTL(60s)
# 把foo和租约绑定,设置成60秒后过期
$ etcdctl put foo bar --lease=32695410dcc0ca06
# 续租约,自动定时执行续租约,续约成功后每次租约为60秒
$ etcdctl lease keep-alive 32695410dcc0ca06
lease 32695410dcc0ca06 keepalived with TTL(60)
lease 32695410dcc0ca06 keepalived with TTL(60)
lease 32695410dcc0ca06 keepalived with TTL(60)
...
1.11 获取租约信息(Get lease information)
获取租约信息,以便续租或查看租约是否仍然存在或已过期
# 设置500秒TTL
$ etcdctl lease grant 500
lease 694d5765fc71500b granted with TTL(500s)
# keyzoo1绑定694d5765fc71500b租约
$ etcdctl put zoo1 val1 --lease=694d5765fc71500b
OK
# 查看租约信息,remaining(132s)剩余有效时间132秒;--keys获取租约绑定的key
$ etcdctl lease timetolive --keys 694d5765fc71500b
lease 694d5765fc71500b granted with TTL(500s), remaining(132s), attached keys([zoo1])
值得注意的地方,一个租约可以绑定多个key
$ etcdctl lease grant 500
lease 694d5765fc71500b granted with TTL(500s)
$ etcdctl put zoo1 val1 --lease=694d5765fc71500b
OK
$ etcdctl put zoo2 val2 --lease=694d5765fc71500b
OK
当租约过期后,所有key值会被删除。
当一个租约只绑定了一个key
时,想删除这个key
,最好的办法是撤销它的租约,而不是直接删除这个key
。
# 方法一: 直接删除key
# 设置租约并绑定zoo1
$ etcdctl lease grant 60
lease 694d71f80ed8bf1e granted with TTL(60s)
$ etcdctl put zoo1 val1 --lease=694d71f80ed8bf1e
OK
# 续租约
$ etcdctl lease keep-alive 694d71f80ed8bf1e
lease 694d71f80ed8bf1e keepalived with TTL(60)
# 另一个控制台执行
$ etcdctl del zoo1
# 单纯删除key后,续约操作还会一直进行,造成内存泄露
lease 694d71f80ed8bf1e keepalived with TTL(60)
lease 694d71f80ed8bf1e keepalived with TTL(60)
lease 694d71f80ed8bf1e keepalived with TTL(60)
...
# 方法二: 撤销key的租约
# 设置租约并绑定zoo1
$ etcdctl lease grant 60
lease 694d71f80ed8bf1e granted with TTL(60s)
$ etcdctl put zoo1 val1 --lease=694d71f80ed8bf1e
OK
# 续租约
$ etcdctl lease keep-alive 694d71f80ed8bf1e
lease 694d71f80ed8bf1e keepalived with TTL(60)
lease 694d71f80ed8bf1e keepalived with TTL(60)
#另一个控制台执行
$ etcdctl lease revoke 694d71f80ed8bf1e
# 续约操作并退出
lease 694d71f80ed8bf1e expired or revoked.
当租约没有绑定key时,应主动把它撤销掉。