大纲
1.基于Curator进行基本的zk数据操作
2.基于Curator实现集群元数据管理
3.基于Curator实现HA主备自动切换
4.基于Curator实现Leader选举
5.基于Curator实现分布式Barrier
6.基于Curator实现分布式计数器
7.基于Curator实现zk的节点和子节点监听机制
8.基于Curator创建客户端实例的源码分析
9.Curator在启动时是如何跟zk建立连接的
10.基于Curator进行增删改查节点的源码分析
11.基于Curator的节点监听回调机制的实现源码
12.基于Curator的Leader选举机制的实现源码
1.基于Curator进行基本的zk数据操作
Guava is to Java what Curator is to ZooKeeper,引入依赖如下:
<dependencies>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.12.0</version>
</dependency>
</dependencies>
Curator实现对znode进行增删改查的示例如下,其中CuratorFramework代表一个客户端实例。注意:可以通过creatingParentsIfNeeded()方法进行指定节点的级联创建。
public class CrudDemo {
public static void main(String[] args) throws Exception {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", 5000, 3000, retryPolicy);
client.start();//启动客户端并建立连接
System.out.println("已经启动Curator客户端");
client.create()
.creatingParentsIfNeeded()//进行级联创建
.withMode(CreateMode.PERSISTENT)//指定节点类型
.forPath("/my/path", "10".getBytes());//增
byte[] dataBytes = client.getData().forPath("/my/path");//查
System.out.println(new String(dataBytes));
client.setData().forPath("/my/path", "11".getBytes());//改
dataBytes = client.getData().forPath("/my/path");
System.out.println(new String(dataBytes));
List<String> children = client.getChildren().forPath("/my");//查
System.out.println(children);
client.delete().forPath("/my/path");//删
Thread.sleep(Integer.MAX_VALUE);
}
}
2.基于Curator实现集群元数据管理
Curator可以操作zk。比如自研了一套分布式系统类似于Kafka、Canal,想把集群运行的核心元数据都放到zk里去。此时就可以通过Curator创建一些znode,往里面写入对应的值。
写入的值推荐用json格式,比如Kafka就是往zk写json格式数据。这样,其他客户端在需要的时候,就可以从里面读取出集群元数据了。
3.基于Curator实现HA主备自动切换
HDFS、Kafka、Canal都使用了zk进行Leader选举,所以可以基于Curator实现HA主备自动切换。
HDFS的NameNode是可以部署HA架构的,有主备两台机器。如果主机器宕机了,备用的机器可以感知到并选举为Leader,这样备用的机器就可以作为新的NameNode对外提供服务。
Kafka里的Controller负责管理整个集群的协作,Kafka中任何一个Broker都可以变成Controller,类似于Leader的角色。
Canal也会部署主备两台机器,主机器挂掉了,备用机器就可以跟上去。
4.基于Curator实现Leader选举
(1)Curator实现Leader选举的第一种方式之LeaderLatch
(2)Curator实现Leader选举的第二种方式之LeaderSelector
(1)Curator实现Leader选举的第一种方式之LeaderLatch
通过Curator的LeaderLatch来实现Leader选举:
public class LeaderLatchDemo {
public static void main(String[] args) throws Exception {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", 5000, 3000, retryPolicy);
client.start();
//"/leader/latch"这其实是一个znode顺序节点
LeaderLatch leaderLatch = new LeaderLatch(client, "/leader/latch");
leaderLatch.start();
leaderLatch.await();//直到等待他成为Leader再往后执行
//类似于HDFS里,两台机器,其中一台成为了Leader就开始工作
//另外一台机器可以通过await阻塞在这里,直到Leader挂了,自己就会成为Leader继续工作
Boolean hasLeaderShip = leaderLatch.hasLeadership();//判断是否成为Leader
System.out.println("是否成为leader:" + hasLeaderShip);
Thread.sleep(Integer.MAX_VALUE);
}
}
(2)Curator实现Leader选举的第二种方式之LeaderSelector
通过Curator的LeaderSelector来实现Leader选举如下:其中,LeaderSelector有两个监听器,可以关注连接状态。
public class LeaderSelectorDemo {
public static void main(String[] args) throws Exception {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", 5000, 3000, retryPolicy);
client.start();
LeaderSelector leaderSelector = new LeaderSelector(
client,
"/leader/election",
new LeaderSelectorListener() {
public void takeLeadership(CuratorFramework curatorFramework) throws Exception {
System.out.println("你已经成为了Leader......");
//在这里干Leader所有的事情,此时方法不能退出
Thread.sleep(Integer.MAX_VALUE);
}
public void stateChanged(CuratorFramework curatorFramework, ConnectionState connectionState) {
System.out.println("连接状态的变化,已经不是Leader......");
if (connectionState.equals(ConnectionState.LOST)) {
throw new CancelLeadershipException();
}
}
}
);
leaderSelector.start();//尝试和其他节点在节点"/leader/election"上进行竞争成为Leader
Thread.sleep(Integer.MAX_VALUE);
}
}
5.基于Curator实现的分布式Barrier
(1)分布式Barrier
(2)分布式双重Barrier
(1)分布式Barrier
很多台机器都可以创建一个Barrier,此时它们都被阻塞了。除非满足一个条件(setBarrier()或removeBarrier()),才能不再阻塞它们。
//DistributedBarrier
public class DistributedBarrierDemo {
public static void main(String[] args) throws Exception {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", 5000, 3000, retryPolicy);
client.start();
DistributedBarrier barrier = new DistributedBarrier(client, "/barrier");
barrier.waitOnBarrier();
}
}
(2)分布式双重Barrier
//DistributedDoubleBarrier
public class DistributedDoubleBarrierDemo {
public static void main(String[] args) throws Exception {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", 5000, 3000, retryPolicy);
client.start();
DistributedDoubleBarrier doubleBarrier = new DistributedDoubleBarrier(client, "/barrier/double", 10);
doubleBarrier.enter();//每台机器都会阻塞在enter这里
//直到10台机器都调用了enter,就会从enter这里往下执行
//此时可以做一些计算任务
doubleBarrier.leave();//每台机器都会阻塞在leave这里,直到10台机器都调用了leave
//此时就可以继续往下执行
}
}
6.基于Curator实现分布式计数器
如果真的要实现分布式计数器,最好用Redis来实现。因为Redis的并发量更高,性能更好,功能更加的强大,而且还可以使用lua脚本嵌入进去实现复杂的业务逻辑。但是Redis天生的异步同步机制,存在机器宕机导致的数据不同步风险。然而zk在ZAB协议下的数据同步机制,则不会出现宕机导致数据不同步的问题。
//SharedCount:通过一个节点的值来实现
public class SharedCounterDemo {
public static void main(String[] args) throws Exception {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", 5000, 3000, retryPolicy);
client.start();
SharedCount sharedCount = new SharedCount(client, "/shared/count", 0);
sharedCount.start();
sharedCount.addListener(new SharedCountListener() {
public void countHasChanged(SharedCountReader sharedCountReader, int i) throws Exception {
System.out.println("分布式计数器变化了......");
}
public void stateChanged(CuratorFramework curatorFramework, ConnectionState connectionState) {
System.out.println("连接状态变化了.....");
}
});
Boolean result = sharedCount.trySetCount(1);
System.out.println(sharedCount.getCount());
}
}
7.基于Curator实现zk的节点和子节点监听机制
(1)基于Curator

最低0.47元/天 解锁文章
2768

被折叠的 条评论
为什么被折叠?



