因为最近在学分布式,而机会所有常见的分布式框架都使用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设置监听之后例可失效,必须在时间发生之后再次设置监听 // 此处设置的是监听根目录 Listchildren = 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条)