jinzh notes
jinzh notes

etcd学习记录

etcd学习记录
内容纲要

简介

etcd是开源的、高可用的分布式key-value存储系统,可用于配置共享和服务的注册和发现,它专注于:

  • 完全复制:集群中的每个节点都可以使用完整的存档
  • 高可用性:Etcd可用于避免硬件的单点故障或网络问题
  • 一致性:每次读取都会返回跨多主机的最新写入
  • 简单:包括一个定义良好、面向用户的API(gRPC)
  • 安全:实现了带有可选的客户端证书身份验证的自动化TLS
  • 快速:每秒10000次写入的基准速度
  • 可靠:使用Raft算法实现了强一致、高可用的服务存储目录

etcd 是一个高度一致的分布式键值存储,它提供了一种可靠的方式来存储需要由分布式系统或机器集群访问的数据。它可以优雅地处理网络分区期间的领导者选举,即使在领导者节点中也可以容忍机器故障。

etcd特性

应用场景

  1. 服务注册与发现
  2. 配置中心
  3. 分布式锁
https://jinzh.me/wp-content/uploads/2022/03/pexels-aleksandar-pasaric-325185.jpg

etcdctl

官方提供的etcd的命令行工具

主要支持的命令有写入、读取、历史查询、删除、观察、压缩、租约操作(也就是相当于存活时间)等

查看版本号

$ etcdctl version
etcdctl version: 3.3.3
API version: 3.3

写入

$ etcdctl put foo bar
OK

读取

读取单个键

etcdctl get foo

以16进制格式读取键

$ etcdctl get foo --hex
\x66\x6f\x6f          # 键
\x62\x61\x72          # 值

只获取值

$ etcdctl get foo --print-value-only
bar

范围查询

注意:查询的是左闭右开区间,也就是说,一下命令查询到的是foo-foo2,不包含foo3的值

$ etcdctl get foo foo3
foo
bar
foo1
bar1
foo2
bar2

前缀查询

$ etcdctl get --prefix foo
foo
bar
foo1
bar1
foo2
bar2
foo3
bar3

限定数量查询

一下指令也进行了前缀查询

$ etcdctl get --prefix --limit=2 foo
foo
bar
foo1
bar1

历史查询

有时会有需求需要查询得到历史版本,etcd 的修改有些类似commit, etcd 集群上键值存储的每个修改都会增加 etcd 集群的全局修订版本,应用可以通过提供旧有的 etcd 修改版本来读取被替代的键

etcd的历史记录版本更类似于是数据库的自增id,进行一次put或者是del等操作,就会递增一次记录版本号,因此可以根据版本号查询当时全局的数据

假设 etcd 已经存在以下键

foo = bar         # revision = 2
foo1 = bar1       # revision = 3
foo = bar_new     # revision = 4
foo1 = bar1_new   # revision = 5

观察历史改动

# 从修订版本 2 开始观察键 `foo` 的改动
$ etcdctl watch --rev=2 foo
PUT
foo
bar
PUT
foo
bar_new
# 从修订版本 3 开始观察键 `foo` 的改动
$ etcdctl watch --rev=3 foo
PUT
foo
bar_new

观察变更时同时返回修改之前的值

# 在键 `foo` 上观察变更并返回被修改的值和上个修订版本的值
$ etcdctl watch --prev-kv foo
# 在另外一个终端: etcdctl put foo bar_latest
PUT
foo         # 键
bar_new     # 在修改前键foo的上一个值
foo         # 键
bar_latest  # 修改后键foo的值

压缩

如我们提到的,etcd 保存修订版本以便应用可以读取键的过往版本。但是,为了避免积累无限数量的历史数据,压缩过往的修订版本就变得很重要。压缩之后,etcd 删除历史修订版本,释放资源来提供未来使用。所有修订版本在压缩修订版本之前的被替代的数据将不可访问。

压缩修订版本

$ etcdctl compact 5
compacted revision 5

# 在压缩修订版本之前的任何修订版本都不可访问
$ etcdctl get --rev=4 foo
Error:  rpc error: code = 11 desc = etcdserver: mvcc: required revision has been compacted

注意: etcd 服务器的当前修订版本可以在任何键(存在或者不存在)以json格式使用get命令来找到。下面展示的例子中 mykey 是在 etcd 服务器中不存在的:

$ etcdctl get mykey -w=json
{"header":{"cluster_id":14841639068965178418,"member_id":10276657743932975437,"revision":15,"raft_term":4}}

授予租约

应用可以为 etcd 集群里面的键授予租约。当键被附加到租约时,它的存活时间被绑定到租约的存活时间,而租约的存活时间相应的被 time-to-live (TTL)管理。在租约授予时每个租约的最小TTL值由应用指定。租约的实际 TTL 值是不低于最小 TTL,由 etcd 集群选择。一旦租约的 TTL 到期,租约就过期并且所有附带的键都将被删除。

授予租约

# 授予租约,TTL为10秒
$ etcdctl lease grant 10
lease 32695410dcc0ca06 granted with TTL(10s)

# 附加键 foo 到租约32695410dcc0ca06
$ etcdctl put --lease=32695410dcc0ca06 foo bar
OK

撤销租约

应用通过租约 id 可以撤销租约。撤销租约将删除所有它附带的 key。

$ etcdctl lease revoke 32695410dcc0ca06
lease 32695410dcc0ca06 revoked

$ etcdctl get foo
# 空应答,因为租约撤销导致foo被删除

维持租约

应用可以通过刷新键的 TTL 来维持租约,以便租约不过期。

$ etcdctl lease keep-alive 32695410dcc0ca06
lease 32695410dcc0ca06 keepalived with TTL(10)
lease 32695410dcc0ca06 keepalived with TTL(10)
lease 32695410dcc0ca06 keepalived with TTL(10)
...

获取租约信息

应用程序可能想知道租约信息,以便可以更新或检查租约是否仍然存在或已过期。应用程序也可能想知道有那些键附加到了特定租约。

假设我们完成了下列操作序列:

# 授予租约,TTL为500秒
$ etcdctl lease grant 500
lease 694d5765fc71500b granted with TTL(500s)

# 将键 zoo1 附加到租约 694d5765fc71500b
$ etcdctl put zoo1 val1 --lease=694d5765fc71500b
OK

# 将键 zoo2 附加到租约 694d5765fc71500b
$ etcdctl put zoo2 val2 --lease=694d5765fc71500b
OK

获取租约信息

$ etcdctl lease timetolive 694d5765fc71500b
lease 694d5765fc71500b granted with TTL(500s), remaining(258s)

获取租约信息和租约附带的键

$ etcdctl lease timetolive --keys 694d5765fc71500b
lease 694d5765fc71500b granted with TTL(500s), remaining(132s), attached keys([zoo2 zoo1])

# 如果租约已经过期或者不存在,它将给出下面的应答:
lease 694d5765fc71500b already expired

影翼

文章作者

发表回复

textsms
account_circle
email

jinzh notes

etcd学习记录
简介 etcd是开源的、高可用的分布式key-value存储系统,可用于配置共享和服务的注册和发现,它专注于: 完全复制:集群中的每个节点都可以使用完整的存档 高可用性:Etcd可用于避免硬件…
扫描二维码继续阅读
2022-03-27