zookeeper
第一章 总述
第二章 安装zookeeper
解压
tar -zxvf apache-zookeeper-3.6.2-bin.tar.gz -C /opt/application/
配置:
rm zoo_sample.cfg zoo.cfg
mkdir /opt/application/zookeeper/data
vi zoo.cfg
dataDir=/opt/application/zookeeper/data
启动:
./zkServer.sh start
./zkServer.sh status
./zkCli.sh
集群:
配置:
server.1=192.168.1.111:2888:3888
server.2=192.168.1.112:2888:3888
server.3=192.168.1.113:2888:3888
mkdir /opt/application/zookeeper/data
cd /opt/application/zookeeper/data
touch myid -> 1,2,3
scp -r zookeeper chenkai@192.168.1.112:/opt/application/
scp -r zookeeper chenkai@192.168.1.113:/opt/application/
change myid
启动:
cd /opt/application/zookeeper/bin
./zkServer.sh start
./zkServer.sh status
./zkCli.sh
第三章 客户端命令
ls / ls 命令用于查看某个路径下目录列表
ls /zookeeper
ls2 /zookeeper ls2 命令用于查看某个路径下目录列表,它比 ls 命令列出更多的详细信息。
get /path [watch] get 命令用于获取节点数据和状态信息。
set /runoob 1 在终端二对此节点进行修改
stat path [watch] stat 命令用于查看节点状态信息。
create [-s] [-e] path data acl create 命令用于创建节点并赋值。
[-s] [-e]:-s 和 -e 都是可选的,-s 代表顺序节点, -e 代表临时节点,注意其中 -s 和 -e 可以同时使用的,并且临时节点不能再创建子节点。
path:指定要创建节点的路径,比如 /runoob。
data:要在此节点存储的数据。
path:访问权限相关,默认是 world,相当于全世界都能访问。
set path data [version] set 命令用于修改节点存储的数据。
path:节点路径。
data:需要存储的数据。
[version]:可选项,版本号(可用作乐观锁)。
delete path [version] delete 命令用于删除某节点。
path:节点路径。
[version]:可选项,版本号(同 set 命令)。
第四章java中使用
3.1 直接创建连接
导入jar:zookeeper-3.6.2.jar,zookeeper-jute-3.6.2.jar
package kai.zookeeper; import java.io.IOException; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs; import org.apache.zookeeper.ZooKeeper; /** * zookeeper测试连接 导入包:zookeeper-3.6.2.jar zookeeper-jute-3.6.2.jar * <p>Title: ZookeeperConnTest</p> * <p>Description: </p> * @author chenkai * @date 2021年3月21日 */ public class ZookeeperConnTest { /** zookeeper地址 */ static final String CONNECT_ADDR = "192.168.1.111:2181,192.168.1.112:2181,192.168.1.113:2181"; /** session超时时间 */ static final int SESSION_OUTTIME = 5000;//ms /** * 需要先确认zookeeper连接了后,才能对zookeeper进行操作,否则报错:KeeperErrorCode = ConnectionLoss for /test */ static final CountDownLatch countDownLatch = new CountDownLatch(1); public static void main(String[] args) throws IOException, KeeperException, InterruptedException { ZooKeeper zoo = new ZooKeeper(CONNECT_ADDR, SESSION_OUTTIME, new Watcher() { @Override public void process(WatchedEvent event) { KeeperState keeperState = event.getState(); if(KeeperState.SyncConnected == keeperState) { System.out.println("zk 建立连接"); countDownLatch.countDown(); } } }); countDownLatch.await(); System.out.println("可以操作zookeeper了"); zoo.delete("/test", -1); zoo.create("/test", "test".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zoo.close(); } }
3.2 使用zkclient
导入jar:zkclient-0.1.jar
package kai.zkclient; import java.util.Iterator; import java.util.List; import org.I0Itec.zkclient.IZkChildListener; import org.I0Itec.zkclient.ZkClient; import org.I0Itec.zkclient.ZkConnection; import org.apache.zookeeper.CreateMode; /** * 利用ZKclient连接zookeeper * <p>Title: ZkclientConnTest</p> * <p>Description: </p> * @author chenkai * @date 2021年3月21日 */ public class ZkclientConnTest { /** zookeeper地址 */ static final String CONNECT_ADDR = "192.168.1.111:2181,192.168.1.112:2181,192.168.1.113:2181"; /** session超时时间 */ static final int SESSION_OUTTIME = 5000;//ms public static void main(String[] args) throws InterruptedException { ZkClient zkClient = new ZkClient(new ZkConnection(CONNECT_ADDR, SESSION_OUTTIME)); //删除节点 zkClient.delete("/zkclient1"); zkClient.delete("/zkclient2"); zkClient.delete("/zkclient3"); zkClient.deleteRecursive("/zkclient4/t1");//删除递归节点 /*常规创建节点*/ zkClient.create("/zkclient1", "zkclient1", CreateMode.PERSISTENT); /*创建临时节点,连接关闭节点自动删除*/ zkClient.createEphemeral("/zkclient2","zkclient2"); /*创建常规节点等同于create*/ zkClient.createPersistent("/zkclient3","zkclient3"); /*创建递归节点,第二个参数必须为true*/ zkClient.createPersistent("/zkclient4/t1",true); System.out.println("创建节点成功!"); //更新数据 zkClient.writeData("/zkclient4/t1", "t1内容"); //读取子节点 System.out.println("节点:" + zkClient.getChildren("/zkclient1")); System.out.println("节点:" + zkClient.getChildren("/zkclient2")); System.out.println("节点:" + zkClient.getChildren("/zkclient3")); System.out.println("节点:" + zkClient.getChildren("/zkclient4")); //读取节点数据 System.out.println("zkclient1节点数据:" + zkClient.readData("/zkclient1").toString()); System.out.println("zkclient2节点数据:" + zkClient.readData("/zkclient2").toString()); System.out.println("zkclient3节点数据:" + zkClient.readData("/zkclient3").toString()); System.out.println("zkclient4节点数据:" + zkClient.readData("/zkclient4/t1")); //监听子节点变化subscribeChildChanges,subscribeDataChanges,subscribeStateChanges zkClient.subscribeChildChanges("/zkclient4", new IZkChildListener() { @Override public void handleChildChange(String s, List<String> list) throws Exception { //监听的全路径 System.out.println("s:" + s); //变动之后剩余的子节点 for (Iterator iterator = list.iterator(); iterator.hasNext();) { String string = (String) iterator.next(); System.out.println(string); } } }); //监听之后改动 zkClient.createPersistent("/zkclient4/t2",true); zkClient.deleteRecursive("/zkclient4/t2"); // Thread.sleep(100000000); zkClient.close(); System.out.println("连接关闭!"); } }
3.3 使用curator
导入jar:curator-client-2.4.2.jar,curator-framework-2.4.2.jar,curator-recipes-2.4.2.jar
package kai.curator; import java.util.Iterator; import java.util.List; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.data.Stat; public class CuratorConnTest { /** zookeeper地址 */ static final String CONNECT_ADDR = "192.168.1.111:2181,192.168.1.112:2181,192.168.1.113:2181"; /** session超时时间 */ static final int SESSION_OUTTIME = 5000;//ms public static void main(String[] args) throws Exception { //建立连接 CuratorFramework curatorFramework = CuratorFrameworkFactory .builder() .connectString(CONNECT_ADDR) .sessionTimeoutMs(SESSION_OUTTIME) .retryPolicy(new ExponentialBackoffRetry(1000, 3)) // .namespace("") .build(); curatorFramework.start(); //删除节点 curatorFramework.delete().deletingChildrenIfNeeded().forPath("/curator1"); curatorFramework.delete().deletingChildrenIfNeeded().forPath("/curator2/t1"); //创建节点 curatorFramework.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT) .forPath("/curator1", "curator1 data".getBytes()); curatorFramework.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT) .forPath("/curator2/t1", "curator2 t1 data".getBytes()); //得到节点数据 byte[] data1 = curatorFramework.getData().forPath("/curator1"); byte[] data2 = curatorFramework.getData().forPath("/curator2/t1"); System.out.println(new String(data1)); System.out.println(new String(data2)); byte[] bytes = curatorFramework.getData().storingStatIn(new Stat()).forPath("/curator1"); System.out.println(new String(bytes)); //得到子节点 List list = curatorFramework.getChildren().forPath("/curator2"); for (Iterator iterator = list.iterator(); iterator.hasNext();) { Object object = (Object) iterator.next(); System.out.println(object); } // System.out.println(curatorFramework.getChildren().forPath("/curator2").get(0)); //修改节点数据 curatorFramework.setData().forPath("/curator2/t1", "change curator2 t1 data".getBytes()); byte[] data3 = curatorFramework.getData().forPath("/curator2/t1"); System.out.println(new String(data3)); } }
3.4 分布式锁
package kai.curator; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.CountDownLatch; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.recipes.locks.InterProcessMutex; import org.apache.curator.retry.ExponentialBackoffRetry; public class ZookeeperLock { /** zookeeper地址 */ static final String CONNECT_ADDR = "192.168.1.111:2181,192.168.1.112:2181,192.168.1.113:2181"; /** session超时时间 */ static final int SESSION_OUTTIME = 5000;//ms static int count = 0; public static void main(String[] args) throws InterruptedException { //建立连接 CuratorFramework curatorFramework = CuratorFrameworkFactory .builder() .connectString(CONNECT_ADDR) .sessionTimeoutMs(SESSION_OUTTIME) .retryPolicy(new ExponentialBackoffRetry(1000, 3)) // .namespace("") .build(); curatorFramework.start(); //分布式锁 InterProcessMutex lock = new InterProcessMutex(curatorFramework, "/lock"); CountDownLatch countDownLatch = new CountDownLatch(1); for (int i = 0; i < 10 ; i++) { new Thread(new Runnable() { @Override public void run() { try { countDownLatch.await(); //加锁 lock.acquire(); System.out.println(count); count++; SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss|SSS"); System.out.println(sdf.format(new Date())); } catch (Exception e) { e.printStackTrace(); } finally { try { //释放锁 lock.release(); } catch (Exception e) { e.printStackTrace(); } } } }).start(); } countDownLatch.countDown(); System.out.println("the end!"); } }
3.4 java锁
package kai.curator; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.CountDownLatch; import java.util.concurrent.locks.ReentrantLock; public class SengleLock { static ReentrantLock reentrantLock = new ReentrantLock(); static int count = 10; public static void genarNo(){ try { reentrantLock.lock(); count--; System.out.println(count); } finally { reentrantLock.unlock(); } } public static void main(String[] args) throws Exception{ final CountDownLatch countdown = new CountDownLatch(1); for(int i = 0; i < 10; i++){ new Thread(new Runnable() { @Override public void run() { try { countdown.await(); genarNo(); System.out.println("count-" + count ); SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss|SSS"); System.out.println(sdf.format(new Date())); } catch (Exception e) { e.printStackTrace(); } finally { } } },"t" + i).start(); } Thread.sleep(500); countdown.countDown(); } }