etcd 调优技巧
何时更新检测信号间隔和选举超时设置
etcd 中的默认设置应该适用于平均网络延迟较低的本地网络上的安装。但是,当跨多个数据中心或通过高延迟网络使用 etcd 时,可能需要调整检测信号间隔和选举超时设置。
网络并不是延迟的唯一来源。每个请求和响应都可能受到主节点和从属节点上慢速磁盘的影响。这些超时中的每一个都表示从请求到另一台计算机成功响应的总时间。
调整时间参数
底层的分布式共识协议依赖于两个独立的时间参数,以确保节点在停滞或离线时可以交接领导权。第一个参数称为检测信号间隔。这是领导者通知追随者它仍然是领导者的频率。对于最佳做法,应围绕成员之间的往返时间设置该参数。默认情况下,etcd 使用 100ms
心跳间隔。
第二个参数是选举超时。此超时是指跟随者节点在尝试成为领导者之前在未听到心跳的情况下运行多长时间。默认情况下,etcd 使用 1000ms
选举超时。
调整这些值是一种权衡。建议心跳间隔的值约为成员之间平均往返时间 (RTT) 的最大值,通常约为往返时间的 0.5-1.5 倍。如果心跳间隔过低,etcd 会发送不必要的消息,增加 CPU 和网络资源的使用率。另一方面,检测信号间隔过长会导致选举超时时间过长。较高的选举超时需要更长的时间才能检测到领导者故障。测量往返时间 (RTT) 的最简单方法是使用 PING 实用程序。
应根据成员之间的检测信号间隔和平均往返时间设置选举超时。选举超时必须至少是往返时间的 10 倍,这样才能考虑网络中的差异。例如,如果成员之间的往返时间为 10 毫秒,则选举超时应至少为 100 毫秒。
选举超时上限为 50000ms(50s),仅在部署全局分布式 etcd 集群时使用。美国大陆的合理往返时间为 130 毫秒,美国和日本之间的时间约为 350-400 毫秒。如果网络性能不均匀或经常出现数据包延迟/丢失,则可能需要重试几次才能成功发送数据包。因此,5s 是全局往返时间的安全上限。由于选举超时应比广播时间大一个数量级,因此对于全局分布式集群,如果 ~5 秒,则 50 秒成为合理的最大值。
对于一个集群中的所有成员,检测信号间隔和选举超时值应相同。为 etcd 成员设置不同的值可能会破坏集群稳定性。
可以在命令行上覆盖默认值:
# Command line arguments:
$ etcd --heartbeat-interval=100 --election-timeout=500
# Environment variables:
$ ETCD_HEARTBEAT_INTERVAL=100 ETCD_ELECTION_TIMEOUT=500 etcd
这些值以毫秒为单位指定。
Snapshots 快照
etcd 将所有关键更改附加到日志文件中。此日志会永远增长,并且是对密钥所做的每次更改的完整线性历史记录。完整的历史记录适用于使用较少的集群,但使用频繁的集群将携带大量日志。
为了避免有一个巨大的日志,etcd 会定期制作快照。这些快照为 etcd 提供了一种通过保存系统的当前状态和删除旧日志来压缩日志的方法。
Snapshot tuning 快照调优
使用 V2 后端创建快照可能很昂贵,因此只有在对 etcd 进行给定数量的更改后才会创建快照。默认情况下,每 10,000 次更改后将创建快照。如果 etcd 的内存使用率和磁盘使用率过高,请尝试通过在命令行中设置以下内容来降低快照阈值:
# Command line arguments:
$ etcd --snapshot-count=5000
# Environment variables:
$ ETCD_SNAPSHOT_COUNT=5000 etcd
Disk 磁盘
etcd 集群对磁盘延迟非常敏感。由于 etcd 必须将建议持久化到其日志中,因此来自其他进程的磁盘活动可能会导致较长 fsync
的延迟。结果是 etcd 可能会错过心跳,导致请求超时和暂时的领导丢失。当给定高磁盘优先级时,etcd 服务器有时可以与这些进程一起稳定运行。
在 Linux 上,etcd 的磁盘优先级可以配置为 ionice
:
# best effort, highest priority
$ sudo ionice -c2 -n0 -p `pgrep etcd`
Network 网络
如果 etcd leader 服务于大量并发客户端请求,可能会因网络拥塞而延迟处理 follower 对等请求。这表现为以下节点上的发送缓冲区错误消息:
dropped MsgProp to 247ae21ff9436b2d since streamMsg's sending buffer is full
dropped MsgAppResp to 247ae21ff9436b2d since streamMsg's sending buffer is full
这些错误可以通过将 etcd 的对等流量优先于其客户端流量来解决。在 Linux 上,可以使用流量控制机制对对等流量进行优先级排序:
tc qdisc add dev eth0 root handle 1: prio bands 3
tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip sport 2380 0xffff flowid 1:1
tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip dport 2380 0xffff flowid 1:1
tc filter add dev eth0 parent 1: protocol ip prio 2 u32 match ip sport 2379 0xffff flowid 1:1
tc filter add dev eth0 parent 1: protocol ip prio 2 u32 match ip dport 2379 0xffff flowid 1:1
要取消 tc
,请执行:
tc qdisc del dev eth0 root
CPU
由于 etcd 对延迟非常敏感,因此可以通过将 CPU 调控器设置为性能或保守模式来进一步优化 Linux 系统的性能。
在 Linux 上,可以将 CPU 调控器配置为性能模式:
echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor