Skip to content

1. 概述

这是一个序列总结文档。

1.1 VirtualBox虚拟机信息记录

学习etcd时,使用以下几个虚拟机:

序号虚拟机主机名IPCPU内存说明
1ansible-masteransible192.168.56.1202核4GAnsible控制节点
2ansible-node1etcd-node1192.168.56.1212核2GAnsible工作节点1
3ansible-node2etcd-node2192.168.56.1222核2GAnsible工作节点2
4ansible-node3etcd-node3192.168.56.1232核2GAnsible工作节点3

后面会编写使用ansible部署etcd集群的剧本。

操作系统说明:

sh
[root@etcd-node1 ~]# cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)
[root@etcd-node1 ~]# hostname -I
192.168.56.121 10.0.3.15
[root@etcd-node1 ~]#

1.2 回顾历史

在第5节 etcd角色权限控制 中设置了一些快捷命令,如下所示:

sh
# ETCD相关快捷命令
alias etcdctl='etcdctl --endpoints=$ENDPOINTS --cacert=/etc/etcd/ssl/ca.crt --cert=/etc/etcd/ssl/client.crt --key=/etc/etcd/ssl/client.key'
alias rootetcdctl='etcdctl --user root --password securePassword'
# 查看etcd集群成员信息
alias ecm='etcdClusterMember'
alias etcdClusterMember='rootetcdctl --write-out=table member list'
# 查看etcd集群状态信息
alias ecs='etcdClusterStatus'
alias etcdClusterStatus='rootetcdctl --write-out=table endpoint status'
# 查看etcd集群健康状态
alias ech='etcdClusterHealth'
alias etcdClusterHealth='rootetcdctl --write-out=table endpoint health'

之前参考第7节 etcd配置文件, 通过etcd配置文件来配置相关参数,然后启动etcd服务。

在三个节点上面使用start_by_config.sh启动etcd服务。

sh
[root@etcd-node1 ~]# cd /srv/etcd/node
[root@etcd-node1 node]# ls
config     logs       openssl.conf       start_by_config.sh  start.sh
data.etcd  nohup.out  start_auto_ssl.sh  start_no_ssl.sh     stop.sh
[root@etcd-node1 node]# ./start_by_config.sh 
[root@etcd-node1 node]# nohup: appending output to ‘nohup.out’

[root@etcd-node1 node]#

启动后,查看etcd集群状态:

sh
[root@etcd-node1 ~]# ech
+-----------------------------+--------+------------+-------+
|          ENDPOINT           | HEALTH |    TOOK    | ERROR |
+-----------------------------+--------+------------+-------+
| https://192.168.56.121:2379 |   true | 1.226138ms |       |
| https://192.168.56.123:2379 |   true | 1.153493ms |       |
| https://192.168.56.122:2379 |   true |  753.212µs |       |
+-----------------------------+--------+------------+-------+
[root@etcd-node1 ~]# ecm
+------------------+---------+-------+-----------------------------+-----------------------------+------------+
|        ID        | STATUS  | NAME  |         PEER ADDRS          |        CLIENT ADDRS         | IS LEARNER |
+------------------+---------+-------+-----------------------------+-----------------------------+------------+
| a7d7b09bf04ad21b | started | node3 | https://192.168.56.123:2380 | https://192.168.56.123:2379 |      false |
| d553b4da699c7263 | started | node2 | https://192.168.56.122:2380 | https://192.168.56.122:2379 |      false |
| e14cb1abc9daea5b | started | node1 | https://192.168.56.121:2380 | https://192.168.56.121:2379 |      false |
+------------------+---------+-------+-----------------------------+-----------------------------+------------+
[root@etcd-node1 ~]# ecs
+-----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|          ENDPOINT           |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+-----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| https://192.168.56.121:2379 | e14cb1abc9daea5b |  3.5.18 |   25 kB |     false |      false |        23 |        974 |                974 |        |
| https://192.168.56.122:2379 | d553b4da699c7263 |  3.5.18 |   25 kB |      true |      false |        23 |        975 |                975 |        |
| https://192.168.56.123:2379 | a7d7b09bf04ad21b |  3.5.18 |   25 kB |     false |      false |        23 |        976 |                976 |        |
+-----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
[root@etcd-node1 ~]#

1.3 现象说明

使用etcd-workbench可以查看键的历史版本对比,如新建一个timekey键,初始值为当前时间2025年6月15日11:33:01,然后过一会儿再修改该键的值为2025年6月15日11:38:31,此时点击键右上角的“Version Diff”查看版本差异:

Snipaste_2025-06-15_11-39-20.png

可以看到,正常显示了两个版本间的差异了!

而对于历史的键config,我们尝试查看版本差异,却提示 No multiple versions, required revision has been compacted异常:

Snipaste_2025-06-15_11-42-17.png

即该键没有多个版本,需要查看的版本已经被压缩了!!!

为什么会出现这种不同的现象呢,以下就来分析说明etcd的压缩机制。

2. etcd压缩机制

我们在etcd的配置文件中可以看到以下两行内容:

yaml
auto-compaction-mode: periodic
auto-compaction-retention: "1"
  • 在 etcd 配置中,auto-compaction-retention: 1auto-compaction-mode: periodic 组合起来定义了 etcd 的自动压缩行为,用于控制历史数据的保留策略。

这种情况是1小时前的版本会被清理掉:

Snipaste_2025-06-17_22-33-24.png

在etcd官方文档中 https://etcd.io/docs/v3.5/op-guide/configuration/,有关于这两个配置的说明:

sh
--auto-compaction-retention '0'
  Auto compaction retention length. 0 means disable auto compaction.
--auto-compaction-mode 'periodic'
  Interpret 'auto-compaction-retention' one of: periodic|revision. 'periodic' for duration based retention, defaulting to hours if no time unit is provided (e.g. '5m'). 'revision' for revision number based retention.

2.1 压缩模式

  • auto-compaction-mode用于定义压缩模式,可选值有两个,一个是periodic,另一个是revision
  • periodic表示周期性的,即这种模式是 周期性时间间隔压缩模式
  • revision表示版本,即这种模式是 版本号数量间隔压缩模式

2.1.1 周期性时间间隔压缩模式

  • 当配置auto-compaction-mode: periodic时,表示使用周期性时间间隔压缩模式。
  • 此时,如果auto-compaction-retention的值未配置单位的话,则默认使用hour小时作为时间单位。
  • 也可以使用5m之类的,表示5分钟时间间隔。

2.1.2 周期性时间间隔压缩单位说明

auto-compaction-retention 参数支持以下时间单位:

单位符号含义示例值实际保留时长
h小时"1h"保留最近 1 小时
m分钟"30m"保留最近 30 分钟
无单位小时 (默认)"1"保留最近 1 小时

生产环境建设配置:

yaml
# 周期性时间间隔压缩模式
auto-compaction-mode: periodic
# 保留 24 小时历史数据
auto-compaction-retention: "24h"

测试环境可以配置成5分钟或15分钟:

yaml
# 周期性时间间隔压缩模式
auto-compaction-mode: periodic
# 保留 15 分钟历史数据
auto-compaction-retention: "15m"

2.1.3 手动压缩

由于我有时将虚拟机关机了,再次启动虚拟机时,仍然可以看到之前的版本对比差异。

Snipaste_2025-06-15_11-39-20.png

因此,我们现在来尝试进行一次强制压缩。

sh
# 手动执行压缩 (使用当前索引)
NOW_REV=$(etcdctl endpoint status -w json | jq '.[].Status..header.revision'|uniq)
etcdctl compact $NOW_REV

执行命令:

sh
[root@etcd-node1 ~]# rootetcdctl endpoint status -w json|jq .[].Status
{
  "header": {
    "cluster_id": 11928626832149064000,
    "member_id": 16234546108147886000,
    "revision": 38,
    "raft_term": 35
  },
  "version": "3.5.18",
  "dbSize": 24576,
  "leader": 16234546108147886000,
  "raftIndex": 1602,
  "raftTerm": 35,
  "raftAppliedIndex": 1602,
  "dbSizeInUse": 16384
}
{
  "header": {
    "cluster_id": 11928626832149064000,
    "member_id": 15371828803313365000,
    "revision": 38,
    "raft_term": 35
  },
  "version": "3.5.18",
  "dbSize": 24576,
  "leader": 16234546108147886000,
  "raftIndex": 1603,
  "raftTerm": 35,
  "raftAppliedIndex": 1603,
  "dbSizeInUse": 16384
}
{
  "header": {
    "cluster_id": 11928626832149064000,
    "member_id": 12094329508124610000,
    "revision": 38,
    "raft_term": 35
  },
  "version": "3.5.18",
  "dbSize": 24576,
  "leader": 16234546108147886000,
  "raftIndex": 1604,
  "raftTerm": 35,
  "raftAppliedIndex": 1604,
  "dbSizeInUse": 16384
}
[root@etcd-node1 ~]#

可以看到当前最新版本是38。

sh
[root@etcd-node1 ~]# rootetcdctl endpoint status -w json|jq .[].Status.header.revision|uniq
38
[root@etcd-node1 ~]# rootetcdctl compact 38
compacted revision 38
[root@etcd-node1 ~]#

此时,再查看timekey的差异对比,可以看到已经没有了。

Snipaste_2025-06-21_20-57-18.png

2.1.4 测试周期性自动压缩

为了便于观察周期性自动压缩,我们停掉etcd服务,并将自动压缩时间1小时修改成5m,即5分钟。

sh
# 停止etcd服务
./stop.sh

# 清空etcd日志
> logs/nohup.out
> logs/etcd.log

然后三个节点同时修改配置,修改后查看auto-compaction相关配置:

sh
[root@etcd-node1 node]# pwd
/srv/etcd/node
[root@etcd-node1 node]# grep auto-compaction config/etcd.yaml
auto-compaction-mode: periodic
auto-compaction-retention: "5m"
[root@etcd-node1 node]#

启动服务:

sh
[root@etcd-node1 node]# ./start_by_config.sh 
[root@etcd-node1 node]# nohup: appending output to ‘nohup.out’

此时,在etcd-workbench中进行修改timekey的值,修改两次后,可以看到差异:

Snipaste_2025-06-21_22-47-49.png

再修改一次,还是可以看到差异:

Snipaste_2025-06-21_22-48-35.png

过了几分钟后,在节点1的etcd.log中看到出现新的日志:

sh
{"level":"info","ts":"2025-06-21T22:50:06.033391+0800","caller":"v3compactor/periodic.go:134","msg":"starting auto periodic compaction","revision":38,"compact-period":"5m0s"}
{"level":"info","ts":"2025-06-21T22:50:06.034352+0800","caller":"v3compactor/periodic.go:142","msg":"completed auto periodic compaction","revision":38,"compact-period":"5m0s","took":"907.1µs"}

说明etcd自动启动了压缩服务。

只是压缩到版本38了,我们刚新建的三个版本 39、40、 41没有被压缩,此时仍然可以看到三个版本之间的对比。

Snipaste_2025-06-21_22-54-16.png

再新建两个版本。最新版本到43呢!

过了一会儿,日志中显示压缩到版本41了!!

Snipaste_2025-06-21_22-55-57.png

此时,再在etcd-workbench中查看版本信息,可以看到timekey最早只能查看到版本41。

Snipaste_2025-06-21_22-57-23.png

此时,不再新建版本,并保持etcd服务持续运行!过一会儿看看是不是43版本前面的版本都会被压缩!!

过几分钟再看,看不到差异对比了!

Snipaste_2025-06-21_23-09-40.png

当前已经只剩下最新版本43了,看不了timekey的历史记录信息。说明自动压缩是正常工作的!!!

本首页参考 https://notes.fe-mm.com/ 配置而成