彻底搞懂 etcd 系列文章(九):etcd compact 和 watch API

本文详细解析了etcd的Compact方法和Watch服务,包括事件、监视流和Watch service的定义。了解这些内容能帮助我们更好地掌握etcd在微服务和Kubernetes集群中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0 专辑概述

etcd 是云原生架构中重要的基础组件,由 CNCF 孵化托管。etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册与发现,还可以作为 key-value 存储的中间件。

《彻底搞懂 etcd 系列文章》将会从 etcd 的基本功能实践、API 接口、实现原理、源码分析,以及实现中的踩坑经验等几方面具体展开介绍 etcd。预计会有 20 篇左右的文章,笔者将会每周持续更新,欢迎关注。

1 Compact方法

Compact 方法压缩 etcd 键值对存储中的事件历史。键值对存储应该定期压缩,否则事件历史会无限制的持续增长。

rpc Compact(CompactionRequest) returns (CompactionResponse) {}

请求的消息体是 CompactionRequest, CompactionRequest 压缩键值对存储到给定修订版本。所有修订版本比压缩修订版本小的键都将被删除:

message CompactionRequest {
  // 键值存储的修订版本,用于比较操作
  int64 revision = 1;

  bool physical = 2;
}

physical 设置为 true 时 RPC 将会等待直到压缩物理性的应用到本地数据库,到这程度被压缩的项将完全从后端数据库中移除。应答的消息体 CompactionResponse 定义为:

message CompactionResponse {
  ResponseHeader header = 1;
}

CompactionResponse 只有一个通用的响应头。

2 Watch 服务

Watch API 提供了一个基于事件的接口,用于异步监视键的更改。etcd3 监视程序通过从给定的修订版本(当前版本或历史版本)持续监视 key 更改,并将 key 更新流回客户端。

事件

每个键的更改都用事件消息表示。事件消息会同时提供更新数据和更新类型,mvccpb.Event 的消息体定义如下:

message Event {
  enum
<think>嗯,用户这次提出了一个非常具体的etcd运维问题:健康检查报错显示成员ID 1801147372557467469565触发NOSPACE告警。这显然是个生产环境紧急故障,需要快速响应。 从引用内容看,用户已经具备一定etcd基础:引用1展示了典型的空间溢出状态(DB SIZE达2.1GB并触发NOSPACE),引用3提到配额配置方法。但用户没提是否做过快照备份,这很关键——数据恢复操作前必须确认备份状态。 核心矛盾点在于:etcd的boltdb存储引擎达到配额上限后,会拒绝所有写操作导致集群不可用。需要分三步处理: 1. 立即扩容:临时调大quota_backend_bytes值缓解(如引用3所述),但要注意v3.4+版本需通过API动态调整 2. 紧急释放空间:必须用etcdctl defrag命令,但需谨慎——在线碎片整理会瞬间增加内存压力 3. 根本解决:需检查compact参数是否合理,默认5分钟compact一次可能不够 用户给出的成员ID很完整(180114...),说明已经准确定位到故障节点。不过etcd集群通常有多个节点,需要确认其他节点状态:若只有单节点报错可能只需局部处理,但引用1显示整个集群触发告警(alarm list输出NOSPACE),说明是全局存储溢出。 突然想到个风险点:碎片整理期间如果客户端持续写入,可能触发mvcc: database space exceeded错误。最好在业务低峰期操作,并提前用etcdctl endpoint status确认所有节点状态。 用户没提K8s环境,但根据经验这大概率是K8s的etcd集群。需要提醒检查kube-apiserver日志——当etcd不可写时,apiserver会返回503错误,这比etcd自身的健康检查更能反映业务影响。</think>根据您的描述,etcd集群出现了健康检查错误(`memberID:1801147372557469565`)`NOSPACE`告警,这通常由**存储空间耗尽**引起。以下是完整解决方案: --- ### **原因分析** 1. **存储超限** - `alarm:NOSPACE`表示etcd后端数据库超过配额(默认2GB),触发写保护机制[^1]。 - 通过`etcdctl endpoint status`可确认DB大小(如引用中`2.1 GB`已超限)[^1]。 2. **碎片累积** - etcd频繁更新/删除数据会产生存储碎片,即使实际数据量未超限,碎片仍占用配额[^3]。 --- ### **解决步骤** #### **1. 紧急释放空间** ```bash # 查看当前告警(确认NOSPACE) ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 alarm list # 执行在线碎片整理(在**每个**etcd节点运行) ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 defrag # 解除告警(整理后执行) ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 alarm disarm ``` > **风险提示**:`defrag`会阻塞etcd进程,需在低峰期操作,否则可能触发请求超时! #### **2. 永久调整存储配额** 编辑etcd配置文件(如`/etc/etcd/etcd.conf`): ```ini # 将配额调整为8GB(根据业务需求设定) ETCD_QUOTA_BACKEND_BYTES="8589934592" ``` 重启etcd服务: ```bash sudo systemctl restart etcd ``` #### **3. 检查历史压缩** ```bash # 确认自动压缩已启用(默认每5分钟压缩) ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 endpoint status -w fields | grep "dbSizeInUse" ``` 若`dbSizeInUse`接近`dbSize`,说明碎片过多,需**手动压缩历史版本**: ```bash # 获取当前版本号 rev=$(ETCDCTL_API=3 etcdctl endpoint status --write-out="json" | grep -o '"revision":[0-9]*' | cut -d: -f2) # 压缩所有旧版本 ETCDCTL_API=3 etcdctl compact $rev # 执行碎片整理(再次defrag) ``` #### **4. 监控与预防** - **定期检查**: ```bash ETCDCTL_API=3 etcdctl --write-out=table endpoint status ``` - **设置告警**:监控`etcd_mvcc_db_total_size_in_bytes`指标(Prometheus)。 - **备份策略**:每日执行快照备份: ```bash ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-$(date +%s).db ``` --- ### **关键注意事项** 1. **碎片整理顺序**: `compact → defrag → disarm`,避免直接整理未压缩的数据[^3]。 2. **成员ID一致性**: 操作时确保`memberID`与故障节点一致(您提供的`1801147372557469565`需与实际节点匹配)。 3. **多节点集群**: 若为集群环境,需**依次操作每个节点**,并确保多数节点在线。 > 通过上述步骤,可解除`NOSPACE`告警并恢复健康状态。若问题持续,需检查是否由**内存泄漏**或**磁盘故障**引发[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值