etcd 的租约 TTL 是怎么生效的?keepalive 要多频繁?一个 lease 挂很多 key 有什么好处?leader 切换时租约会怎样?这篇用单节点和三节点的 etcd 3.7.2 把它们量出来。
申请的 TTL | etcd 回的 TTL | 最短 | 中位数 | 最长(key 消失用了多久,10 次) --------+-------------+--------+--------+-------------------- 1 s | 2 s | 2.06 s | 2.49 s | 2.52 s 2 s | 2 s | 2.48 s | 2.49 s | 2.52 s 3 s | 3 s | 3.47 s | 3.49 s | 3.51 s 5 s | 5 s | 5.47 s | 5.49 s | 5.52 s etcd 对 TTL 有下限:申请 1 s 实际得到 2 s(我的理解是下限由选举超时推出来,这台默认选举超时 1 s,没有改参数验证);key 消失的时间比 TTL 多约半秒,看起来是 leader 周期性检查到期的 lease(检查周期约 0.5 s,这个周期是我从数据推测的,没有读源码)
etcd 对 TTL 有下限,key 在 TTL 之后再过约半秒才消失。
续约方式 | key | 续约成功 / 发出 | 续约响应里的 TTL ---------------+-----------+-----------+----------- (a) 每 1.7 s 续约 | 一直存在 | 8 / 8 | 5 (b) 每 4.5 s 续约 | 一直存在 | 3 / 3 | 5 (c) 每 5.5 s 续约 | 5.4 s 时消失 | 0 / 2 | NULL 续约把剩余时间重置为完整的 TTL(响应里的 TTL 是 5);续约间隔小于 TTL 才能保住租约;lease 一旦过期,之后发出的 keepalive 就不再成功(上表 (c) 的两次续约响应里都没有大于 0 的 TTL),客户端必须重新申请 lease 并重新写 key
续约间隔小于 TTL 才能保住租约;过期之后要重新申请。
一个 lease 上挂的 key 数 | revoke 用时 | revoke 之后剩余的 key | 对照 | 总用时 -------------------+-----------+------------------+------------------------+--------- 100 | 12.2 ms | 0 | 100 个 lease 逐个 revoke | 1069 ms 1000 | 14.0 ms | 0 | 1000 个 lease 逐个 revoke | 10012 ms 10000 | 25.5 ms | 0 | 1000 个 lease 逐个 revoke | 9518 ms revoke 一次请求就把挂在这个 lease 上的所有 key 删光(之后查询剩余为 0),用时随 key 数增长得很慢;而每个 key 一个 lease 时,要发 N 次 revoke,每次约 10 ms。服务发现里,一个服务实例通常只有一个 key,一个 lease;一个进程注册多个 key(例如多个服务名、多个端口)时,共用一个 lease 比较省
revoke 一次删光所有挂着的 key,比每个 key 一个 lease 省得多。
杀 leader 的时刻(申请后) | 杀之前 timetolive 的剩余 | 新 leader 选出的时刻 | 新 leader 上 timetolive 的剩余 | key 实际消失的时刻(申请后) ------------------+--------------------+----------------+---------------------------+----------------- 6.0 s | 3 | 7.5 s | 10 | 18.7 s 原本申请后 10 s 到期;leader 切换之后,新 leader 上 timetolive 回报的剩余时间是完整的 10 s(杀 leader 之前是 3 s),key 因此比原定的到期时间晚得多才消失。我的理解是 lease 的剩余时间只在 leader 的内存里按时钟走,换 leader 之后新 leader 把它们重置为完整的 TTL(这个机制我没有读源码验证,只看到了结果)
新 leader 把 lease 剩余时间重置为完整的 TTL。