polaris-server leader 选举功能模块
shichaoyuan opened this issue · comments
背景
由 #775 引出 polaris-server 需要一个 leader 选举模块,选出一个 leader 执行一些协调性的任务
问题 issue 中 polaris.checker 存在脏实例,所以复用现有的自注册机制选择 id 最小的实例并不能解决问题,这里的选主模块需要独立于 polaris 的自注册机制。
方案
基于 store 层实现选举,对上层提供接口
type LeaderElection interface {
IsLeader() bool
}
基于 mysql 的实现:
- 选主依赖原子操作
update leader_election set leader_id = ?, version = version + 1 where service_id = ? and version = ?
,只会有一个实例更新成功获得 leader 身份; - leader 身份的维护通过周期性(tick)原子更新 version 和 update_time 实现;(这里需要原子更新的原因是,leader如果长时间卡住,需要感知自己已经失去leader身份)
- follower 周期性(tick)检查 leader 是否存活,如果
UNIX_TIMESTAMP(SYSDATE()) - update_time
超过了设定的“租约(lease)”,尝试第1步竞争 leader 身份。
配置
# 存储配置
store:
# 数据库存储插件
name: defaultStore
option:
master:
dbType: mysql
dbName: polaris_server
dbUser: ##DB_USER##
dbPwd: ##DB_PWD##
dbAddr: ##DB_ADDR##
maxOpenConns: 300
maxIdleConns: 50
connMaxLifetime: 300 # 单位秒
txIsolationLevel: 2 #LevelReadCommitted
leaderelection:
open: true
tick: 1s
lease: 10s
限制
- leader 挂掉的感知时间为 lease
- 允许 tick 时间窗内两个 leader 并存
其他sql数据库都支持类似的操作,如果之后扩容 raft 协议的内嵌数据库也很容易支持。
leaderelection 或许应该是要默认只能开启?
同时还有另外一个问题,这个 LeaderElection 需要支持不同的功能组之间,leader各自选举吗?比如一组功能的leader和另一组功能的leader可以各自进行 election
同时还有另外一个问题,这个 LeaderElection 需要支持不同的功能组之间,leader各自选举吗?比如一组功能的leader和另一组功能的leader可以各自进行 election
这可能取决于leader的任务的数量,如果有很多的任务,分一下组比较合适;如果像kafka的controller那样,那么一个就够了,并且默认开启。
同时还有另外一个问题,这个 LeaderElection 需要支持不同的功能组之间,leader各自选举吗?比如一组功能的leader和另一组功能的leader可以各自进行 election
这可能取决于leader的任务的数量,如果有很多的任务,分一下组比较合适;如果像kafka的controller那样,那么一个就够了,并且默认开启。
也是,目前先不过度考虑了
LeaderElection 仅作为内部能力,相关参数不对外用户暴露。