# Etcd坑了多少公司？

LLMS 索引： [llms.txt](/llms.txt)

---

前几天 [影视飓风分享的 Pigsty / PostgreSQL 高可用案例](https://mp.weixin.qq.com/s/7zJe6_HJU7Q2_Uf9-lS2vQ) 里面踩的一个雷在 X 上引起网友热议。
“因为 etcd 未开启自动压实功能，且默认仅为 2GB 容量”，ayanamist 评论到：“ _我倒要看看 etcd 这个傻逼 2G 的设计可以坑多少公司_ ”。

etcd 的 slogan 是：“一个分布式的、可靠的键-值存储，用于存放系统中最为关键的配置数据”。
目前最常见的场景是用于存储 K8S 的元数据。当然类似 Patroni 这样的 PostgreSQL 高可用方案也可能会用到 etcd 作为 DCS。

在 Ayanamist 这条推的评论下，可以看到许多人都踩过这个雷。大部分是 K8S 用户，也有在 PG 高可用场景上翻车的例子。

-------

## etcd 的缺陷

ETCD 有一个非常傻逼的设计，就是在默认配置下，写满 2GB 数据就挂了。

具体来说，etcd 每次写入都会创建一个新的版本，当这些数据/版本超过 2GB 之后，etcd 就会进入维护模式（挂了）。
想象一个没有启用 GC 垃圾回收的 Java JDK，就可以理解 etcd 有多坑了。

当然，其实是有参数配置项可以解决这个问题的，例如使用以下配置项，可以让 etcd 只保留最近 24 小时的版本，从而避免了存储空间的无限增长。

```yaml
auto-compaction-retention: "24h"
```

但坑就坑在，这并不是一个默认配置，这个参数的默认值是 `0`，也就是保留所有历史版本。

更坑的是，在 etcd “[维护](https://etcd.io/docs/v3.4/op-guide/maintenance/)” 部分的文档里的语句很有误导性，例如在 Maintenance 部分是这么说的：

> 为了保持稳定性，etcd 集群需要定期维护。根据 etcd 应用的需求，**这些维护通常可以自动化执行** ，且不会导致停机或显著性能下降。

而且在下面的 “Auto Compaction” 部分，一眼看过去，给人的感觉就是 auto compact 设置了很好的默认值嘛： 每小时垃圾回收一次，保留10个小时，这不是挺好的？应该不需要我操心了。

但如果你没去看那个 Configuration Options 参考文档，那完犊子了

最后，这个问题还不会在 etcd 开始服务时立即暴露，而是会在使用几个月之后突然爆雷。

-------

## PostgreSQL 的例子

其实在很早的时候（8.0, 2005 年前） PostgreSQL 也有这个问题。 PostgreSQL 使用与 etcd 类似的 MVCC 逻辑，每次写入也都是创建新版本/标记删除，所以会留下许多历史版本。
当垃圾版本积累的太多而没有清理时，数据库就炸了，而这个操作是需要管理员手工执行的，所以成为了 PG 广为诟病的一个问题。

不过后来 PostgreSQL 引入了 AutoVacuum 机制，也就是自动垃圾回收，会有守护进程不断扫描清理回收，免去了人工操作的烦恼。
因此在现代硬件上，默认参数下的 PostgreSQL 基本不会再因为这个问题而头疼了。

然而，并非所有数据库都像 PostgreSQL 这样 “靠谱贴心”，给用户设置了足够好的 “默认值”，可以开箱即用。etcd 就是一个非常典型的例子。

-------

## Pigsty 的例子

Pigsty 也在这个问题上翻过车。从 2023-02-28 发布的 v2.0.0 首次引入 etcd 作为 DCS 开始，到 2024-02-13 v2.6.0 修复 etcd 的这个问题，
整整一年的版本都受到 etcd 这个问题的影响。我们在文档的 [漏洞缺陷](https://pigsty.cc/docs/bug/) 与 [ETCD FAQ](https://pigsty.cc/docs/etcd/faq/) 中多次强调过这个问题。

在这里还是要特别提醒一下使用 Pigsty v2.0 ~ v2.5 的用户，请尽快更新升级一下 Etcd 的配置。
