基于Apache Curator框架的两种分布式Leader选举策略学习记录

应用场景

在分布式项目开发中,我们通常需要将某个程序部署到多个节点上面。但是要求程序的运行方式是一主多从,当主节点Master挂掉后,可以从剩余的节点中从新选举出新的Master节点来继续工作,对于Leader的选举策略,Apache Curator框架提供了两种策略,开发者可以根据实际需求具体选择:

策略1:LeaderLatch 参考:https://curator.apache.org/curator-recipes/leader-latch.html 

简要概括:这种选举方式是保持Leader一直当到底,除非调用close方法,才会进行重新选举,因此这种方式适合不需要频繁切换Leader的情况;

策略2:LeaderElection 参考:https://curator.apache.org/curator-recipes/leader-election.html

简要概括:这种选举方式是会让众多的节点轮流当Leader,通俗来说就是轮流做大哥,当LeaderSelectorListenerAdapter类中的takeLeadership方法执行完毕,Leader就会释放当Leader的权利,然后重新竞选新的Leader,这就保证了,大家都有做大哥的机会,因此这种方式适合需要频繁切换Leader的情况;

添加依赖

compile group: 'org.apache.curator', name: 'curator-recipes', version: '4.2.0'

策略1:LeaderLatch (初始化多个LeaderLatch,然后自动选出Leader) 代码展示

public class MyLeaderLatch {
	private String name; // Latch名称
	private LeaderLatch leaderLatch;
	private LeaderTask leaderTask; // Leader当选之后需要做的事情
	private String PATH = "/latchPath"; // Latch Path

	public MyLeaderLatch(CuratorFramework client, String name, LeaderTask leaderTask) {
		this.name = name;
		this.leaderTask = leaderTask;
		this.leaderLatch = new LeaderLatch(client, PATH); //初始化LeaderLatch
	}

    //创建任务接口,外部提供实现
	public interface LeaderTask {
		public void doTASK();
	}

    //自定义LeaderLatch监听器
	private class MyLeaderLatchListener implements LeaderLatchListener {
		private String name;
		private LeaderTask leaderTask;

		public MyLeaderLatchListener(String name, LeaderTask leaderTask) {
			this.name = name;
			this.leaderTask = leaderTask;
		}

		@Override
		public void isLeader() {
			System.out.println(name + " say : I am become a leader!");
			this.leaderTask.doTASK();
		}

		@Override
		public void notLeader() {
			// do something
		}
	}
    //启动LeaderLatch
	public void start() throws Exception {
		leaderLatch.start();
        //为LeaderLatch添加监听器
		leaderLatch.addListener(new MyLeaderLatchListener(this.name, this.leaderTask));
	}

    //关闭LeaderLatch,释放Leader权力
	public void close() throws Exception {
        System.out.println(name + " say : I am no longer a leader!");
		leaderLatch.close();
	}
}
  • 测试代码
public class MyTest {
	CuratorFramework client = null;

    //测试之前初始化CuratorFramework
	@Before
	public void beforeTest() {
		String zkServerAddress = "127.0.0.1:2181";
		ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3, 5000);
		client = CuratorFrameworkFactory.builder().connectString(zkServerAddress).sessionTimeoutMs(5000)
				.connectionTimeoutMs(5000).retryPolicy(retryPolicy).build();
		client.start();
	}
    //创建5个LeaderLatch竞选Leader
	@Test
	public void testMyLeaderLatch() throws Exception {
		for (int i = 1; i <= 5; i++) {
			MyLeaderLatch selector = new MyLeaderLatch(client, "Latch-" + i, new MyLeaderLatch.LeaderTask() {
				@Override
				public void doTASK() {
					System.out.println("Leader do something!");
				}
			});
			selector.start();
            //等1S,调用close放弃主权
			Thread.sleep(1000);
			selector.close();
		}
        //延时1分支看输出结果
		Thread.sleep(60000);
	}
}
  • 测试结果(从结果可以看出,放弃主权之后的节点不再参与选举)
Latch-1 say : I am become a leader!
Leader do something!
Latch-1 say : I am no longer a leader!
Latch-2 say : I am become a leader!
Leader do something!
Latch-2 say : I am no longer a leader!
Latch-3 say : I am become a leader!
Leader do something!
Latch-3 say : I am no longer a leader!
Latch-4 say : I am become a leader!
Leader do something!
Latch-4 say : I am no longer a leader!
Latch-5 say : I am become a leader!
Leader do something!
Latch-5 say : I am no longer a leader!

策略2:LeaderElection(初始化多个LeaderSelector,然后自动选出Leader) 代码展示

public class MyLeaderElection extends LeaderSelectorListenerAdapter implements Closeable {
	private final String name;
	private final LeaderTask leaderTask;
	private final LeaderSelector leaderSelector;
	private String PATH = "/latchPath"; // Latch Path

	public MyLeaderElection(CuratorFramework client, String name, LeaderTask leaderTask) {
		this.name = name;
		this.leaderTask = leaderTask;
        //初始化LeaderSelector
		this.leaderSelector = new LeaderSelector(client, PATH, this);
        //放弃主权后自动重新参与竞选
		this.leaderSelector.autoRequeue();
	}

	public interface LeaderTask {
		public void doTASK();
	}

	public void start() throws Exception {
		leaderSelector.start();
	}

	public void close() {
		leaderSelector.close();
	}

	@Override
	public void takeLeadership(CuratorFramework client) throws Exception {
		System.out.println(name + " say : I am become a leader!");
		try {
			this.leaderTask.doTASK();
		} finally {
			System.out.println(name + " say : I am no longer a leader!");
		}
	}
}
  • 测试代码
public class MyTest {
	CuratorFramework client = null;
	private List<MyLeaderElection> selectorList = new ArrayList<>(5);

	@Before
	public void beforeTest() {
		String zkServerAddress = "127.0.0.1:2181";
		ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3, 5000);
		client = CuratorFrameworkFactory.builder().connectString(zkServerAddress).sessionTimeoutMs(5000)
				.connectionTimeoutMs(5000).retryPolicy(retryPolicy).build();
		client.start();
	}

	@Test
	public void testMyLeaderElection() throws Exception {
		for (int i = 1; i <= 5; i++) {
			MyLeaderElection selector = new MyLeaderElection(client, "Latch-" + i, new MyLeaderElection.LeaderTask() {
				@Override
				public void doTASK() {
					System.out.println("Leader do something!");
				}
			});
			selector.start();
			selectorList.add(selector);
		}
		Thread.sleep(60000);
	}

	@After
	public void afterTest() {
		selectorList.forEach(selector -> selector.close());
	}
}
  • 测试结果(可以看出,这种选举模式leader自动切换,并且是随机的)
Latch-3 say : I am no longer a leader!
Latch-2 say : I am become a leader!
Leader do something!
Latch-2 say : I am no longer a leader!
Latch-4 say : I am become a leader!
Leader do something!
Latch-4 say : I am no longer a leader!
Latch-5 say : I am become a leader!
Leader do something!
Latch-5 say : I am no longer a leader!
Latch-1 say : I am become a leader!
Leader do something!
Latch-1 say : I am no longer a leader!
Latch-3 say : I am become a leader!
Leader do something!
Latch-3 say : I am no longer a leader!
Latch-2 say : I am become a leader!
Leader do something!
Latch-2 say : I am no longer a leader!
Latch-4 say : I am become a leader!
Leader do something!
Latch-4 say : I am no longer a leader!
Latch-5 say : I am become a leader!
Leader do something!
Latch-5 say : I am no longer a leader!
Latch-1 say : I am become a leader!
Leader do something!
Latch-1 say : I am no longer a leader!
....
....
....

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值