FireflySoft.LeaderElection的第一个版本实现了基于Consul的Leader选举,考虑到ZooKeeper的一个常见用途也是选主,所以此类库把ZooKeeper也集成了进来。并且进行了多项优化,比如在Leader断开连接时增加了一个Leader选举失败的事件,防止集群产生脑裂问题。

GitHub地址:https://github.com/bosima/FireflySoft.LeaderElection

代码结构

下边先来张图,了解下代码结构:

从上图可以看到,此类库可以方便的添加其它Leader选举支持程序,只要按照规范实现ILeaderElection接口就可以了,有兴趣的可以试试。

使用说明

下边继续对基于Consul和ZooKeeper的Leader选举进行详细说明。

基于Consul

原理

1、参加选举的程序可以在Consul中创建一个Session,这个Session的存活状态依赖于当前程序的Consul健康检查状态, 一旦健康检查处于Critical状态,则对应的Session就会失效。

2、使用这个Session去锁定某个Consul Key/Value,只有一个Session能成功锁住KV,拥有这个Session的程序即为Leader。

3、Leader选举成功后,所有节点还要继续阻塞查询上边的Consul Key/Value,如果KV绑定的Session失效了, 所有节点可以立即发现并发起一次Leader选举,并选举出1个Leader。

使用说明

1、准备Consul环境

这里为了方便使用本机Consul,此程序也支持配置远程Consul地址。

如果本地环境已经配置Consul,保证其正常运行即可。

如果本地环境没有配置Consul,可以下载后以开发模式快速启动,以方便体验Leader选举功能。

下载地址:https://www.consul.io/downloads

启动命令:./consul agent -dev

2、安装Nuget包

NuGet包地址:https://www.nuget.org/packages/FireflySoft.LeaderElection

3、编写Leader选举代码

以控制台程序为例:

    class Program
{
static void Main(string[] args)
{
Console.WriteLine("I am ElectionService1."); // 参与Leader选举的多个程序应该使用相同的服务名
// 参与Leader选举的每个程序应该有唯一的服务Id
LeaderElectionManager electionManager = new LeaderElectionManager("ElectionService", "ElectionService1", new ConsulElectionOptions());
electionManager.Watch(LeaderElectCompletedEventHandler); Console.WriteLine("Start Election..."); Console.Read();
} private static void LeaderElectCompletedEventHandler(LeaderElectionResult result)
{
// 在这里处理Leader选举结果。
Console.WriteLine($"LeaderElectCompleted, Result: {result.IsSuccess}, Current Leader: {result.State.CurrentLeaderId}.");
}
}

4、注意事项

ConsulElectionOptions中提供了一个重新选举沉默期:ReElectionSilencePeriod,默认10s。应用场景如下:

当一个程序的Leader状态失效时,它可能仍在处理某些事务,并且不能立即中止。这时候如果马上启动选举,并且开始处理数据,则可能导致数据不一致的状态。

基于ZooKeeper

原理

1、所有参与选举的程序都在ZooKeeper上发起创建一个相同路径的EPHEMERAL Node,只有一个程序能够创建成功,此程序即为Leader。

2、所有参与选举的程序都Watch上边创建的EPHEMERAL Node,Leader程序在ZooKeeper的会话过期后,这个Node会被删除,所有Watch的程序都会收到通知,从而发起新一轮选举。

使用说明

1、准备ZooKeeper环境

如果已经有搭建好的ZooKeeper集群,直接使用对应的地址就可以了。

如果没有,这里给出一个快速搭建ZooKeeper环境的方法:通过docker启动一个单节点ZooKeeper。

docker run --name zoo1 -p 8080:8080 -p 2181:2181 --restart always -d zookeeper

2、编写Leader选举代码

以控制台程序为例:

    class Program
{
static void Main(string[] args)
{
Console.WriteLine("I am ElectionService1."); // 参与Leader选举的多个程序应该使用相同的服务名
// 参与Leader选举的每个程序应该有唯一的服务Id
LeaderElectionManager electionManager = new LeaderElectionManager("ElectionService", "ElectionService1", new ZkElectionOptions());
electionManager.Watch(LeaderElectCompletedEventHandler); Console.WriteLine("Start Election..."); Console.Read();
} private static void LeaderElectCompletedEventHandler(LeaderElectionResult result)
{
// 在这里处理Leader选举结果。
Console.WriteLine($"LeaderElectCompleted, Result: {result.IsSuccess}, Current Leader: {result.State.CurrentLeaderId}.");
}
}

其它说明

Leader状态保持

在Consul中Leader状态取决于当前Leader程序的健康状态,该程序的健康状态依赖于程序自身的健康检查状态以及程序注册的Consul Agent的健康检查状态,只要有一个关联的健康检查状态不通过,程序就是非健康的,就会丢失Leader状态。(新版本的Consul中支持健康状态法定数目判定规则,此类库没有使用。)

在ZooKeeper中Leader状态依赖于选举成功时创建的临时ZooKeeper Node,Leader程序如果未在SessioinTimeout时间内与ZooKeeper通信,Node就会被删除,则Leader状态丢失。

无论是Consul健康检查机制,还是ZooKeeper临时Node保持机制,都依赖于应用程序与选举支持程序(即Consul、ZooKeeper等)之间的状态维护机制,这些机制都需要一定的时间进行确认,并非是完全实时的。

Leader优先选举权

此类库为Leader增加了优先选举权。应用场景如下:

Leader状态失效可能只是一种短暂的中断导致的,系统会很快自动恢复,而业务事务的的启动和中止需要进行复杂的处理, 所以我们仍然期望下一次Leader选举时之前的Leader有优先选举权,避免数据同步和加快系统恢复。

防脑裂

Leader断开与选举支持程序之间的连接时,选举支持程序会认为Leader已经下线,从而开启新的选举,选举出新的Leader,而原Leader并不能收到重新选举的通知,仍旧保持Leader状态,则就会同时存在两个Leader,也就是产生了脑裂问题。

此类库对这种问题进行了处理,应用程序会定时访问选举支持程序,一旦出现连接不上的情况,就会自动产生一条Leader选举失败的事件,应用程序可以据此进行降级处理。

FireflySoft.LeaderElection增加基于ZooKeeper的Leader选举的更多相关文章

  1. 面试官:说一说Zookeeper中Leader选举机制

    哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 今天又是一个阳光明媚的一天,我又 ...

  2. 【分布式】Zookeeper的Leader选举

    一.前言 前面学习了Zookeeper服务端的相关细节,其中对于集群启动而言,很重要的一部分就是Leader选举,接着就开始深入学习Leader选举. 二.Leader选举 2.1 Leader选举概 ...

  3. 简单理解Zookeeper的Leader选举【转】

    Leader选举是保证分布式数据一致性的关键所在.Leader选举分为Zookeeper集群初始化启动时选举和Zookeeper集群运行期间Leader重新选举两种情况.在讲解Leader选举前先了解 ...

  4. zookeeper应用 - leader选举 锁

    模拟leader选举: 1.zookeeper服务器上有一个/leader节点 2.在/leader节点下创建短暂顺序节点/leader/lock-xxxxxxx 3.获取/leader的所有子节点并 ...

  5. Zookeeper系列(十一)zookeeper的Leader选举详解(核心之一)

    作者:leesf    掌控之中,才会成功:掌控之外,注定失败. 出处:http://www.cnblogs.com/leesf456/p/6107600.html尊重原创,奇文共欣赏: 一.前言 前 ...

  6. 【分布式】Zookeeper的Leader选举-选举过程介绍(经典的Paxos算法解析)

    一.前言 前面学习了Zookeeper服务端的相关细节,其中对于集群启动而言,很重要的一部分就是Leader选举,接着就开始深入学习Leader选举. 二.Leader选举 2.1 Leader选举概 ...

  7. 简单理解Zookeeper的Leader选举

    Leader选举是保证分布式数据一致性的关键所在.Leader选举分为Zookeeper集群初始化启动时选举和Zookeeper集群运行期间Leader重新选举两种情况.在讲解Leader选举前先了解 ...

  8. 搞了个基于zookeeper的Leader/Follower切换Demo

    基于zookeeper写了个Leader选举类库demo,场景如下: 上图中的Program1..4可以部署在1台server上,也可以部署在多台server上,也可以是一个进程中的多个线程. 运行效 ...

  9. Zookeeper之Leader选举过程

    Leader在集群中是一个非常重要的角色,负责了整个事务的处理和调度,保证分布式数据一致性的关键所在.既然Leader在ZooKeeper集群中这么重要所以一定要保证集群在任何时候都有且仅有一个Lea ...

  10. zookeeper进行leader选举

    一.如何进行leader选举 创建 /lj/producer和/lj/master/producer外层节点 创建临时顺序节点 判断自己是否是master节点(判断流程:遍历/lj/producer节 ...

随机推荐

  1. 【故障公告】被放出的 Bing 爬虫,又被爬宕机的园子

    这些巨头爬虫们现在怎么了?记忆中2022年之前的十几年,园子没有遇到过被巨头爬虫们爬宕机的情况,巨头们都懂得爱护,都懂得控制节奏,都懂得在爬网时控制并发连接数以免给目标网站造成过大压力. 从去年开始, ...

  2. RTSP Server(LIVE555)源码分析(三)-DESCRIBE信令

    主要分析RTSPServer::RTSPClientSession针对客户端DECCRIBE信令处理. 一.回调函数incomingRequestHandler分析 回顾一下rtsp客户端sessio ...

  3. 安装Nodejs,执行npm命令异常

    异常现象: 在安装完成Nodejs之后,使用npm install时提示异常: 使用cmd查看npm版本,也报同样的错误. "operation not permitted, mkdir ' ...

  4. [Opencv-C++] 3. opencv数据类型

    文章目录 Point类 cv::Scalar类 size类 cv::Rect类 cv::RotatedRect类 固定矩阵类 固定向量类 复数类 工具函数 模板结构 Point类 在大多数程序中,Po ...

  5. 武装你的WEBAPI-OData Versioning

    本文属于OData系列 目录 武装你的WEBAPI-OData入门 武装你的WEBAPI-OData便捷查询 武装你的WEBAPI-OData分页查询 武装你的WEBAPI-OData资源更新Delt ...

  6. 2021-08-19:超级洗衣机。假设有 n 台超级洗衣机放在同一排上。开始的时候,每台洗衣机内可能有一定量的衣服,也可能是空的。在每一步操作中,你可以选择任意 m (1 ≤ m ≤ n) 台洗衣机,

    2021-08-19:超级洗衣机.假设有 n 台超级洗衣机放在同一排上.开始的时候,每台洗衣机内可能有一定量的衣服,也可能是空的.在每一步操作中,你可以选择任意 m (1 ≤ m ≤ n) 台洗衣机, ...

  7. vue全家桶进阶之路44:Vue3 Element Plus el_row和el_col组件

    在 Vue 3 中,Element Plus 也提供了 ElRow 和 ElCol 组件,用于实现栅格布局. ElRow 组件的常用属性: gutter:栅格间距,默认为 0. type:布局模式,可 ...

  8. 【重学C++】01| C++ 如何进行内存资源管理?

    文章首发 [重学C++]01| C++ 如何进行内存资源管理? 前言 大家好,我是只讲技术干货的会玩code,今天是[重学C++]的第一讲,我们来学习下C++的内存管理. 与java.golang等自 ...

  9. .Net使用第三方onnx或ModelBuilder轻松接入AI模型

    ML.Net - 开源的跨平台机器学习框架 支持CPU/GPU训练 轻松简洁的预测代码 可扩展其他的机器学习平台 跨平台 1.使用Visual Studio的Model Builder训练和使用模型 ...

  10. MySQL的sql语句执行流程(简述)

    导言: MySQL和服务器端对接的时候,我们知道一般就是服务器端会打包一些SQL命令去增删改查数据库,这个打包的数据库SQL语句数据包一般为4MB,再大一些就不会被数据库端接收了 但是我们可以自己更改 ...