ETCD -- 压缩(Compaction)​详解

在 ​etcd 中,​数据压缩(Compaction)的本质是删除历史版本数据,但 ​不会删除键的当前最新值。这是 etcd 优化存储空间和性能的核心机制之一。

一、压缩(Compaction)的本质

1. ​删除历史版本

压缩操作会删除指定 revision 之前的所有 ​历史版本​(即旧值),但保留键的 ​当前最新值。
示例:

键 /mykey 被修改了 3 次,对应的 revision 为 100、200、300。
执行 compact 250 后:
revision ≤250 的历史数据被删除(如 revision 100 和 200 的旧值)。
键的当前值(revision 300)仍然保留。

2. ​存储优化

压缩通过清理不再需要的历史版本,减少 etcd 的存储占用,提升查询性能(尤其是范围查询)。

3. ​不影响最新数据

当前值始终保留:无论是否压缩,键的当前最新值(即最后一次写入的值)都不会被删除。

二、压缩配置

1. 基于时间:保留最近一段时间的历史版本。

# 保留 24 小时内的历史, 24小时外的删除
<think>我们注意到用户之前尝试使用systemctl管理etcd服务,但发现服务不存在(Unit etcd.service could not be found),同时使用etcdctl时出现命令未找到(-bash: etcdctl: command not found)。根据用户提供的引用内容,用户希望使用Docker部署etcd,因此我们不需要通过systemctl管理etcd服务(因为etcd运行在容器中),而是通过Docker命令管理容器。 用户的需求是:修改当前的docker run命令以正确部署etcd容器,并解决etcdctl未找到的问题。 分析: 1. 用户之前运行etcd容器可能没有正确配置,或者容器已经停止,导致无法连接。 2. 用户直接在宿主机上执行etcdctl,但宿主机并没有安装etcdctl客户端,所以出现命令未找到。 解决方案: 1. 使用Docker运行etcd容器,并确保容器在后台运行(使用-d参数)。 2. 将etcd的客户端端口(2379)映射到宿主机,这样可以通过宿主机的2379端口访问etcd。 3. 为了使用etcdctl命令,我们可以有两种方式: a. 在宿主机上安装etcdctl客户端(通过下载二进制文件或使用包管理器安装)。 b. 通过Docker容器执行etcdctl命令(推荐,因为版本与etcd服务容器一致,且不需要在宿主机安装)。 根据引用[1]中的命令,我们启动一个单节点etcd容器: docker run -d \ --name etcd-single-node \ -p 2379:2379 \ quay.io/coreos/etcd:latest \ /usr/local/bin/etcd \ --name etcd0 \ --advertise-client-urls http://localhost:2379 \ --listen-client-urls http://0.0.0.0:2379 但是,这个命令中,etcd容器使用的是latest标签,可能不是最稳定的版本,建议使用特定版本,例如v3.5.0。 另外,引用[2]和[3]中展示了如何使用另一个etcdctl容器来执行命令,这样可以避免在宿主机安装etcdctl。 因此,我们提供两种方法: 方法一:在宿主机安装etcdctl(以CentOS为例) 步骤1:下载etcdctl二进制文件(注意选择与etcd服务相同版本) ETCD_VER=v3.5.0 wget https://github.com/etcd-io/etcd/releases/download/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz tar xvf etcd-${ETCD_VER}-linux-amd64.tar.gz cd etcd-${ETCD_VER}-linux-amd64 sudo mv etcdctl /usr/local/bin/ 步骤2:验证安装 etcdctl version 方法二:通过另一个etcd容器执行etcdctl命令(推荐,因为不需要在宿主机安装,且版本与服务器一致) docker run --rm -it \ --net host \ quay.io/coreos/etcd:latest \ etcdctl --endpoints=http://localhost:2379 endpoint status 注意:这里使用了`--net host`,使得etcdctl容器使用宿主机的网络,可以直接访问localhost:2379。 但是,如果etcd容器运行在默认的bridge网络下,我们也可以使用容器名称来访问(需要创建同一个网络并指定容器名称)。 根据用户之前的操作,我们发现用户已经通过Docker运行了etcd容器(通过ss命令看到2379端口被docker-proxy占用),但是容器名称未知。因此,我们建议: 1. 停止并删除现有的etcd容器(如果有): docker stop <container_name> # 如果不知道容器名,可以用docker ps查看 docker rm <container_name> 2. 使用以下命令启动一个新的etcd容器(使用特定版本,避免latest可能带来的变动): docker run -d \ --name my-etcd \ -p 2379:2379 \ quay.io/coreos/etcd:v3.5.0 \ etcd \ --name etcd0 \ --advertise-client-urls http://localhost:2379 \ --listen-client-urls http://0.0.0.0:2379 3. 验证etcd容器是否运行: docker ps 4. 使用etcdctl容器执行命令(无需在宿主机安装): docker run --rm -it \ --net host \ quay.io/coreos/etcd:v3.5.0 \ etcdctl --endpoints=http://localhost:2379 endpoint status 或者,也可以进入etcd容器内部执行命令(不推荐,因为etcd容器可能没有包含etcdctl): docker exec -it my-etcd sh # 然后在容器内执行:etcdctl endpoint status 但是,注意etcd镜像中通常包含etcdctl,所以上面的命令应该可以工作。 如果用户希望使用docker-compose,可以参考引用[3]中的方式编写docker-compose.yml文件。 总结步骤: 步骤1:停止并删除可能存在的旧etcd容器 docker stop my-etcd docker rm my-etcd 步骤2:启动etcd容器 docker run -d \ --name my-etcd \ -p 2379:2379 \ quay.io/coreos/etcd:v3.5.0 \ etcd \ --name etcd0 \ --advertise-client-urls http://localhost:2379 \ --listen-client-urls http://0.0.0.0:2379 步骤3:使用etcdctl容器检查状态 docker run --rm -it \ --net host \ quay.io/coreos/etcd:v3.5.0 \ etcdctl --endpoints=http://localhost:2379 endpoint status 预期输出: 127.0.0.1:2379 is healthy 注意:如果使用`--net host`出现权限问题,可以尝试使用`--network="host"`(在Linux环境下)。 另外,如果用户不想使用host网络,也可以将etcdctl容器连接到同一个bridge网络(默认就是bridge,且通过端口映射,所以通过localhost:2379访问即可)。 因此,上述命令在Linux宿主机上应该可以正常运行。 如果用户需要经常使用etcdctl命令,可以在宿主机上设置别名(alias)来简化命令: alias etcdctl='docker run --rm -it --net host quay.io/coreos/etcd:v3.5.0 etcdctl' 然后就可以直接使用: etcdctl --endpoints=http://localhost:2379 endpoint status 这样,用户就不会再遇到“etcdctl: command not found”错误。 关于服务未找到(Unit etcd.service could not be found)的问题,因为etcd是通过Docker容器运行的,所以不需要systemd服务管理。用户可以通过docker命令管理容器: docker start my-etcd # 启动 docker stop my-etcd # 停止 docker restart my-etcd # 重启 最后,为了确保容器在宿主机重启后自动启动,可以添加`--restart always`参数: docker run -d \ --restart always \ --name my-etcd \ -p 2379:2379 \ quay.io/coreos/etcd:v3.5.0 \ etcd \ --name etcd0 \ --advertise-client-urls http://localhost:2379 \ --listen-client-urls http://0.0.0.0:2379 这样,etcd容器就会在宿主机重启后自动启动。 综上所述,我们通过Docker容器运行etcd服务,并通过另一个etcd容器提供etcdctl命令,解决了用户的问题。</think>### 解决 Docker 部署 ETCD 的问题 根据您的问题和引用内容,以下是完整的解决方案,解决 `etcdctl: command not found` 和 `Unit etcd.service could not be found` 错误: --- ### 1. **修改 Docker 命令部署 ETCD** 修改您的 `docker run` 命令如下(关键修改已标记): ```bash docker run -d \ --name etcd-single-node \ -p 2379:2379 \ -p 2380:2380 \ # 新增管理端口映射 --restart unless-stopped \ # 添加自动重启 quay.io/coreos/etcd:latest \ /usr/local/bin/etcd \ --name etcd0 \ --advertise-client-urls http://0.0.0.0:2379 \ # 修改为0.0.0.0 --listen-client-urls http://0.0.0.0:2379 \ --initial-advertise-peer-urls http://0.0.0.0:2380 \ --listen-peer-urls http://0.0.0.0:2380 ``` **关键修改说明**: 1. `-p 2380:2380`:添加 peer 通信端口映射[^1] 2. `--advertise-client-urls http://0.0.0.0:2379`:允许所有IP连接 3. `--restart unless-stopped`:确保容器自动重启 4. 添加 peer 相关参数保证集群基础功能 --- ### 2. **解决 `etcdctl: command not found` 错误** #### 方法1:使用 Docker 容器执行 etcdctl(推荐) ```bash docker exec -it etcd-single-node etcdctl \ --endpoints=http://localhost:2379 \ endpoint status ``` #### 方法2:下载 etcdctl 二进制文件 ```bash # 下载特定版本(与容器版本匹配) ETCD_VER=$(docker exec etcd-single-node etcd --version | head -1 | awk '{print $3}') curl -L https://github.com/etcd-io/etcd/releases/download/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz | tar xz # 安装到系统路径 sudo mv etcd-${ETCD_VER}-linux-amd64/etcdctl /usr/local/bin/ ``` --- ### 3. **验证 ETCD 状态** ```bash # 使用容器内 etcdctl docker exec etcd-single-node etcdctl \ --write-out=table \ --endpoints=http://localhost:2379 \ endpoint status ``` **正常输出示例**: ``` +----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | +----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ | localhost:2379 | 8e9e05c52164694d | 3.5.0 | 20 kB | true | false | 2 | 10 | 10 | | +----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ ``` --- ### 4. **解决服务未找到问题** 由于 ETCD 运行在容器中,**不需要 systemd 服务**。使用 Docker 命令管理: ```bash # 启动/停止容器 docker start etcd-single-node docker stop etcd-single-node # 查看日志 docker logs -f etcd-single-node # 设置开机自启 docker update --restart=always etcd-single-node ``` --- ### 5. **常用操作命令** ```bash # 写入数据 docker exec etcd-single-node etcdctl put /message "Hello ETCD" # 读取数据 docker exec etcd-single-node etcdctl get /message # 备份数据 docker exec etcd-single-node etcdctl snapshot save backup.db # 查看成员 docker exec etcd-single-node etcdctl member list ``` --- ### 故障排除流程图 ```mermaid graph TD A[etcdctl not found] --> B{执行方式} B -->|宿主机| C[下载匹配的 etcdctl 二进制] B -->|容器内| D[docker exec etcd-single-node etcdctl] E[服务未找到] --> F{管理方式} F -->|容器| G[使用 docker start/stop 命令] F -->|宿主机| H[安装 etcd 系统服务] I[连接拒绝] --> J[检查端口映射和防火墙] ``` 通过以上步骤,您应该能解决 ETCD 容器部署和 etcdctl 命令问题。如果仍有问题,请提供 `docker logs etcd-single-node` 的输出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值