
因为最近在学分布式,而机会所有常见的分布式框架都使用zookeeper作为解决分布式一致性(分布式锁,选举leader)的工具,所以再好好学一遍zookeeper。
视频教程
-
zookeeper是什么?
zookeeper本质上是一个基于观察者模式的分布式框架,在zookeeper中,A创建了一个节点,那么其它节点(比如B)就可以去监听这个节点,当节点的状态发生变化的适合,B就可以触发自己的一系列动作。zookeeper使用了一种类似于文件系统的东西去实现整个流程:创建节点即创建某个目录下的文件(节点),监听可以是监听某个文件(节点),也可以是监听某个文件路径。 -
Zookeeper Java api
实际使用中,常常是使用API去对zookeeper进行一系列 *** 作
zk java api的基本 *** 作:非常简单,连接到zk之后直接调用api:
package com.ms.zookeeper;
import org.apache.zookeeper.*;
import org.junit.jupiter.api.Test;
import java.io.IOException;
public class baseOperation {
String connectionURL="127.0.0.1:2181";
int sessionTimeout=2000;
ZooKeeper zooKeeper = new ZooKeeper(connectionURL, sessionTimeout, new Watcher() {
public void process(WatchedEvent event) {
}
});
public baseOperation() throws IOException {
}
@Test
void TestConnection() throws InterruptedException, KeeperException {
System.out.println(zooKeeper.getAllChildrenNumber("/"));
}
@Test
void TestCreate() throws InterruptedException, KeeperException {
String res = zooKeeper.create("/ms", "suzhou ms".getBytes(), ZooDefs.Ids.READ_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(res);
}
}
zk监听事件:这里要注意,我们监听zk下的某个节点,当这个节点发生变化引起监听事件,那么我们的监听器就会释放,也就是说,监听器只能监听一次。
package com.ms.zookeeper;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.List;
public class Monitor {
String hostURL="127.0.0.1:2181";
int connectionTimeout=3000;
ZooKeeper zkClient=new ZooKeeper(hostURL, connectionTimeout, new Watcher() {
public void process(WatchedEvent event) {
try {
// zk设置监听之后例可失效,必须在时间发生之后再次设置监听
// 此处设置的是监听根目录
List children = zkClient.getChildren("/", true);
System.out.println("----------------------------");
children.forEach(System.out::println);
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
}
});
public Monitor() throws IOException {
}
@Test
public void Listen() throws InterruptedException {
System.out.println("begin");
// 线程阻塞,持续监听
Thread.sleep(Long.parseLong("10000000"));
}
}
zk实现分布式锁的解析
假设有
N
N
N个机器要竞争一个分布式锁,我们可以在zk下新建一个目录,比方说/lock,这
N
N
N个机器同时在此目录下创建带序号的文件,比方说/lock/getlock00000000,/lock/getlock00000001……(zk内置提供了在同一路径下创建这种文件的方法,即在同一路径下的同一文件名,每次创建后缀数字+1),在机器创建好文件之后,其会监听/lock这个目录,如果某个机器的文件后缀数字是当前目录中最小的,那么它获得锁,执行事务,在事务执行完之后删除自己的文件,导致其它机器的监听事件被触发,从而继续竞争锁。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)