etcd 实战课
唐聪
腾讯云资深工程师,etcd 活跃贡献者
28449 人已学习
新⼈⾸单¥59
登录后,你可以任选3讲全文学习
课程目录
已完结/共 28 讲
开篇词 (1讲)
etcd 实战课
15
15
1.0x
00:00/00:00
登录|注册

08 | Watch:如何高效获取数据变化通知?

解决方案
业务场景问题
高效的事件匹配
可靠的事件推送机制
事件历史版本存储
获取事件机制
思考题
Watch特性设计实现

该思维导图由 AI 生成,仅供参考

你好,我是唐聪。
在 Kubernetes 中,各种各样的控制器实现了 Deployment、StatefulSet、Job 等功能强大的 Workload。控制器的核心思想是监听、比较资源实际状态与期望状态是否一致,若不一致则进行协调工作,使其最终一致。
那么当你修改一个 Deployment 的镜像时,Deployment 控制器是如何高效的感知到期望状态发生了变化呢?
要回答这个问题,得从 etcd 的 Watch 特性说起,它是 Kubernetes 控制器的工作基础。今天我和你分享的主题就是 etcd 的核心特性 Watch 机制设计实现,通过分析 Watch 机制的四大核心问题,让你了解一个变化数据是如何从 0 到 1 推送给 client,并给你介绍 Watch 特性从 etcd v2 到 etcd v3 演进、优化过程。
希望通过这节课,你能在实际业务中应用 Watch 特性,快速获取数据变更通知,而不是使用可能导致大量 expensive request 的轮询模式。更进一步,我将帮助你掌握 Watch 过程中,可能会出现的各种异常错误和原因,并知道在业务中如何优雅处理,让你的服务更稳地运行。

Watch 特性初体验

在详细介绍 Watch 特性实现原理之前,我先通过几个简单命令,带你初体验下 Watch 特性。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

etcd Watch机制是Kubernetes控制器的核心基础,通过监听、比较资源实际状态与期望状态的一致性来实现数据变化通知。本文深入介绍了etcd Watch机制的设计原理和优化,包括etcd v2和v3中client获取事件的机制、事件存储机制的演变、基于HTTP/2的gRPC协议实现的连接多路复用,以及etcd v3的MVCC机制。文章重点讨论了WatchableKV模块的工作原理,包括最新事件推送、异常场景重试机制和历史事件推送机制。此外,还介绍了etcd如何高效地根据变化的key快速找到监听它的watcher。总的来说,本文对于想要深入了解分布式存储Watch特性的读者具有很高的参考价值。 在获取事件机制、事件历史版本存储两个问题中,作者介绍了etcd v2在使用HTTP/1.x轮询、滑动窗口时,存在大量的连接数、丢事件等问题,导致扩展性、稳定性较差。而etcd v3 Watch特性优化思路是基于HTTP/2的流式传输、多路复用,实现了一个连接支持多个watcher,减少了大量连接数,事件存储也从滑动窗口优化成稳定可靠的MVCC机制,历史版本保存在磁盘中,具备更好的扩展性、稳定性。在实现可靠的事件推送机制问题中,作者通过一个整体架构图带你了解整个Watch机制的核心链路,数据推送流程。 Watch特性的核心实现模块是watchableStore,它通过将watcher划分为synced/unsynced/victim三类,将问题进行了分解,并通过多个后台异步循环 goroutine负责不同场景下的事件推送,提供了各类异常等场景下的Watch事件重试机制,尽力确保变更事件不丢失、按逻辑时钟版本号顺序推送给client。最后一个事件匹配性能问题,etcd基于map和区间树数实现了watcher与事件快速匹配,保障了大规模场景下的Watch机制性能和读写稳定性。 业务场景是希望agent能通过Watch机制监听server端下发给它的任务信息,简要实现如下,你认为它存在哪些问题呢? 它一定能监听到server下发给其的所有任务信息吗?欢迎你给出正确的解决方案。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《etcd 实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(22)

  • 最新
  • 精选
  • 当某个 key 发生变化的一定要去 key 的 watcher 区间树去查询是否对应的 watcher 吗? 这样会不会有很大的浪费,当一个系统 监听了一些不经常变的 key, 另一些经常变化的 key 没有对应的 watcher ,这样经常变化的key就会一直去查询key 的 watcher 区间树。 难道 key 不能直接知道是否有对应的 watcher 呢? (比如 key 的结构体记录一个 watcher Id 的数组)

    作者回复: 是的,一定会查,这性能开销很低的。正如我文章中所介绍的,有两类watcher, 一类是监听一个key的watcher,这种直接使用map来保存,也就是检查这个key是否有相关watcher,时间复杂度是o(1),另一类是监听整个区间的watcher,查找这个key落在了哪些watcher监听的范围,一般情况下,时间复杂度o(log n), n是你创建的watcher数。而你建议的方案,使用key结构体记录一个watcher id数组,这在key非常多的情况下,内存开销是非常大,假设一个watcher监听了一个非常大的key范围,那么etcd创建此watcher的时候,还需要遍历这个key范围,给key增加相应的watcher id, 不仅内存,cpu开销也是不可忽略的。 在哪些场景下watcher事件通知性能会非常慢呢?如果你成千上万个watcher,监听同一个key或者范围时,就会导致性能极差。

    2021-02-06
    2
    17
  • 七里
    如何保证WatchableKV 模块启动的syncVictimsLoop是可靠的呢?机器重启了怎么办?

    作者回复: 好问题,整个watch链路的可靠性,不能光靠server,从业务逻辑正确使用watch api到client watch中断重试机制,再到本讲介绍的server推送机制,层层相连才能尽量保证watch事件可靠性。如果机器重启了,这时就依赖client库的重试机制了,client收到每个watch事件时,会记录收到的版本号,连接到新节点后,再次创建watcher时会带上这个版本号,然后就会进入历史数据同步逻辑。

    2021-02-07
    14
  • 写点啥呢
    请问下老师,如果etcd集群某个节点崩溃或者网络问题导致client/server间连接断开,etcd是如何处理watch重新连接?如果是在另外一个节点重连后,etcd如何确定哪些event已经发送来避免event重复发送呢? 谢谢老师

    作者回复: etcd clientv3 watch库有中断重连、恢复机制,它会记录上次已收到的watch事件版本号,重启到新节点后,创建watcher的时候会带上这个版本,这样就可以尽量避免event重复发送哈,你可以使用etcd 3.4.9版本自己测试体验下。

    2021-02-05
    8
  • 带 --rev 版本号的监听,不是从需要监听某个 key 的某个指定的版本开始吗? 文章中怎么写的是集群的版本号

    作者回复: 版本号是集群的逻辑时间,参考07,监听key时,你可以指定任意一个时间点,过去、未来的版本号都可以。

    2021-02-05
    1
  • 八台上
    想问一下 每个key 有没有时间戳呢 想看真实的创建时间

    作者回复: 目前没有,你可以通过版本号信息来判断对比key的创建、修改时间等,它是个逻辑时间

    2021-08-03
  • BeanNan
    想问下老师,思考题的答案在哪有解惑?
    2022-01-04
    3
  • 谢小路
    学 etcd 还是需要些功底的,基础薄弱应该看不懂这些。
    2021-04-07
    1
    3
  • Geek_7d539e
    有一个地方没有写明: watch 通过 raft 通讯模块,传播到各个节点,也就是给个节点都有这个 watch(id) ,key 的 put 更新操作,给个节点自然都能监听到该 key 的变化,那么是各个节点都会去通知这个变化吗?还是就只有一个节点会去通知 client ?我本人猜测是,每个节点都会去通知,但是并不是每个节点都有 client watch steam ,没有连接 stream 就自然丢弃通知,有 stream 才会去落实通知。请老师释疑下,多谢。还有顺道多问一个问题,put 请求是单 key 的事务操作吗?
    2021-07-27
    4
    1
  • Geek_539c73
    越底层,越是数据结构
    2023-07-26归属地:北京
  • 踏雪无痕
    “同时当 watch 连接的节点故障,clientv3 库支持自动重连到健康节点,并使用之前已接收的最大版本号创建新的 watcher,避免旧事件回放等。” 作者你好,请问这一段话有没有对应的官网文档相关内容,我找了下没找到。
    2023-06-27归属地:浙江
收起评论
显示
设置
留言
22
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部