最近想了解一下zookeeper,写个博客做个记录;
什么是zookeeper
ZooKeeper :官网是一个开源的分布式协调服务,原本是Hadoop大数据内部的一个组件,然后现在我们主要就是用来做dubbo的注册中心,当然不止这点作用,还可以 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。贴一张百度的图:

设计目的
- 最终一致性:client不论连接到哪个Server,展示给它都是同一个视图,这是zookeeper最重要的性能。
- 可靠性:具有简单、健壮、良好的性能,如果消息m被到一台服务器接受,那么它将被所有的服务器接受。
- 实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。
- 等待无关(wait-free):慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待。
- 原子性:更新只能成功或者失败,没有中间状态。
- 顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。
如何下载
官网里面找到下载,就会跳这里:https://www.apache.org/dyn/closer.cgi/zookeeper/
然后直接下载
两个都下载了,然后解压
一个是有源码的,一个是执行文件,zookeeper也是个maven项目,有空可以研究一下源码,现在只想先了解一下.我们直接进到bin里面执行:zkServer.cmd发现一闪而过.百度一下,发现解决:
进到conf文件将zoo_sample.cfg文件打开看看,也看不懂,修改一下目录,因为是windows的:
参数常用的就几个:
tickTime:就是心跳时间了,心跳机制还是有听说过得
dataDir:就是zookeeper的一些文件保存的目录
clientPort:就是监听的端口了,默认2181就不动了
我就只改个目录好了:
dataDir=E:/zookeeper_study/tmp/zookeeper/data
然后改个名字zoo.cfg,然后启动,就成功了!
使用zkcli简单尝试
bin目录下有zkCli.cmd,要是你zkserver启动成功,那就直接点这个,就会出现一个窗口,
然后随便输入个help:
可以看出大概这些命令,就简单创个节点,修改一下删除好了:
create /aaa bbb
get /aaa
set /aaa ccc
get /aaa
delete /aaa
get /aaa
#创建子节点
create -e /temp/aaa ccc
#查看某个节点的状态
stat /temp
#使用-s参数,创建一个顺序节点,我们虽然指定的节点名是aaa,但是实际上,名称却是 /temp/aa0000000001,如果我们重复执行可以在分布式环境下主键生成器:
create -s /temp/aa
简单的试了试,当然也可以
通过javaapi来进行操作节点
引入pom
<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.5</version>
</dependency>
随便抄个代码https://blog.csdn.net/u010398771/article/details/82420504,他那复制下来有问题,我就删除部分,自己搞了搞能够跑通,不知道为啥连接很慢,算了不管了
import org.apache.zookeeper.*;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public class ZooKeeperProSync implements Watcher {
private static ZooKeeper zookeeper;
private static final int SESSION_TIME_OUT = 2000;
private CountDownLatch countDownLatch = new CountDownLatch(1);
@Override
public void process(WatchedEvent event) {
if (event.getState() == KeeperState.SyncConnected) {
System.out.println("Watch received event");
countDownLatch.countDown();
}
}
/**
* 连接zookeeper
* * @param host
* * @throws Exception
*
*/
public void connectZookeeper(String host) throws Exception {
zookeeper = new ZooKeeper(host, SESSION_TIME_OUT, this);
countDownLatch.await();
System.out.println("zookeeper connection success");
}
/**
* * 创建节点
* * @param path
* * @param data
* * @throws Exception
*
*/
public String createNode(String path, String data) throws Exception {
return this.zookeeper.create(path, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
/**
* * 获取路径下所有子节点
* * @param path
* * @return
* * @throws KeeperException
* * @throws InterruptedException
*
*/
public List<String> getChildren(String path) throws KeeperException, InterruptedException {
List<String> children = zookeeper.getChildren(path, false);
return children;
}
/**
* * 获取节点上面的数据
* * @param path 路径
* * @return
* * @throws KeeperException
* * @throws InterruptedException
*
*/
public String getData(String path) throws KeeperException, InterruptedException {
byte[] data = zookeeper.getData(path, false, null);
if (data == null) {
return "";
}
return new String(data);
}
public static void main(String[] args) throws Exception {
//连接zookeeper并且注册一个默认的监听器
zookeeper = new ZooKeeper("127.0.0.1:2181", 5000, //
new ZooKeeperProSync());
ZooKeeperProSync zooKeeperProSync = new ZooKeeperProSync();
List<String> children = zooKeeperProSync.getChildren("/");
for (String child : children) {
System.out.println(child);
}
}
}
图形化操作
参考:https://blog.csdn.net/qq_38366063/article/details/93495348