etcd报错:发送心跳超时

532人浏览 / 0人评论

Etcd心跳发送超时

 

一、背景

线上etcd 采用多实例方式部署etcd,9个集群共用5台etcd 物理机来提供服务。发现etcd经常出现 发送心跳超时的错误日志。

 

2022-04-19T01:12:03.519 Apr 19 01:12:03 ops-etcd etcd: failed to send out heartbeat on time (exceeded the 100ms timeout for 9.132836ms)

 

二、etcd心跳发送原理说明

  1. 心跳发送的时间是由 默认参数 --heartbeat-interval 100 --election-timeout 1000控制的,目前我们的集群中没有特殊配置,所以按照默认执行。

参数解释:

 

参数解释:心跳间隔和检测超时,etcd leader每100ms去向follower 发送心跳,如果请求超时共累计达到--election-timeout 1000ms 或者 follower在--election-timeout 超时时间内没有收到心跳 则进行竞选leader。 https://etcd.io/docs/v3.3/tuning/#time-parameters ###(请求超时是代码写死的 1秒)

 

最后的这个时间加上2倍的心跳时间大于选举超时时间,则Follower就会竞选leader。

原理图:

 

三、官方版问题解决

https://etcd.io/docs/v3.3/faq/

etcd 警告“未能按时发出心跳”是什么意思?

etcd 使用基于领导者的共识协议来进行一致的数据复制和日志执行。集群成员选举一个领导者,所有其他成员成为追随者。The elected leader must periodically send heartbeats to its followers to maintain its leadership. 如果在选举间隔内没有收到心跳,则追随者会推断领导失败并触发选举。如果leader没有及时发送心跳但仍在运行,则选举是虚假的,很可能是资源不足造成的。为了捕捉这些软故障,如果领导者跳过两个心跳间隔,etcd 将警告它未能按时发送心跳。

 

通常这个问题是由慢速磁盘引起的。在领导者发送带有元数据的心跳之前,它可能需要将元数据持久化到磁盘。磁盘可能在 etcd 和其他应用程序之间发生争用,或者磁盘太慢(例如,共享虚拟化磁盘)。要排除慢磁盘导致此警告,请监控wal_fsync_duration_seconds(p99 持续时间应小于 10 毫秒)以确认磁盘相当快。如果磁盘太慢,为 etcd 分配专用磁盘或使用更快的磁盘通常可以解决问题。

 

第二个最常见的原因是 CPU 不足。如果监控机器的 CPU 使用率显示使用率很高,则可能没有足够的计算能力用于 etcd。将 etcd 移至专用机器,使用 cgroups 增加进程资源隔离,或将 etcd 服务器进程重新调整为更高的优先级通常可以解决问题。

 

缓慢的网络也可能导致此问题。如果 etcd 机器之间的网络指标显示延迟较长或掉线率较高,则可能是 etcd 的网络容量不足。将 etcd 成员移动到拥塞较少的网络通常可以解决问题。但是,如果 etcd 集群跨数据中心部署,则预计成员之间的延迟会很长。对于此类部署,调整heartbeat-interval配置以大致匹配机器之间的往返时间,并且election-timeout配置至少为 5 * heartbeat-interval。有关详细信息,请参阅调整文档

如果上述建议都没有清除警告,请打开一个包含详细日志记录、监控、指标和可选工作负载信息的问题。

大概官方说明磁盘和网络和cpu都会导致出现此告警。

1、磁盘问题,已按照官方去看 wal_fsync_duration_seconds 值并没有超过10毫秒,都在1毫秒左右。

2、cpu 已看falcon大图,并发现异常。

3、网络 已看falcon大图,并发现异常。

 

四、问题解决

https://etcd.io/docs/v3.3/tuning/

通过参数优化进行整改问题:

 

  1. 修改心跳间隔

--heartbeat-interval 350 --election-timeout 3500

官方建议:您还应该将选举超时设置为至少 5 到 10 倍心跳间隔,以解决领导者复制的差异。对于 50 毫秒的心跳间隔,您应该将选举超时设置为至少 250 毫秒 - 500 毫秒。

 

  1. 修改快照保存时间-不修改

--snapshot-count=5000 (官方默认是10000次更改后生成快照,在快照前 数据是写入到内存中的)

详细说明:

  • etcd 将所有关键更改附加到日志文件。该日志会永远增长,并且是对密钥所做的每次更改的完整线性历史记录。完整的历史记录适用于轻度使用的集群,但频繁使用的集群会携带大量日志。为了避免日志过大,etcd 会定期进行快照。这些快照为 etcd 提供了一种通过保存系统当前状态和删除旧日志来压缩日志的方法。

  • 创建快照可能很昂贵,因此它们仅在对 etcd 进行给定数量的更改后创建。默认情况下,将在每 10,000 次更改后生成快照。如果 etcd 的内存使用量和磁盘使用量过高,可以通过在命令行中设置以下内容来降低快照阈值。

 

  1. etcd存储数据大小

--quota-backend-bytes=8589934592

etcd存储数据 默认为2G,3.2版本最大限制8G,3.3版本后不限制。

 

  1. 调整etcd磁盘读写优先级

sudo ionice -c2 -n0 -p `pgrep etcd`

etcd 集群对磁盘延迟非常敏感。由于 etcd 必须将提案保存到其日志中,因此来自其他进程的磁盘活动可能会导致较长的fsync延迟。结果是 etcd 可能会错过心跳,导致请求超时和临时领导者丢失。当赋予高磁盘优先级时,etcd 服务器有时可以与这些进程一起稳定运行。

 

  1. 调整历史数据压缩-无需修改从3.2版本开始就已经是1小时压缩一次了

etcd_compaction_retention 1

  • 由于ETCD数据存储多版本数据,随着写入的主键增加历史版本需要定时清理, 默认的历史数据是不会清理的,数据达到2G就不能写入,必须要清理压缩历史数据才能继续写入;

  • 所以根据业务需求,在上生产环境之前就提前确定,历史数据多长时间压缩一次; 我们的生产环境现在升级后是默认一小时压缩一次数据。这样可以极大的保证集群稳定,减少内存和磁盘占用

 

五、etcd dev测试

参数优化:

 

优化前参数: ETCD_NAME=etcd02 ETCD_DATA_DIR="/data/etcd/etcd_2379/data/etcd" ETCD_LISTEN_PEER_URLS="https://0.0.0.0:2380" ETCD_LISTEN_CLIENT_URLS="https://0.0.0.0:2379" ETCD_ADVERTISE_CLIENT_URLS="https://xx:2379" ETCD_INITIAL_ADVERTISE_PEER_URLS="https://xx:2380" ETCD_INITIAL_CLUSTER="etcd01=https://xx:2380,etcd02=https://xx:2380,etcd03=https://xxx :2380" ETCD_CERT_FILE="/data/etcd/etcd_2379/etc/etcd/ssl/dev-etcd01.pem" ETCD_KEY_FILE="/data/etcd/etcd_2379/etc/etcd/ssl/dev-etcd01-key.pem" ETCD_TRUSTED_CA_FILE="/data/etcd/etcd_2379/etc/etcd/ssl/ca.pem" ETCD_CLIENT_CERT_AUTH="true" ETCD_PEER_CERT_FILE="/data/etcd/etcd_2379/etc/etcd/ssl/dev-etcd01.pem" ETCD_PEER_KEY_FILE="/data/etcd/etcd_2379/etc/etcd/ssl/dev-etcd01-key.pem" ETCD_PEER_TRUSTED_CA_FILE="/data/etcd/etcd_2379/etc/etcd/ssl/ca.pem" ETCD_PEER_CLIENT_CERT_AUTH="true" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_INITIAL_CLUSTER_TOKEN="dev-k8s-etcd01"

 

优化后参数: ETCD_NAME=etcd02 ETCD_DATA_DIR="/data/etcd/etcd_2379/data/etcd" ETCD_LISTEN_PEER_URLS="https://0.0.0.0:2380" ETCD_LISTEN_CLIENT_URLS="https://0.0.0.0:2379" ETCD_ADVERTISE_CLIENT_URLS="https://xxx:2379" ETCD_INITIAL_ADVERTISE_PEER_URLS="https://xx:2380" ETCD_INITIAL_CLUSTER="etcd01=https://xxx:2380,etcd02=https://xxx:2380,etcd03=https://xx :2380" ETCD_CERT_FILE="/data/etcd/etcd_2379/etc/etcd/ssl/dev-etcd01.pem" ETCD_KEY_FILE="/data/etcd/etcd_2379/etc/etcd/ssl/dev-etcd01-key.pem" ETCD_TRUSTED_CA_FILE="/data/etcd/etcd_2379/etc/etcd/ssl/ca.pem" ETCD_CLIENT_CERT_AUTH="true" ETCD_PEER_CERT_FILE="/data/etcd/etcd_2379/etc/etcd/ssl/dev-etcd01.pem" ETCD_PEER_KEY_FILE="/data/etcd/etcd_2379/etc/etcd/ssl/dev-etcd01-key.pem" ETCD_PEER_TRUSTED_CA_FILE="/data/etcd/etcd_2379/etc/etcd/ssl/ca.pem" ETCD_PEER_CLIENT_CERT_AUTH="true" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_INITIAL_CLUSTER_TOKEN="dev-k8s-etcd01" ETCD_HEARTBEAT_INTERVAL=500 ETCD_ELECTION_TIMEOUT=5000 ETCD_QUOTA_BACKEND_BYTES=8589934592

 

日志:

etcd-20220421.log:Apr 21 19:57:27 ops-etcd etcd: failed to send out heartbeat on time (exceeded the 500ms timeout for 932.885614ms)

etcd-20220421.log:Apr 21 19:57:27 ops-etcd etcd: failed to send out heartbeat on time (exceeded the 500ms timeout for 932.973823ms)

 

全部评论