共计 1151 个字符,预计需要花费 3 分钟才能阅读完成。
前沿
K8s client-go 中,源生自带了一个 leader 库,便于实现分布式工夫锁。
分布式工夫锁应用场景
以 K8s 原生的 controller-manager 组件为例,当有三台 master 机器时,默认会运行三个 controller-manager 实例,但只有一个在干活,另外两个处于备用状态。而这个性能的实现,就依赖于分布式工夫锁。
工夫锁配置阐明
所有相干配置如下图所示:
锁的持有者,会每隔 retryPeriod 更新锁的有效期,示意它始终在持有这把锁。
特地阐明下两个参数:
一. leaseTimeout
- 举个例子:当初有个房间,我要求当有人进入房间时,下一个人至多期待 1 小时才可进入房间。这时,咱们能够将 leaseTimeout 设置为 1 小时,每当有人进入房间,则将房门上的时候改为以后工夫。下一个人筹备进入时,必须查看房门上的工夫间隔以后工夫超过 leaseTimeout。
- 之所以要这样设计,是因为在分布式状况下,只有程序活着的时候才能够要求它干什么,而一旦它异样了,它就失控了。而为了避免在它异样时,其它活着的程序能够失常接替它,所以就约定了 leaseTimeout,一旦超过这个工夫,则间接认定它异样,能够接管。
二. renewDeadline
- 下面的约定,无奈避免脑裂。因为锁持有者在 leaseTimeout 中未更新锁,并不代表它曾经挂了,它可能只是因为其它起因无奈更新锁,或者程序夯住了,之后它可能再复原。而如果它在他人接替它后,原持有者再复原运行,则会导致脑裂,为了避免这种状况产生,针对锁持有者就设置了 renewDeadline
- 如果锁持有者如果无奈在 renewDeadline 工夫内实现锁的更新,则要求锁持有者强制开释锁,程序退出。
- 所以 renewDeadline 必须比 leaseTimeout 小
leader 运行流程
下面流程很清晰,上面独自具体讲下:
尝试获取锁并更新锁
选举时序图
从下面获取锁流程,除了第一次创立锁之外,选举的要害就是察看工夫: observedTime
- id1 异常情况
- id1 网络异样无奈更新锁
从时序图中可看进去,监听工夫的必要性。所有的 flower(待接替者)都必须更新本地监听工夫,必须保障在 renewDeadline 工夫中,锁未产生任何变动,否则就须要再从新选举。
当然,还有一种极其状况:两个 flower 同时发现锁未产生任何变动,同时尝试去获取锁,这个时候就须要用到 etcd 的 resourceVersion 机制:在 update 时须要上送查问时的 resourceVersion,示意在这过程中该资源未产生过其它更新。
原理就相似 sql 的 select for update –> 查问时锁定记录。在这种状况下,etcd 会保障先更新的能更新胜利,后更新的会失败。这样就保障这种极其状况不会脑裂。
正文完
发表至: kubernetes
2022-07-15