介绍
zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
ZooKeeper 是一个典型的分布式数据一致性解决方案,分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。
zookeeper=文件系统+通知机制
spring boot 配置zk
spring.dubbo.appname=dubboname
spring.dubbo.registry=zookeeper://ip1:2181?backup=ip2:2181,ip3:2181
spring.dubbo.protocol=dubbo
zookeeper分布式锁
package com.sto.zk;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.ZkConnection;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import java.util.Collections;
import java.util.List;
/**
* @author yanyugang
* @description
* ZooKeeper 分布式锁原理:临时有序节点
* 1、创建永久性锁节点
* 2、在锁节点下创建临时节点
* 3、只有当前节点是锁节点下的最小节点,则获取锁成功
* @date 2019-09-11 15:24
*/
public class ZkTest {
private static final String LOCK_ROOT_PATH="/money/lock";
private static final String LOCK_NODE_NAME="Lock_";
public static void main(String[] args){
String connect_addr="127.0.0.1:2181";
// 建立连接
ZkClient zkc=new ZkClient(new ZkConnection(connect_addr), 10000);
// 创建永久性锁节点
boolean flg=zkc.exists(LOCK_ROOT_PATH);
if (!flg){
// 创建永久性锁节点
zkc.createPersistent(LOCK_ROOT_PATH, true);
}
List<String> list;
for (int i=0; i < 10; i++) {
// 临时有序节点
// 创建EPHEMERAL_SEQUENTIAL类型节点
String lockPath=zkc.create(LOCK_ROOT_PATH + "/" + LOCK_NODE_NAME,
Thread.currentThread().getName().getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(lockPath);
}
list=zkc.getChildren(LOCK_ROOT_PATH);
Collections.sort(list);
System.out.println("最小节点值==================>" + list.get(0));
}
}
- 运行结果
/money/lock/Lock_0000000314
/money/lock/Lock_0000000315
/money/lock/Lock_0000000316
/money/lock/Lock_0000000317
/money/lock/Lock_0000000318
/money/lock/Lock_0000000319
/money/lock/Lock_0000000320
/money/lock/Lock_0000000321
/money/lock/Lock_0000000322
/money/lock/Lock_0000000323
最小节点值==================>Lock_0000000314
zookeeper启动和停止
- 启动ZK服务: sh bin/zkServer.sh start
- 查看ZK服务状态: sh bin/zkServer.sh status
- 停止ZK服务: sh bin/zkServer.sh stop
- 重启ZK服务: sh bin/zkServer.sh restart
集群配置
- Zookeeper leader选举机制,在zookeeper集群中,会有三种角色,leader、 follower、 observer
- 配置多个实例共同构成一个集群对外提供服务以达到水平扩展的目的,每个服务器上的数据是相同的,每一个服务器均可以对外提供读和写的服务,这点和redis是相同的,即对客户端来讲每个服务器都是平等的。
- zookeeper集群是单数
配置文件
zookeeper1
- D:\MySoftware\zookeeper\zookeeper-3.4.6(1)\conf\zoo.cfg
# the port at which the clients will connect
clientPort=2181
#集群配置
dataDir=D:/MySoftware/zookeeper/zookeeper-3.4.6(1)/dataDir
dataLogDir=D:/MySoftware/zookeeper/zookeeper-3.4.6(1)/dataLog
#server.NUM=IP:port1:port2 NUM表示本机为第几号服务器;IP为本机ip地址;
#port1为leader与follower通信端口;port2为参与竞选leader的通信端口
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
- 新建D:\MySoftware\zookeeper\zookeeper-3.4.6(1)\dataDir\myid文件,内容如下
1
- 新建D:/MySoftware/zookeeper/zookeeper-3.4.6(3)/dataLog目录
zookeeper2
- D:\MySoftware\zookeeper\zookeeper-3.4.6(2)\conf\zoo.cfg
# the port at which the clients will connect
clientPort=2182
#集群配置
dataDir=D:/MySoftware/zookeeper/zookeeper-3.4.6(2)/dataDir
dataLogDir=D:/MySoftware/zookeeper/zookeeper-3.4.6(2)/dataLog
#server.NUM=IP:port1:port2 NUM表示本机为第几号服务器;IP为本机ip地址;
#port1为leader与follower通信端口;port2为参与竞选leader的通信端口
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
- 新建D:\MySoftware\zookeeper\zookeeper-3.4.6(2)\dataDir\myid文件,内容如下
2
- 新建D:/MySoftware/zookeeper/zookeeper-3.4.6(3)/dataLog目录
zookeeper3
- D:\MySoftware\zookeeper\zookeeper-3.4.6(3)\conf\zoo.cfg
# the port at which the clients will connect
clientPort=2183
#集群配置
dataDir=D:/MySoftware/zookeeper/zookeeper-3.4.6(3)/dataDir
dataLogDir=D:/MySoftware/zookeeper/zookeeper-3.4.6(3)/dataLog
#server.NUM=IP:port1:port2 NUM表示本机为第几号服务器;IP为本机ip地址;
#port1为leader与follower通信端口;port2为参与竞选leader的通信端口
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
- 新建D:\MySoftware\zookeeper\zookeeper-3.4.6(3)\dataDir\myid文件,内容如下
3
- 新建D:/MySoftware/zookeeper/zookeeper-3.4.6(3)/dataLog目录
zk选举机制
zk集群超过半数才能正常工作,所有zk集群一般为奇数台
半数机制
判断是否已经胜出
默认是采用投票数大于半数则胜出的逻辑。
选举状态
LOOKING,竞选状态。
FOLLOWING,随从状态,同步leader状态,参与投票。
OBSERVING,观察状态,同步leader状态,不参与投票。
LEADING,领导者状态。
选举流程简述
目前有5台服务器,每台服务器均没有数据,它们的服务器ID(存放在myid文件中)分别是1,2,3,4,5,按编号依次启动,它们的选择举过程如下:
- 服务器1启动,给自己投票,然后发投票信息,由于其它机器还没有启动所以它收不到反馈信息,服务器1的状态一直属于Looking。
- 服务器2启动,给自己投票,同时与之前启动的服务器1交换结果,由于服务器2的编号大所以服务器2胜出,但此时投票数没有大于半数,所以两个服务器的状态依然是LOOKING。
- 服务器3启动,给自己投票,同时与之前启动的服务器1,2交换信息,由于服务器3的编号最大所以服务器3胜出,此时投票数正好大于半数,所以服务器3成为领导者,服务器1,2成为小弟。
- 服务器4启动,给自己投票,同时与之前启动的服务器1,2,3交换信息,尽管服务器4的编号大,但之前服务器3已经胜出,所以服务器4只能成为小弟。
- 服务器5启动,后面的逻辑同服务器4成为小弟。