集群频繁触发 etcdDatabaseHighFragmentationRatio 告警,PrometheusRule 内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - alert: etcdDatabaseHighFragmentationRatio annotations: description: 'etcd cluster "{{ $labels.job }}": database size in use on instance {{ $labels.instance }} is {{ $value | humanizePercentage }} of the actual allocated disk space, please run defragmentation (e.g. etcdctl defrag) to retrieve the unused fragmented disk space.' runbook_url: https://etcd.io/docs/v3.5/op-guide/maintenance/#defragmentation summary: etcd database size in use is less than 50 % of the actual allocated storage. expr: (last_over_time(etcd_mvcc_db_total_size_in_use_in_bytes{job=~".*etcd.*"}[5m]) / last_over_time(etcd_mvcc_db_total_size_in_bytes{job=~".*etcd.*"}[5m])) < 0.5 and etcd_mvcc_db_total_size_in_use_in_bytes{job=~".*etcd.*"} > 104857600 for: 10m labels: severity: warning
相关指标说明 该告警主要涉及以下指标:
etcd_server_quota_backend_bytes:当前后端存储配额大小,单位为字节,默认为 2 GB。
etcd_mvcc_db_total_size_in_bytes:底层数据库实际分配的总大小,包含数据和碎片空间,即 DB SIZE。
etcd_mvcc_db_total_size_in_use_in_bytes:底层数据库中逻辑上正在使用的空间大小,不包含碎片空间,即 IN USE。
需要注意的是,配置 quota-backend-bytes 后,etcd_mvcc_db_total_size_in_bytes 的大小并不会直接根据该值变化。变化的是 etcd_server_quota_backend_bytes 指标。
为什么会产生碎片 etcd 产生碎片的主要原因如下:
etcd 支持多版本并发控制(MVCC),会记录 keyspace 的历史版本。
压缩操作是清理历史版本的主要方式,通常可以通过 --auto-compaction-mode 和 --auto-compaction-retention 实现自动压缩。
压缩操作只会清理历史版本,但清理后的空闲空间并不会立即从文件系统中释放,而是被 etcd 标记为可复用的空闲空间。因此,压缩后 DB 文件仍然会占用磁盘空间。
如果需要真正释放这部分空闲空间,需要执行碎片整理,也就是 etcdctl defrag。
是否需要执行碎片整理 针对 etcdDatabaseHighFragmentationRatio 告警,可以参考以下方式判断是否需要进行碎片整理:
通过 etcd_server_quota_backend_bytes 指标查看当前 etcd Backend DB 的实际配额。
通过 etcd_mvcc_db_total_size_in_bytes 指标,或通过命令检查 DB SIZE 是否确实较大,并且是否接近 quota-backend-bytes。如果 DB SIZE 并不大,且距离配额仍有较大空间,则通常无需担心。
如果 DB SIZE 已经较大并接近 quota-backend-bytes,可以进一步统计各类资源数量,确认是否存在大量资源导致 DB SIZE 增长。随后可以通过碎片整理尝试释放空间。如果碎片整理后仍然接近 quota-backend-bytes,则需要考虑增加配额。
统计资源数量:
1 etcdctl get /registry --prefix --keys-only | grep -v ^$ | awk -F '/' '{ h[$3]++ } END {for (k in h) print h[k], k}' | sort -nr
执行碎片整理:
通过 etcdctl 查看 DB SIZE 和碎片率 除了 Prometheus 指标,也可以通过 etcdctl endpoint status 获取对应信息:
1 2 3 4 etcdctl endpoint status -w table
示例输出:
1 2 3 4 5 6 7 +----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+-----------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+ | ENDPOINT | ID | VERSION | STORAGE VERSION | DB SIZE | IN USE | PERCENTAGE NOT IN USE | QUOTA | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | DOWNGRADE TARGET VERSION | DOWNGRADE ENABLED | +----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+-----------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+ | https://172.16.16.120:2379 | 8af47ddd59a4380d | 3.6.7 | 3.6.0 | 38 MB | 37 MB | 2% | 2.1 GB | false | false | 41 | 223679135 | 223679135 | | | false | | https://172.16.16.121:2379 | 5c60194b69e150d6 | 3.6.7 | 3.6.0 | 38 MB | 37 MB | 2% | 2.1 GB | true | false | 41 | 223679135 | 223679135 | | | false | | https://172.16.16.122:2379 | c5794547c5d8917b | 3.6.7 | 3.6.0 | 38 MB | 37 MB | 2% | 2.1 GB | false | false | 41 | 223679135 | 223679135 | | | false | +----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+-----------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+