下载安装
3.8下载地址:
https://www.apache.org/dyn/closer.lua/zookeeper/zookeeper-3.8.0/apache-zookeeper-3.8.0-bin.tar.gz
其他本地址:
https://archive.apache.org/dist/zookeeper/
创建并移动到指定文件夹
cd /usr/local
mkdir zookeeper
cd /root
mv apache-zookeeper-3.8.0-bin.tar.gz /usr/local/zookeeper/
执行解压安装包
cd /usr/local/zookeeper/
tar -zxvf /usr/local/zookeeper/apache-zookeeper-3.8.0-bin.tar.gz
进入到解压好的目录中创建 data 和 logs 文件夹
cd /usr/local/zookeeper/apache-zookeeper-3.8.0-bin
mkdir data
进入 conf 文件夹,拷贝一份配置文件并进行修改
cd /usr/local/zookeeper/apache-zookeeper-3.8.0-bin/conf/
# 复制文件
cp zoo_sample.cfg zoo.cfg
修改配置文件,单节点只需要修改文件存储位置就可以了
vim zoo.cfg
dataDir=/usr/local/zookeeper/apache-zookeeper-3.8.0-bin/data
集群配置:在data文件下创建一个myid,myid需要唯一
# 进入数据目录
cd /usr/local/zookeeper/apache-zookeeper-3.8.0-bin/data
#节点1 myid=1
touch myid && echo 1 > myid
#节点2 myid=2
touch myid && echo 2 > myid
#节点3 myid=2
touch myid && echo 3 > myid
cd /usr/local/zookeeper/apache-zookeeper-3.8.0-bin/conf/
vim zoo.cfg
# 节点配置,server后面的id编号和各节点下的myid保持一致
server.1=192.168.158.158:2888:3888
server.2=192.168.158.159:2888:3888
server.3=192.168.158.160:2888:3888
server.myid.服务器地址.服务器通信端口号.leader选取的通信地址
执行命令使 profile 文件生效
source /etc/profile
防火墙添加 zookeeper 访问端口
firewall-cmd --zone=public --add-port=2181/tcp --permanent
firewall-cmd --zone=public --add-port=2888/tcp --permanent
firewall-cmd --zone=public --add-port=3888/tcp --permanent
重启防火墙
firewall-cmd --reload
启动
服务端
启动服务端,在集群模式下,启动的服务器不超过半数,无法提供服务
/usr/local/zookeeper/apache-zookeeper-3.8.0-bin/bin/zkServer.sh start
查看启动状态
/usr/local/zookeeper/apache-zookeeper-3.8.0-bin/bin/zkServer.sh status
查看zookeeper是否启动,可以使用 jps是jdk提供的一个查看当前java进程的小工具
jps
jps –l 输出主类或者jar的完全路径名
jps –v 输出jvm参数
jps –q 仅仅显示java进程号
jps -mlv 10.134.68.173
配置文件解释
心跳时间:毫秒
tickTime=2000
初始连接,通信时限,这里是5次心跳(5*2000),超时连接失败
initLimit=5
首次建立连接之后,通信时限,这里是2次心跳(2*2000)
syncLimit=2
数据存放位置
dataDir=/usr/local/zookeeper/apache-zookeeper-3.8.0-bin/data
客户端通信端口
clientPort=2181
启动异常。可以删除data文件夹下文件
cd /usr/local/zookeeper/apache-zookeeper-3.8.0-bin/data
rm -rf version-2/
rm -rf zookeeper_server.pid
客户端
启动客户端
/usr/local/zookeeper/apache-zookeeper-3.8.0-bin/bin/zkCli.sh
或者
/usr/local/zookeeper/apache-zookeeper-3.8.0-bin/bin/zkCli.sh -server 192.168.158.158:2181
推出客户端
quit
客户端节点类型
- 持久:客户端和服务端,断开连接后,创建的节点不删除
- 短暂:客户端和服务端,断开连接后,创建的节点自己删除
节点相关的Shell操作:
1.永久节点(不带序号:不能创建名称相同的节点)
创建节点:create /节点名 "节点描述"
获取节点信息:get -s /节点名
2.永久节点(带序号:可以创建名称相同的节点,序号自动增加)
创建节点:create -s /一级节点名/二级节点名 "节点描述"
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LtaGVMqB-1668950884621)(C:\Users\IsTrueLove\AppData\Roaming\Typora\typora-user-images\image-20221119175746858.png)]
3.临时节点(不带序号)
创建节点:create -e /一级节点名/二级节点名 "节点描述"
4.临时节点(带序号)
创建节点:create -e -s /一级节点名/二级节点名 "节点描述"
5.修改节点数值:
set /一级节点名/二级节点名 "节点描述"
6.查看节点状态:
stat /节点名
7.节点删除:
删除单个节点:delete /一级节点名/二级节点名
删除整个节点:deleteall /一级节点名
java Api创建节点
/**
* 连接地址
*/privateString connectString ="192.168.158.158:2181,192.168.158.159:2181,192.168.158.160:2181";/**
* 毫秒
*/privateInteger sessionTimeout =2000;@GetMapping("/test")publicObjecttest(String path,String data){ZooKeeper zooKeeper =null;try{//创建连接
zooKeeper =newZooKeeper(connectString, sessionTimeout,newWatcher(){@Overridepublicvoidprocess(WatchedEvent watchedEvent){}});//判断节点是否存在Stat exists = zooKeeper.exists(path,false);if(exists !=null){return"节点以存在";}//创建节点
zooKeeper.create(path, data.getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);//监听节点变化,第一个参数为路径,第二个参数是监听,如果为true就会使用创建连接时的监听器,返回的是节点名List<String> children = zooKeeper.getChildren("/",true);
children.forEach(a ->System.out.println(a));}catch(Exception e){thrownewRuntimeException(e);}return"zooKeeper";}
基础概念
特点
- zooleeper集群只有一个leader,有多个follower
- 集群中只要存活半数以上的节点,集群就能正常提供服务,所以zookeeper适合安装奇数台服务器
- 多个节点全局数据一致,无论连接到那个服务器,数据都是一致的
- 更新请求顺序执行,来自同一个客户端的请求按顺序执行
- 数据更新具有原子性
- 在一定时间范围内,客户端能读到最新的数据
zookeeper数据模型与Uinx文件系统很相似,整体可以看作是一棵树,每个节点 默认能够存储1MB数据,每个节点都可以通过文件路径来唯一标识
leader选举
- 第一次启动- 第一台服务器启动,会先投票给自己,如果得票不超过一半,选举就无法完成,服务器保持为LOOKING状态(既不是leader也不是follwer)- 第二台服务器启动,会在发起一次选举,也会投票给自己,然后会交换选票信息,两台会把选票投给myid最大的服务器,然后判断是否超过半数,如果超过了,选举结束,除leader以外,其他服务器都是follwer,不超过,就继续选举- 当选举出leader以后,后续集群其他服务器再启动,也不会影响leader的选举结果
- 非第一次启动- 有两种情况会产生leader选举- 服务器初始化启动- 服务器运行期间无法和leader保持连接(某台服务器和其他节点连接不上,它不会认为自己出现了故障,而是认为其他节点出现故障)- 所以发生leader选举时会有两种情况- 集群中已近存在leader了 - 集群中已近存在leader,某台服务器试图取选举leader时,会被告知当前leader的信息,然后连接当前leader- 集群中确实不存在leader - 就需要没有故障的节点,需要根据SID、ZXID、Epoch选举出新的leader- 先判断Epoch,大的胜出- Epoch相同ZXID,事务id大的胜出- ZXID相同,SID服务器id大的胜出
监听器原理
- 再一个mian线程里,创建zookeeper客户端,会有两个线程,一个负责网络通信,一个负责监听
- 通过通信的线程将注册的监听事件发送给zookeeper ,再zookeeper的注册监听列表中将注册的监听事件添加到列表中
- zookeeper监听到数据或者路径有变化时,就会将这个消息发送给监听线程
zookeeper写原理
- 写流程直接请求leader, leader收到请求后,leader会先写入数据,会通知follwer写数据,只要集群中超过半数的节点写数据完成,leader就会返回写入成功,然后接着完成剩下的节点的写操作
- 写流程不是请求的leader,就会把写请求转发给leader, leader收到请求后,leader会先写入数据,会通知follwer写数据,只要集群中超过半数的节点写数据完成,被请求的节点就会返回写入成功(这里不是leader返回),然后接着完成剩下的节点的写操作
动态上下线
- 首先zookeepe创建一个永久节点
- 服务器操作:创建服务器连接,将自己注册到zookeeper集群(也就是创建对应的节点,上线一台服务器就创建一个节点,下线节点就消失)
- 客户端操作:监听服务器的变化,也就是监听指定的节点变化
zookeeper分布式锁
- 当产生资源竞争时,线程往zookeeper集群创建临时顺序节点
- 判断自己是不是最小节点,是就拿到锁,不是,就监听上一个节点
- 序号最小的拿到锁,执行完后,删除节点释放锁,然后下一个节点通过监听知道上一个节点消失,立即拿到锁,然后执行,然后重复这些步骤
版权归原作者 isTrueLoveColour 所有, 如有侵权,请联系我们删除。