了解etcd(二)

在这里插入图片描述etcd在选举投票的时候,当follower收到来自candidater的请求后,它会看candidater的数据至少和自己的一样新,它的任期号大于自己的任期号,并且自己没有投票给其他人,follower变成candidater后自己的任期会加1,当leader坏掉以后,恢复之后不会获得集群leader地位,是因为自身的数据是落后其他节点的

leader节点主动上报特殊心跳,汇报健康状态,如果follower没有收到心跳,它就有发生选举行为,etcd的主动型上报模式是lease,它是client和etcd server之间存在的一个约定,内容是etcd server保证在有效期(TTL)内不会删除关联到lease上的key-value,

etcd 在启动的时候,创建 Lessor 模块的时候,它会启动两个常驻 goroutine,一个是 RevokeExpiredLease 任务,定时检查是否有过期 Lease,发起撤销过期的 Lease 操作。一个CheckpointScheduledLease,定时触发更新 Lease 的剩余到期时间的操作。Lessor 模块提供了 Grant、Revoke、LeaseTimeToLive、LeaseKeepAlive API 给 client 使用,各接口作用如下:
Grant 表示创建一个 TTL 为你指定秒数的 Lease,Lessor 会将 Lease 信持久化存储在boltdb 中;
Revoke 表示撤销 Lease 并删除其关联的数据;
LeaseTimeToLive 表示获取一个 Lease 的有效期、剩余时间;
LeaseKeepAlive 表示为 Lease 续期。
当我们使用–lease操作一个key时候mvcc模块会通过lessor模块的attach方法把key关联到lease的key内存集合itemset中,boltdb中保存了lease信息,lease续约就是把lease的过期时间更新为系统时间加TTL,lossor模块的一个异步goroutine定时的从最小堆中取出已经过期的lease,为了解决leader频繁切换,切换时间小于lease的ttl会导致lease永远无法删除,引入了checkpointscheduledleases,一方面,etcd 启动的时候,Leader 节点后台会运行此异步任务,定期批量地将 Lease 剩余的TTL 基于 Raft Log 同步给 Follower 节点,Follower 节点收到 CheckPoint 请求后,更新内存数据结构 LeaseMap 的剩余 TTL 信息。另一方面,当 Leader 节点收到 KeepAlive 请求的时候,它也会通过 checkpoint 机制把此Lease 的剩余 TTL 重置,并同步给 Follower 节点,尽量确保续期后集群各个节点的 Lease 剩余 TTL 一致性

Lease 的核心是 TTL,当 Lease 的 TTL 过期时,它会自动删除其关联的 key-value 数据。首先是 Lease 创建及续期。当你创建 Lease 时,etcd 会保存 Lease 信息到 boltdb 的 Leasebucket 中。为了防止 Lease 被淘汰,你需要定期发送 LeaseKeepAlive 请求给 etcd server续期 Lease,本质是更新 Lease 的到期时间。续期的核心挑战是性能,etcd 经历了从 TTL 属性在 key 上,到独立抽象出 Lease,支持多key 复用相同 TTL,同时协议从 HTTP/1.x 优化成 gRPC 协议,支持多路连接复用,显著降低了 server 连接数等资源开销。其次是 Lease 的淘汰机制,etcd 的 Lease 淘汰算法经历了从时间复杂度 O(N) 到 O(Log N)的演进,核心是轮询最小堆的 Lease 是否过期,若过期生成 revoke 请求,它会清理 Lease和其关联的数据。最后我给你介绍了 Lease 的 checkpoint 机制,它是为了解决 Leader 异常情况下 TTL 自动被续期,可能导致 Lease 永不淘汰的问题而诞生

etcd是通过mvcc实现的多版本控制,基于mvcc实现了watch机制,mvcc是一个乐观锁实现的多版本控制,它乐观的认为不会冲突,在提交的时候具有冲突检测的能力,每个数据都对应一个版本号,mvcc把请求分为两个部分,读事务和写事务,读事务处理range,写事务处理put,treeindex处理读写事务,treeindex基于Btree保存了key与版本的映射关系,为什么要用btree,因为etcd要范围查询,在treeindex中通过keyindex保存key与版本的映射关系,keyindex包含用户的key,最后一次修改的版本号,key的若干代generation的信息,它是一个数组,包含了key的修改次数,generation创建时的版本号,对key修改的记录,revision是一个结构体,它包括main和sub,main是全局的,sub是事务内的,当我们第一次更新一个数据的时候,它的keyindex为空,全局revision自增,初始值为1,现在变成revision{2,0}这是boltdb的key,boltdb的value包含,用户的key,value,create_revision,mod_revision,version 和lease首次创建会生成keyindex对象,当我们读的时候通过key在keyindex中获取到版本号,根据版本号先从buffer中读,读不到从boltdb中读取,当我们删除一个key的时候,etcd采用的是一个延时删除,真正删除是通过compator实现的,只要压缩组件没有回收历史版本,我们就可以找到他的值
在这里插入图片描述apiserver与etcd之间保持watch,所以当我们修改了deployment里的镜像的时候,控制器就是通过watch机制高效的获取到新的期望状态,etcdv3使用基于http2的grpc,实现了多路复用,实现是基于帧的交错发送,client获取事件也从轮训变成了server推送,watch机制可以从boltdb中获取到错过的事件是依靠mvcc模块,当etcdctl收到一个watch请求的时候会创建一个serverwatchstream,当它收到一个create watcher的时候会将watcher注册到mvcc模块里的watchableKv模块,它有两个重要功能syncwatchloop和syncvictimloop,如果watch的版本大于etcd当前的版本,那么会交给synced watcher不然交给unsynced watcher,那它的最新事件怎么推送呢,serverwatchstream中的sendloop giroutine监听到channel后,把消息推送给client,通过将watcher保存到一个名为victim的watchbatch中来处理异常场景重试,老版本被压缩后,syncwatchloop 遍历unsynced,从中取出版本最小的,然后把它同步到synced中,watch机制通过map和区间树实现了高效匹配
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值