需要从服务实例中选出一个 leader ,从事一些必须“全局唯一”的事情。
当 leader 因为各种原因下线后,其它实例要能及时选举出新 leader 。
要求依赖别太重,或者依赖常用组件服务,比如 redis 。还要考虑这个依赖的组件服务可能掉线可能重连。
需要从服务实例中选出一个 leader ,从事一些必须“全局唯一”的事情。
当 leader 因为各种原因下线后,其它实例要能及时选举出新 leader 。
要求依赖别太重,或者依赖常用组件服务,比如 redis 。还要考虑这个依赖的组件服务可能掉线可能重连。
|
okayanJan 6, 2023
1
如果是在 kubernetes 集群里的话,可以直接用 k8s.io/client-go/tools/leaderelection
|
|
SomeMoreJan 6, 2023
2
好像记得 zookeeper 也有这个功能吧
|
|
ikarosJan 6, 2023
3
基于 raft 写个状态机,不过感觉有点杀鸡用牛刀 https://github.com/hashicorp/raft
|
|
4
@lion250258 可能没 zookeeper 这个或这类组件。
但 redis 应该都有 |
|
stillFoxJan 6, 2023
5
不想要有重的外部依赖的话,自己现实的工作量也会很重哦。感觉这个开发成本并不一定比外部组件的维护成本低。我记得早期 kafka 的选主也是依赖 zookeeper 来实现的。后来才去掉了。
|
|
virusdefenderJan 6, 2023
6
需求不是特别严格的话不难,比如找一个基于数据库或者 redis 的锁的库就行,但是会有一些细节上的问题,比如 redis 可能是单点,要是用集群的话,数据同步可能有延迟,一些极端情况下可能还是不可用或者出现竞争等。
|
|
zoharSoulJan 6, 2023
7
zookeeper 算常用组件了吧, 用这个就可以呀
|
|
aqqwiythJan 6, 2023
8
redis 原子操作 put 一个 value 为节点的 IP, 然后配置 key 15 秒过期. 5 秒维持一次过期时间.
value 为节点 IP 的就是 leader, leader 挂了之后 15 秒之后 put 成功的就是下一个 leader |
|
littlewingJan 6, 2023
9
embedded etcd
|
|
10
leader 这东西类似于分布式锁,可以看看按照分布式锁的思路来做。每个实例起一个后台线程,定时去尝试获取分布式锁。对于获取锁成功的那个实例就是 leader ,然后定时去刷新过期时间。如果 leader 挂了,那么其他实例获得分布式锁的就是 leader 了
|
|
11
@littlewing 这个方案貌似不错。
不知道资源消耗多少?有实例代码吗? |
|
CEBBCATJan 6, 2023
12
可否对「“全局唯一”的事情」举个例子?我是觉得常见业务不用 leader 选举也能做到独占,leader 选举这样的设计一般是为了保证同步
|
|
my3157Jan 6, 2023
13
|
|
potatowishJan 6, 2023 via iPhone
16
结合 10L 可以用 redis 分布式锁,按一定周期获取锁
|
|
sadfQED2Jan 6, 2023 via Android
19
为啥不考虑锁,而去搞个选举。选举要考虑各种情况的脑裂,问题一大堆。分布式锁 redis 几行代码就搞定了
|
|
TheCureJan 6, 2023
20
|
|
JuszoeJan 6, 2023
21
|
|
22
别听楼上什么分布式锁 redis 几行代码就搞定了,
要是其他方案靠谱的话, 就不会有 paxos, raft 了 |
|
23
@teli 知道那些节点在线,那些不在线,上 /下线都有 event ,节点之间还可以广播数据,选个主还不简单,说个最 low 的方法,获取当前活着的节点列表,把 peer ip + port 转成 int ,选最小活着最大的
|
|
dusuJan 6, 2023 via iPhone
24
我这边项目选 leader 主要是为了节点挂了服务正常
所以 redis 的 ping 锁操作可以 但是不适应于异地集群 而且也有单点问题 目前我的简单的解决方案: 用 cloudflare 的 kv 服务代替 redis 使用 |
|
misaka19000Jan 6, 2023
25
直接 redis 分布式锁啊,redis 用哨兵实现高可用就行了
|
|
joesonwJan 7, 2023 via iPhone
26
redis setnx 。slave 到 master 断了再去抢,其余的没抢到的直接取值找到 master 是谁。
|
|
AmericanExpressJan 7, 2023
27
我们用的是改过的 paxos
3 个 replica ,1 leader 2 follower 但是实现挺复杂的 |
|
rrfengJan 7, 2023 via Android
28
最简单的肯定是借助现有的依赖啊,比如你用了数据库,那就在数据库里搞一条记录,所有实例来抢占就行了。
Redis 也行,有啥用啥。 |
|
defageJan 7, 2023
29
我记得 etcd 有个嵌入的 lib 可以直接用,不是自己部署 etcd 服务,是自己用它的 sdk
|
|
31
|
|
xsenJan 7, 2023
32
|
|
litguyJan 7, 2023
33
etcd 的锁机制就可以完成你的功能
几年前我们就是基于这个作的 |
|
sujin190Jan 7, 2023 via Android
34
既然如此,直接实现成分布式锁的逻辑就是了呗,谁获取锁成功谁就能操作或者是 leader
|
|
solosJan 7, 2023
35
|
|
evil0harryJan 7, 2023
36
@okayan 404
|
|
clownpieceJan 7, 2023
37
如果 redis 集群出现故障导致你们 leader 选举出现问题如重复或者无 leader ,那是你们团队的锅,因为 redis 不提供保证。如果用 zk 或者 etcd 出现问题,是对应组件 dba 的锅。
所以选什么很明显了 |
|
starqoqJan 7, 2023
38
西方的选举制度可能不适合我们中国的程序呢。建议程序们开一个党代会选出全局唯一的核心。狗头。
|
|
ihciahJan 7, 2023 via iPhone
39
redis 选主没什么问题,简单方便,还不要求节点之间的连通性。
raft/etcd 杀鸡用牛刀了,你说它能用吧,它确实能用。为啥 etcd 不用 redis ?因为 redis 是单机服务,而 etcd 想解决的就是单点故障。只要你保证 redis 不宕机,那走 redis 就是个 ok 的方案。生产环境不少就是这么选主的,业务自个用 raft 的倒是一个没见过。 |
|
nxcdJaNnmyF9O90XJan 7, 2023
40
@starqoq 还要考虑 做到两个维护
|
|
F281M6Dh8DXpD1g2Jan 7, 2023
41
zookeeper 完事,别给自己找不愉快
|
|
ComolliJan 8, 2023 via iPhone
42
Redis vs Etcd vs memberlist vs paxos ,m
|
|
okayanJan 8, 2023
43
|
|
lance6716Jan 8, 2023 via Android
45
https://pkg.go.dev/go.etcd.io/etcd/clientv3/concurrency#Election.Campaign
麻了现在 golang 看上去很火,怎么看评论好像没啥真正在用的 |
|
lysSJan 9, 2023
46
楼上提 redis 的是怎么搞的,和在 go 里面用一个锁有什么区别?
|
|
ChinsungJan 9, 2023
47
一般是集群每台都尝试去做,但是拿到锁的那台再去做,这个都不要求主备一致性的,有啥必要上 paxos 和 raft 这种?
|
|
wei2629Jan 9, 2023
48
用 consul 抢占 session 就行了。
|