有没有办法实现简单的 Go 服务 leader 选举?

2023-01-06 18:15:00 +08:00
 teli

需要从服务实例中选出一个 leader ,从事一些必须“全局唯一”的事情。

当 leader 因为各种原因下线后,其它实例要能及时选举出新 leader 。

要求依赖别太重,或者依赖常用组件服务,比如 redis 。还要考虑这个依赖的组件服务可能掉线可能重连。

5653 次点击
所在节点    Go 编程语言
48 条回复
okayan
2023-01-06 18:18:35 +08:00
如果是在 kubernetes 集群里的话,可以直接用 k8s.io/client-go/tools/leaderelection
lion250258
2023-01-06 18:21:30 +08:00
好像记得 zookeeper 也有这个功能吧
ikaros
2023-01-06 18:22:11 +08:00
基于 raft 写个状态机,不过感觉有点杀鸡用牛刀 https://github.com/hashicorp/raft
teli
2023-01-06 18:25:54 +08:00
@lion250258 可能没 zookeeper 这个或这类组件。
但 redis 应该都有
stillFox
2023-01-06 18:26:05 +08:00
不想要有重的外部依赖的话,自己现实的工作量也会很重哦。感觉这个开发成本并不一定比外部组件的维护成本低。我记得早期 kafka 的选主也是依赖 zookeeper 来实现的。后来才去掉了。
virusdefender
2023-01-06 18:28:45 +08:00
需求不是特别严格的话不难,比如找一个基于数据库或者 redis 的锁的库就行,但是会有一些细节上的问题,比如 redis 可能是单点,要是用集群的话,数据同步可能有延迟,一些极端情况下可能还是不可用或者出现竞争等。
zoharSoul
2023-01-06 18:36:57 +08:00
zookeeper 算常用组件了吧, 用这个就可以呀
aqqwiyth
2023-01-06 18:40:23 +08:00
redis 原子操作 put 一个 value 为节点的 IP, 然后配置 key 15 秒过期. 5 秒维持一次过期时间.

value 为节点 IP 的就是 leader, leader 挂了之后 15 秒之后 put 成功的就是下一个 leader
littlewing
2023-01-06 18:49:51 +08:00
embedded etcd
hscxrzs
2023-01-06 19:17:49 +08:00
leader 这东西类似于分布式锁,可以看看按照分布式锁的思路来做。每个实例起一个后台线程,定时去尝试获取分布式锁。对于获取锁成功的那个实例就是 leader ,然后定时去刷新过期时间。如果 leader 挂了,那么其他实例获得分布式锁的就是 leader 了
teli
2023-01-06 19:22:39 +08:00
@littlewing 这个方案貌似不错。
不知道资源消耗多少?有实例代码吗?
CEBBCAT
2023-01-06 19:25:58 +08:00
可否对「“全局唯一”的事情」举个例子?我是觉得常见业务不用 leader 选举也能做到独占,leader 选举这样的设计一般是为了保证同步
my3157
2023-01-06 19:27:50 +08:00
teli
2023-01-06 19:35:17 +08:00
@CEBBCAT 目前需求是全局只有一个实例在干这事
luyifei
2023-01-06 20:05:57 +08:00
@ikaros raft + 1 ,可以看一下 mit 的 6.824 ,就是用 raft 写的一个分布式 kv 服务
potatowish
2023-01-06 20:12:17 +08:00
结合 10L 可以用 redis 分布式锁,按一定周期获取锁
teli
2023-01-06 20:14:08 +08:00
@my3157 看起来很牛掰。但没发现支持 leader 特性。有什么好办法基于这个实现 leader 选举吗?
teli
2023-01-06 20:16:36 +08:00
@hscxrzs 我首先想到的也是这个办法。但上面有位朋友提醒了我,如果是集群,同步会有延迟。这个有什么好应对办法?
sadfQED2
2023-01-06 20:26:45 +08:00
为啥不考虑锁,而去搞个选举。选举要考虑各种情况的脑裂,问题一大堆。分布式锁 redis 几行代码就搞定了
TheCure
2023-01-06 20:28:05 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/907067

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX