1 zookeeper简介
官网: https://zookeeper.apache.org/
ZooKeeper 最早起源于雅虎研究院的一个研究小组。在当时,研究人员发现,在雅虎内部很多大型系统基本都需要依赖一个类似的系统来进行分布式协调,但是这些系统往往都存在分布式单点问题,所以,雅虎的开发人员就试图开发一个通用的无单点问题的分布式协调框架,以便让开发人员将精力集中在处理业务逻辑上。
关于“ZooKeeper”这个项目的名字,其实也有一段趣闻,在立项初期,考虑到之前内部很多项目都是使用动物的名字来命名的(例如著名的 Pig 项目),雅虎的工程师希望给这个项目也取一个动物的名字。时任研究院的首席科学家RaghuRamakrishnan(拉古·拉玛克里希南)开玩笑地说:“在这样下去,我们这儿就变成动物园了!”此话一出,大家纷纷表示就叫动物园管理员吧。因为各个以动物命名的分布式组件放在一起, 雅虎的整个分布式系统看上去就像一个大型的动物园了,而Zookeeper 正好要用来进行分布式环境的协调,于是Zookeeper的名字也就由此诞生了。
2 ZooKeeper使用场景
ZooKeeper是一个分布式服务框架,它主要是用来解决分布式应用中所经常遇到的一些数据管理问题,如:命名服务、状态同步、配置中心、集群管理等。
2.1 命令服务
命名服务是分布式系统中比较常见的一类场景。命令服务是分布式系统最基本的公共服务之一。在分布式系统中,被命名的实体通常可以是集群中的机器、提供的服务地址或远程对象等。这些我们都可以统称它们为名字(Name),其中较常见的就是一些分布式服务框架(如RPC、RMI)中的服务地址列表,通过使用命名服务,客户端应用能够根据指定名字来获取资源的实体、服务地址和提供者的信息等。
2.2 状态同步
每个节点除了存储数据内容和Node节点状态信息之外,还存储了已经注册的APP的状态信息,当有些节点或APP不可以时,就将当前状态同步给其他服务。
2.3 配置中心
限制我们大多数应用都是采用分布式开发的应用,搭建到不同的服务器上,同一个应用程序的配置文件一样,还有就是多个程序存在相同的配置,当我们配置文件中有个配置属性需要改变,我们需要改变每个程序的配置属性,这样会很麻烦的去修改配置,那么可以使用Zookeeper来现实配置中心,ZooKeeper采用的推拉相结合方式;客户端向服务端注册自己需要关注的节点,一旦该节点的数据发生变更,那么服务端就会向相应的客户端发送Watcher事件通知,客户端收到这个消息通知后,需要主动到服务端获取最新的数据。
2.4 集群管理
所谓集群管理,包括集群监控与集群控制两大块,前者侧重对集群状态运行时状态的收集,后者则是对集群进行操作和控制,在日常开发和运维过程中,我们经常会有类似于如下的需求:
1、希望知道当前集群中究竟有多少机器在工作。
2、对集群中每台机器的运行时状态进行数据收集。
3、对集群中的机器进行上下线操作。
ZooKeeper具有以下两大特性:
-
客户端如果对ZooKeeper的一个数据节点注册Watcher监听,那么当该数据节点的内容或其子节点列表发生变更时,ZooKeeper服务器就会向订阅的客户端发送变更通知。
-
对在ZooKeeper上创建的临时节点,一旦客户端与服务器之间的会话失败,那么该临时节点也就被自动清除。
Watcher(事件监听器),是Zookeeper中的一个很重要的特性。ZooKeeper允许用户在指定节点上注册一些Watcher,并且在一些特定事件触发的时候,ZooKeeper服务器端会将时间通知到感兴趣的客户端上去,该机制是ZooKeeper实现分布式协调服务的重要特性。
0 生产者启动
1 生产者注册至zookeeper
2 消费者启动并订阅频道
3 zookeeper通知消费者事件
4 消费者调用生产者
5 监控中心负责统计和监控服务状态
3 ZooKeeper单机安装
3.1 配置java环境
官方依赖介绍:
3.2 部署ZooKeeper
官网下载地址:https://archive.apache.org/dist/zookeeper/
#创建zookeeper目录 mkdir -p /apps/zookeeper #进入目录 cd /apps/zookeeper #下载zookeeper wget https://archive.apache.org/dist/zookeeper/zookeeper-3.7.0/apache-zookeeper-3.7.0-bin.tar.gz #解压 tar xvf apache-zookeeper-3.7.0-bin.tar.gz #创建软链接 ln -sv aapache-zookeeper-3.7.0-bin zookeeper #复制配置文件 cd zookeeper/conf/ cp zoo_sample.cfg zoo.cfg #查看配置文件 root@debian10-10:/apps/zookeeper/zookeeper/conf# grep ^[a-Z] zoo.cfg tickTime=2000 initLimit=10 syncLimit=5 dataDir=/tmp/zookeeper clientPort=2181 #启动zookeeper root@debian10-10:/apps/zookeeper/zookeeper/conf# /apps/zookeeper/zookeeper/bin/zkServer.sh start ZooKeeper JMX enabled by default Using config: /apps/zookeeper/zookeeper/bin/../conf/zoo.cfg Starting zookeeper ... STARTED #查看zookeeper状态 root@debian10-10:/apps/zookeeper/zookeeper/conf# /apps/zookeeper/zookeeper/bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /apps/zookeeper/zookeeper/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Client SSL: false. Mode: standalone #验证zookeeper进程 root@debian10-10:/apps/zookeeper/zookeeper/conf# ss -ntlp State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=444,fd=3)) LISTEN 0 5 127.0.0.1:631 0.0.0.0:* users:(("cupsd",pid=475,fd=7)) LISTEN 0 128 127.0.0.1:6010 0.0.0.0:* users:(("sshd",pid=582,fd=11)) LISTEN 0 50 *:8080 *:* users:(("java",pid=2922,fd=51)) LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=444,fd=4)) LISTEN 0 5 [::1]:631 [::]:* users:(("cupsd",pid=475,fd=6)) LISTEN 0 128 [::1]:6010 [::]:* users:(("sshd",pid=582,fd=10)) LISTEN 0 50 *:2181 *:* users:(("java",pid=2922,fd=59)) LISTEN 0 50 *:37609 *:* users:(("java",pid=2922,fd=47))
3.3 使用systemctl管理zookeeper服务
zookeeper.service文件
#编写service文件 vim /usr/lib/systemd/system/zookeeper.service [Unit] Description=Zookeeper Service unit Configuration After=network.target Documentation=https://zookeeper.apache.org/ [Service] Type=forking Environment=JAVA_HOME=/apps/java/jdk ExecStart=/apps/zookeeper/bin/zkServer.sh start /apps/zookeeper/conf/zoo.cfg ExecStop=/apps/zookeeper/bin/zkServer.sh stop ExecReload=/apps/zookeeper/bin/zkServer.sh restart KillMode=none User=root Group=root Restart=on-failure [Install] WantedBy=multi-user.target
3.4 报错解决
查看日志出现一下错误:
Unable to start AdminServer, exiting abnormally org.apache.zookeeper.server.admin.AdminServer$AdminServerException: Problem starting AdminServer on address 0.0.0.0, port 8080 and command URL /commands。
造成原因:
zookeeper的新版中用了netty做为了内嵌的控制台服务,默认占用8080端口;且博主的主机的8080端口被占用了。
解决方案:
#方法一:修改端口 修改配置文件zoo.cfg,添加下面这行 #端口可以按需求修改 admin.serverPort=8001 #方法二: 删除jetty #方法三: 停用这个服务,在启动脚本中增加"-Dzookeeper.admin.enableServer=false"
原文链接:https://blog.csdn.net/lihaitao910215/article/details/105176064
4 ZooKeeper集群搭建
4.1 ZooKeeper集群介绍
ZooKeeper集群用于解决单点和单机性能及数据高可用等问题。
集群结构:
集群角色功能:
集群特征:
整个集群种只要有超过集群数量一半的 zookeeper工作正常的,那么整个集群对外就是可用的,假如有 2 台服务器做了一个 zookeeper集群,只要有任何一台故障或宕机,那么这个 zookeeper 集群就不可用了,因为剩下的一台没有超过集群一半的数量,但是假如有三台 zookeeper组成一个集群,那么损坏一台就还剩两台,大于 3 台的一半,所以损坏一台还是可以正常运行的,但是再损坏一台就只剩一台集群就不可用了。那么要是 4 台组成一个zookeeper 集群,损坏一台集群肯定是正常的,那么损坏两台就还剩两台,那么2 台不大于集群数量的一半,所以 3 台的 zookeeper 集群和 4 台的 zookeeper 集群损坏两台的结果都是集群不可用,以此类推 5 台和 6 台以及 7 台和 8 台都是同理,所以这也就是为什么集群一般都是奇数的原因。
集群选举过程:
-
Leader election(选举阶段):节点在一开始都处于选举阶段,只要有一个节点得到超过半数节点的票数,它就可以当选准 Leader。
-
Discovery(发现阶段):在这个阶段,Followers跟准Leader进行通信,同步Followers最近接收的事务提议。
-
Synchronization(同步阶段):同步阶段主要是利用Leader前一阶段获得的最新提议历史,同步集群中所有的副本。同步完成之后准Leader才会成为真正的Leader。
-
Broadcast(广播阶段): 到了这个阶段,Zookeeper集群才能正式对外提供事务服务,并且Leader 可以进行消息广播。同时如果有新的节点加入,还需要对新节点进行同步。
4.2 部署ZooKeeper集群
官方文档:https://zookeeper.apache.org/doc/r3.4.14/zookeeperAdmin.html
操作系统:debian10 java版本:1.8 ZooKeeper版本:3.7.0
#各节点IP 节点1 10.0.0.10 节点2 10.0.0.20 节点3 10.0.0.30
部署java环境
#创建java的目录 mkdir -p /apps/java #将下载好的文件传到目录下解压 tar xvf jdk-8u271-linux-x64.tar.gz #创建软链接 ln -sv jdk1.8.0_271/ jdk #配置环境变量 vim /etc/profile.d/java.sh #java环境变量 export JAVA_HOME=/apps/java/jdk export JRE_HOME=$JAVA_HOME/jre export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH #同步文件 source /etc/profile.d/java.sh #测试java环境变量是否配置成功 root@ubuntu-40:/apps# java -version java version "1.8.0_271" Java(TM) SE Runtime Environment (build 1.8.0_271-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.271-b09, mixed mode)
ZooKeeper部署
#创建zookeeper目录 mkdir -p /apps #进入目录 cd /apps #下载zookeeper wget https://archive.apache.org/dist/zookeeper/zookeeper-3.7.0/apache-zookeeper-3.7.0-bin.tar.gz #解压 tar xvf apache-zookeeper-3.7.0-bin.tar.gz #创建软链接 ln -sv apache-zookeeper-3.7.0-bin zookeeper #复制配置文件 cd zookeeper/conf/ cp zoo_sample.cfg zoo.cfg #创建zookeeper数据目录 mkdir -p /apps/zookeeper/data #将自己的集群id写入myid文件 echo '1' > /apps/zookeeper/data/myid #查看配置文件 root@debian10-10:/apps/zookeeper/conf# cat zoo.cfg #服务器与服务器之间的单次心跳检测时间间隔,单位为毫秒 tickTime=2000 #集群中 leader 服务器与 follower 服务器初始连接心跳次数,即多少个2000毫秒 initLimit=10 #leader与follower之间连接完成之后,后期检测发送和应答的心跳次数,如果该follower在设置的时间内(5*2000)不能与leader进行通信,那么此follower将被视为不可用。 syncLimit=5 #自定义的zookeeper保存数据的目录 dataDir=/apps/zookeeper/data #客户端连接 Zookeeper 服务器的端口,Zookeeper会监听这个端口,接受客户端的访问请求 clientPort=2181 #单个客户端IP可以和zookeeper保持的连接数 maxClientCnxns=128 #3.4.0中的新增功能:启用后,ZooKeeper 自动清除功能会将 autopurge.snapRetainCount 最新快照和相应的事务日志分别保留在 dataDir 和 dataLogDir 中,并删除其余部分,默认值为3。最小值为3。 autopurge.snapRetainCount=3 #3.4.0及之后版本,ZK 提供了自动清理日志和快照文件的功能,这个参数指定了清理频率,单位是小时,需要配置一个 1 或更大的整数,默认是 0,表示不开启自动清理功能 autopurge.purgeInterval=1 #server.服务器编号=服务器 IP:LF 数据同步端口:LF 选举端口 server.1=10.0.0.10:2888:3888 server.2=10.0.0.20:2888:3888 server.3=10.0.0.30:2888:3888 #把配置文件分发到其他服务器 scp /app/zookeeper/conf/zoo.cfg 10.0.0.20:/app/zookeeper/conf/zoo.cfg scp /app/zookeeper/conf/zoo.cfg 10.0.0.30:/app/zookeeper/conf/zoo.cfg
java部署请参考上面
#创建zookeeper目录 mkdir -p /apps #进入目录 cd /apps #下载zookeeper wget https://archive.apache.org/dist/zookeeper/zookeeper-3.7.0/apache-zookeeper-3.7.0-bin.tar.gz #解压 tar xvf apache-zookeeper-3.7.0-bin.tar.gz #创建软链接 ln -sv apache-zookeeper-3.7.0-bin zookeeper #复制配置文件 cd zookeeper/conf/ cp zoo_sample.cfg zoo.cfg #创建zookeeper数据目录 mkdir -p /apps/zookeeper/data #将自己的集群id写入myid文件 echo '2' > /apps/zookeeper/data/myid #查看配置文件 root@debian10-20:/apps/zookeeper/conf# cat zoo.cfg #服务器与服务器之间的单次心跳检测时间间隔,单位为毫秒 tickTime=2000 #集群中 leader 服务器与 follower 服务器初始连接心跳次数,即多少个2000毫秒 initLimit=10 #leader与follower之间连接完成之后,后期检测发送和应答的心跳次数,如果该follower在设置的时间内(5*2000)不能与leader进行通信,那么此follower将被视为不可用。 syncLimit=5 #自定义的zookeeper保存数据的目录 dataDir=/apps/zookeeper/data #客户端连接 Zookeeper 服务器的端口,Zookeeper会监听这个端口,接受客户端的访问请求 clientPort=2181 #单个客户端IP可以和zookeeper保持的连接数 maxClientCnxns=128 #3.4.0中的新增功能:启用后,ZooKeeper 自动清除功能会将 autopurge.snapRetainCount 最新快照和相应的事务日志分别保留在 dataDir 和 dataLogDir 中,并删除其余部分,默认值为3。最小值为3。 autopurge.snapRetainCount=3 #3.4.0及之后版本,ZK 提供了自动清理日志和快照文件的功能,这个参数指定了清理频率,单位是小时,需要配置一个 1 或更大的整数,默认是 0,表示不开启自动清理功能 autopurge.purgeInterval=1 #server.服务器编号=服务器 IP:LF 数据同步端口:LF 选举端口 server.1=10.0.0.10:2888:3888 server.2=10.0.0.20:2888:3888 server.3=10.0.0.30:2888:3888
#创建zookeeper目录 mkdir -p /apps #进入目录 cd /apps #下载zookeeper wget https://archive.apache.org/dist/zookeeper/zookeeper-3.7.0/apache-zookeeper-3.7.0-bin.tar.gz #解压 tar xvf apache-zookeeper-3.7.0-bin.tar.gz #创建软链接 ln -sv apache-zookeeper-3.7.0-bin zookeeper #复制配置文件 cd zookeeper/conf/ cp zoo_sample.cfg zoo.cfg #创建zookeeper数据目录 mkdir -p /apps/zookeeper/data #将自己的集群id写入myid文件 echo '3' > /apps/zookeeper/data/myid #查看配置文件 root@debian10-30:/apps/zookeeper/conf# cat zoo.cfg #服务器与服务器之间的单次心跳检测时间间隔,单位为毫秒 tickTime=2000 #集群中 leader 服务器与 follower 服务器初始连接心跳次数,即多少个2000毫秒 initLimit=10 #leader与follower之间连接完成之后,后期检测发送和应答的心跳次数,如果该follower在设置的时间内(5*2000)不能与leader进行通信,那么此follower将被视为不可用。 syncLimit=5 #自定义的zookeeper保存数据的目录 dataDir=/apps/zookeeper/data #客户端连接 Zookeeper 服务器的端口,Zookeeper会监听这个端口,接受客户端的访问请求 clientPort=2181 #单个客户端IP可以和zookeeper保持的连接数 maxClientCnxns=128 #3.4.0中的新增功能:启用后,ZooKeeper 自动清除功能会将 autopurge.snapRetainCount 最新快照和相应的事务日志分别保留在 dataDir 和 dataLogDir 中,并删除其余部分,默认值为3。最小值为3。 autopurge.snapRetainCount=3 #3.4.0及之后版本,ZK 提供了自动清理日志和快照文件的功能,这个参数指定了清理频率,单位是小时,需要配置一个 1 或更大的整数,默认是 0,表示不开启自动清理功能 autopurge.purgeInterval=1 #server.服务器编号=服务器 IP:LF 数据同步端口:LF 选举端口 server.1=10.0.0.10:2888:3888 server.2=10.0.0.20:2888:3888 server.3=10.0.0.30:2888:3888
#节点1 root@debian10-10:~# /apps/zookeeper/bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /apps/zookeeper/bin/../conf/zoo.cfg myid could not be determined, will not able to locate clientPort in the server configs. Client port found: 2181 . Client address: localhost. Client SSL: false. Mode: follower #节点2 root@debian10-20:~# /apps/zookeeper/bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /apps/zookeeper/bin/../conf/zoo.cfg myid could not be determined, will not able to locate clientPort in the server configs. Client port found: 2181 . Client address: localhost. Client SSL: false. Mode: leader #节点3 root@debian10-30:~# /apps/zookeeper/bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /apps/zookeeper/bin/../conf/zoo.cfg myid could not be determined, will not able to locate clientPort in the server configs. Client port found: 2181 . Client address: localhost. Client SSL: false. Mode: follower