美文网首页
如何高效获取数据变化通知

如何高效获取数据变化通知

作者: 一生逍遥一生 | 来源:发表于2021-03-25 11:39 被阅读0次

etcd的Watch特性是Kubernetes控制器的工作基础。

Kubernetes中watch特性,有四大核心问题:

  • client获取事件的机制,etcd使用轮询模式还是推送模式,两者各有什么缺点
  • 事件是如何存储的?会保留多久?watch命令汇总的版本号具有什么作用?
  • client和server发生短暂网络波动等异常因素后,导致事件堆积时,server端会丢弃事件吗?若监听的历史版本号server端不存在了,应该如何处理
  • 创建了上万个watcher监听key变化,当server端收到一个写请求后,etcd是如何根据变化的key快速找到监听它的watcher

获取事件的机制

client获取事件机制,分为两种:轮询和推送,两种机制etcd都使用过。
在etcd v2 Watch机制实现中,使用的是HTTP/1.x,实现简单、兼容性好,每一个watcher对应一个TCP连接。client通过HTTP/1.x协议长连接定时轮询
server,获取最新的数据变化事件。
etcd v3使用基于HTTP/2的gRPC的协议,双向流的watch API设计,实现了连接多路复用,并且HTTP消息被分解成为独立的帧,交错发送,帧是最小的数据单位。
每个帧会表示属于那个流,流有多个数据帧组成,每一个流拥有一个唯一ID,一个数据流对应一个请求或响应包,用来解决请求阻塞、连接无法复用,
实现多路复用、乱序发送。

一个client支持多个gRPC Stream,一个个gRPC Stream支持多个watcher,显著降低了开发复杂度。当watch连接的节点故障, etcd v3库支持带
自动重连到健康节点,并使用之前已接收的最大版本号创建新的watcher,避免旧事件回放等。

轮询消耗资源

事件是如何保存的,保存多长事件,版本号的作用

事件是如何保存的,保存多长事件,版本号的作用的本质是历史版本存储。
滑动窗口是仅保存有限的最近历史版本到内存中,MVCC机制则将历史版本保存在磁盘中,避免了历史版本的丢失,极大的提升了watch机制的可靠性。

etcd v2的滑动窗口是如何实现的:

  • 使用环形数组来存储历史事件版本,当key被修改后,相关事件就会添加到数组中来。
  • 如果超过eventQueue的容量,淘汰最旧的事件,容量为1000,如果超过1000条数据,可能会造成OOM。
  • 只能保存有限的历史版本事件版本,是不可靠的。当请求多、网络波动等异常时,会导致事件丢失,发起多次请求。

etcd v3的MVCC:将一个key的历史修改版本保存到boltdb里面。

watch命令的版本号作用:版本号是etcd逻辑时钟,出现网络波动等异常时,通过版本号,可以获取到错过的历史版本,不需要全量同步,是etcd Watch
机制数据增量同步的核心。

可靠的事件推送机制

etcd核心解决方案是复杂度管理,问题拆分。
etcd按照watcher的类型不同分为:synced watcher、unsynced watcher。
synced watcher表示此类watcher监听的数据都已经同步完毕,在等待新的变更。
创建的watcher未指定版本号、或指定的版本号大于etcd server当前最新的版本号,那么它就会保存到synced watcherGroup中。watcherGroup负责管理多个
watcher,能够根据key快速找到监听该key的的一个或多个watcher。

unsynced watcher:表示此类watcher监听的数据还未同步完成,落后于当前最新数据变更,正在努力追赶。

synced和unsynced的区别:synced和最新的版本号一致,不存在数据差异,unsyned落后于最新版本号,存在数据差异。

最新事件推送机制

请求经过KVServer、Raft模块后Apply到状态机时, 在MVCC的put事务中,它会将本次修改后的mvccpb.KeyValue保存到一个changes数组中。
将KeyValue转换成为Event事件,然后回调watchableStore.notify函数。notify会匹配出监听过此key并处于synced watherGroup中的watcher,
同时事件中的版本号要大于等于watcher监听的最小版本号,才能将事件发送到此watcher的事件channel中。
serverWatchStream的sendLoop goroutine监听到channel消息后,独处消息立即推送到client。

异常场景重试机制

若出现channel buffer满的情况,将此watcher从synced watcherGroup中删除,将其添加到vitim的watcherBatch结构中,通过异步机制
重试保证事件的可靠性。

WatchabkeKV模块会启动两个异步goroutine,其中一个是syncVitimLoop:负责slower watcher的堆积的事件推送:遍历vitim watcherBatch数据结构,将数据推送出去,
如果推送失败,进行重试;如果推送成功,将小于server当前版本号加入到unsynced watcherGroup,如果watcher的最小版本号大于server当前版本号,加入到
synced watcher集合。

历史事件推送机制

WatchableKV模块的另一个goroutine:syncWatchersLoop,正是负责unsynced watchergroup中的watch历史事件推送。
syncWatcherLoop会选择一批unsynced watcher批量同步,选出这一批unsynced watcher中监听的最小版本号,因为boltdb的key是按照版本号存储的,
通过指定查询key范围的最小版本号作为开始区间,当前server最大版本号作为结束区间,遍历boltdb获得所有历史数据。

高效事件匹配

区间树支持快速查找一个key是否在某个区间内,事件复杂度为O(LogN),因此etcd基于map和区间树实现了watcher与事件的快速匹配,具有良好的扩展性。

相关文章

  • 如何高效获取数据变化通知

    etcd的Watch特性是Kubernetes控制器的工作基础。 Kubernetes中watch特性,有四大核心...

  • MySQL索引原理

    定义 索引(Index)是帮助MySQL高效获取数据的数据结构。那么什么数据结构可以用来高效的获取数据呢? 查看索...

  • MySQL索引

    什么是索引 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构 数据库如何查询...

  • 对实践 去Model化的一点体验

    前言 在实践 casa 的去Model化后,为了解决网络数据获取后如何处理、如何更新、如何监听模型数据变化等一系列...

  • CMDB 详解

    什么是 CMDB? “CMDB 即配置管理数据库,通过获取、维护,检查企业的IT资源,从而高效控制与管理不断变化的...

  • 线性结构:数组

    什么是数据结构? 数据结构研究的是数据如何在计算机中进行组织和存储,使得我们可以高效的获取数据或者修改数据。 数组...

  • 数据库原理及其应用(一)

    20世纪60年代末诞生。 数据库技术是专门研究如何科学的组织和存储数据、如何高效的获取和处理数据的技术。已成为各行...

  • 第一章 开始学习数据结构

    为什么要学习数据结构 数据结构研究的是数据如何在计算机中进行组织和存储,使得我们可以高效的获取数据或者修改数据。 ...

  • 玩转数据结构之序言

    0. 本质 数据结构研究的是数据如何在计算机中进行组织和存储。 1. 目的 为了高效地获取数据和修改数据。 2. ...

  • mysql快速插入百万条数据

    前言 假设现在我们要向mysql插入500万条数据,如何实现高效快速的插入进去?暂时不考虑数据的获取、网络I/O、...

网友评论

      本文标题:如何高效获取数据变化通知

      本文链接:https://www.haomeiwen.com/subject/dumlhltx.html