Etcd缓存自增造成数据库Size超过2GB的处理
场景
最近一次线上程序使用了etcd,场景是频繁更新请求的数据的value,在高并发场景下几乎每秒更新上千次,这就导致etcd的数据库告警超过了2GB。
可以通过如下命令查看当前的数据库使用情况。
ETCDCTL_API=3 etcdctl endpoint status --write-out=table

通过上图可以看到目前数据库已经超过2GB,这时候的ETCD已经告警无法使用了。可以通过命令 ETCDCTL_API=3 etcdctl alarm list查看告警列表。
一次性解决方案
因为etcd是日志数据库,频繁更新数据会增加etcd的版本号,可以通过一下命令中的revision查看当前的版本。如果数据频繁更新会造成缓存过大的问题,需要及时清理缓存,有三种方式可以解决这个问题:定期手动清理缓存、更新配置、增加容量(etcd默认容量是2GB,最大支持8GB)。
etcd的官网已经给出了具体的解决方案,可以根据官网步骤进行调整。针对线上已经超过容量的我们需要手动清理缓存。官方网站给出的步骤:https://etcd.io/docs/v3.3/op-guide/maintenance
脚本如下:
#!/bin/bash
echo "before clean cache"
ETCDCTL_API=3 etcdctl endpoint status --write-out=table
echo "check alarm list"
ETCDCTL_API=3 etcdctl alarm list
echo "begin to clean cache..."
rev=$(ETCDCTL_API=3 etcdctl --endpoints=:2379 endpoint status --write-out="json" | egrep -o '"revision":[0-9]*' | egrep -o '[0-9]*')
echo "etcd revision is ${rev}, begin to compact"
ETCDCTL_API=3 etcdctl compact $rev
echo "begin to defrag..."
ETCDCTL_API=3 etcdctl defrag --command-timeout=300s
echo "disarm alarm"
ETCDCTL_API=3 etcdctl alarm disarm
ETCDCTL_API=3 etcdctl alarm list
echo "after clean cache"
ETCDCTL_API=3 etcdctl endpoint status --write-out=table
上面脚本主要做了三件事情:
首先是通过执行 etcdctl compact $rev命令,压缩目前的缓存碎片数据。其次是通过命令 etcdctl defrag清理已经过期的缓存碎片。最后通过命令 etcdctl alarm disarm来消除当前的告警,如果不消除告警etcd仍然处于不可用状态。
然后通过命令可以查看当前的数据库使用情况:

通过上图可以看到数据库Size已经变成3.2MB了,问题解决。但是问题真正解决了吗?如果后续还是高频率更新value还是会带来持续增长的缓存,所以还需要一个长期解决方案。
长期解决方案
长期解决方案可以通过更新配置文件来解决,etcd配置文件官方网站:https://etcd.io/docs/v3.3/op-guide/configuration/#configuration-file,我们需要更新两个配置:
vim /etc/etcd/etcd.conf增加如下配置:
ETCD_AUTO_COMPACTION_RETENTION=6
ETCD_AUTO_COMPACTION_MODE=revision
ETCD_AUTO_COMPACTION_RETENTION=6表示压缩碎片只保留6个小时,每隔6个小时系统会自动进行碎片压缩,压缩方法是 revision,就是我们上面的手动命令的方式。
如果业务的确要用到超过2GB的数据库,还可以通过修改启动命令来增加容量,修改方式如下:
vim /usr/lib/systemd/system/etcd.service
#add ExecStart 8589934592=8GB
--quota-backend-bytes=8589934592
systemctl daemon-reload
systemctl restart etcd
这样就增加etcd的容量到8GB,注意官方最高支持8GB,所以只能使用2-8GB之间的值,否则会启动失败。
最后,如果不放心官方的清理模式,还可以通过增加将上面的手动清理脚本加入定时任务里,这样就多重保险保障数据不会持续增长了。