polarismesh / polaris

Service Discovery and Governance Platform for Microservice and Distributed Architecture

Home Page:https://polarismesh.cn

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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 的实现:

  1. 选主依赖原子操作 update leader_election set leader_id = ?, version = version + 1 where service_id = ? and version = ?,只会有一个实例更新成功获得 leader 身份;
  2. leader 身份的维护通过周期性(tick)原子更新 version 和 update_time 实现;(这里需要原子更新的原因是,leader如果长时间卡住,需要感知自己已经失去leader身份)
  3. 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

限制

  1. leader 挂掉的感知时间为 lease
  2. 允许 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 仅作为内部能力,相关参数不对外用户暴露。