首页 > 图灵资讯 > 技术篇>正文

一篇文章带你入门Zookeeper

2023-04-17 11:43:59

  Zookeeper是什么?

  zookeeeper是官方文件中的分布式服务框架,是apacheer Hadoop 子项目主要用于解决分布式应用中经常遇到的数据管理问题,如统一命名服务、状态同步服务、集群管理、分布式应用配置项目管理等。

  以上解释有点抽象,简单来说zookeeper=文件系统+监听通知机制。

  1、 文件系统

  Zookeeper维护类似文件系统的数据结构:

  如每个子目录项 NameService 都被称作为 znode(目录节点),就像文件系统一样,我们可以自由添加和删除znode,在znode下添加和删除子znode。唯一的区别是znode可以存储数据。

  znodeee有四种类型:

  PERSISTENT-持久的目录节点

  客户端与zookeeper断开连接后,该节点仍然存在

  PERSISTENT_SEQUENTIAL-持久顺序编号目录节点

  客户端与zookeeper断开连接后,节点仍然存在,但Zookeeeper将节点名称编号成序列号

  EPHEMERAL-临时目录节点

  客户端与zookeeper断开连接后,节点被删除

  EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点

  客户端与zookeeper断开连接后,节点被删除,但Zookeeeper将节点名称编号为顺序

  2、 监控通知机制

  客户端注册并监控其关心的目录节点。当目录节点发生变化(数据变更、删除、子目录节点添加和删除)时,zookeeper将通知客户端。

  就这么简单,我们来看看Zookeeper能做些什么。

  Zookeper能做什么?

  zookeper功能强大,可实现分布式应用配置管理、统一命名服务、状态同步服务、集群管理等功能。以简单的分布式应用配置管理为例。

  假设我们的程序是分布式部署在多台机器上的,如果我们想改变程序的配置文件,我们需要逐台修改,这是非常麻烦的。现在我们把所有这些配置都放在zookeeper上,保存下来 zookeeper 一旦配置信息发生变化,所有相关应用程序都将监控该目录节点,每个应用程序都会收到 zookeeper 通知,然后从 zookeeper 在系统中获取新的配置信息。

  以上,你应该大致了解zookeper是什么,你能做什么。我们将立即学习zookeper的安装和使用,并开发一个小程序来实现zookeper的分布式配置管理功能。

  Zookeper单机模式安装

  Step1:JAVA环境的配置,环境的检验:java -version

  Step2:下载并解压zookeper# cd /usr/local # wget http://mirror.bit.edu.cn/apache/zookeeper/stable/zookeeper-3.4.12.tar.gz # tar -zxvf zookeeper-3.4.12.tar.gz # cd zookeeper-3.4.12

  Step3:zoo_重命名配置文件sample.cfg # cp conf/zoo_sample.cfg conf/zoo.cfg

  Step4:启动zookeper # bin/zkServer.sh start

  Step5:检测服务端是否成功启动,并与zookeper客户端连接 # bin/zkCli.sh

  Zookeper使用

  使用客户端命令操作zookeperer

  1、使用 ls 命令查看当前情况 ZooKeeper 其中包含的内容 [zk: localhost:2181(CONNECTED) 1] ls / [dubbo, default, zookeeper] [zk: localhost:2181(CONNECTED) 2]

  2、创造新的 znode ,使用 create /zkPro myData [zk: localhost:2181(CONNECTED) 2] create /zkPro myData Created /zkPro [zk: localhost:2181(CONNECTED) 3]

  3、再次使用 ls 命令来查看现在 zookeeper 内容包含: [zk: localhost:2181(CONNECTED) 3] ls / [dubbo, default, zookeeper, zkPro] [zk: localhost:2181(CONNECTED) 4]

  4、让我们在下面操作 get 确认第二步创建的命令 znode 是否包含我们创建的字符串: [zk: localhost:2181(CONNECTED) 6] get /zkPro myData cZxid = 0x1146 ctime = Tue Sep 04 10:40:49 CST 2018 mZxid = 0x1146 mtime = Tue Sep 04 10:40:49 CST 2018 pZxid = 0x1146 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 6 numChildren = 0 [zk: localhost:2181(CONNECTED) 7]

  5、下面我们通过 set 命令来对 zk 设置相关字符串: [zk: localhost:2181(CONNECTED) 7] set /zkPro myData123466 cZxid = 0x1146 ctime = Tue Sep 04 10:40:49 CST 2018 mZxid = 0x1147 mtime = Tue Sep 04 10:43:59 CST 2018 pZxid = 0x1146 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 12 numChildren = 0 [zk: localhost:2181(CONNECTED) 8]

  6、接下来,我们将创建我们刚刚创建的 znode 删除 [zk: localhost:2181(CONNECTED) 8] delete /zkPro [zk: localhost:2181(CONNECTED) 9]

  使用Java API操作zookeperer

  使用Java API操作zookeeper需要引用以下包 com.101tec zkclient 0.10

  让我们实现上述分布式配置中心:

  1、在zookeeper中添加一个目录节点,并将配置信息存储在其中 [zk: localhost:2181(CONNECTED) 9] create /username zhangsan Created /username [zk: localhost:2181(CONNECTED) 10]

  2、启动两个zookeper客户端程序,代码如下 import java.util.concurrent.CountDownLatch; 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.ZooKeeper; import org.apache.zookeeper.data.Stat; /** * demo分布式配置中心 * */ public class ZooKeeperProSync implements Watcher { private static CountDownLatch connectedSemaphore = new CountDownLatch(1); private static ZooKeeper zk = null; private static Stat stat = new Stat(); public static void main(String[] args) throws Exception { //zookeper配置数据存储路径 String path = "/username"; ///连接zookeeper并注册默认监听器 zk = new ZooKeeper("192.168.188.128:2181", 5000, // new ZooKeeperProSync()); ///等待zk连接成功的通知 connectedSemaphore.await(); //获取path目录节点的配置数据,并注册默认监听器 System.out.println(new String(zk.getData(path, true, stat))); Thread.sleep(Integer.MAX_VALUE); } public void process(WatchedEvent event) { if (KeeperState.SyncConnected == event.getState()) { ///zk连接成功通知事件 if (EventType.None == event.getType() && null == event.getPath()) { connectedSemaphore.countDown(); } else if (event.getType() == EventType.NodeDataChanged) { //zk目录节点数据变更通知事件 try { System.out.println(”配置已修改,新值为:" + new String(zk.getData(event.getPath(), true, stat))); } catch (Exception e) { } } } } }

  启动两个程序后,正确读取zookeper/username目录节点下的数据'zhangsan'

  3、我们在zookeper中修改目录节点/username下的数据 [zk: localhost:2181(CONNECTED) 10] set /username zhangsan123466 cZxid = 0x1149 ctime = Tue Sep 04 10:49:11 CST 2018 mZxid = 0x114a mtime = Tue Sep 04 10:52:08 CST 2018 pZxid = 0x1149 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 14 numChildren = 0 [zk: localhost:2181(CONNECTED) 11]

  修改完成后,我们看到两个程序的后台及时收到了他们监控的目录节点数据变更的值,如下所示:

  zhangsan 已修改配置,新值为:zhangsan123456

  Zookeper集群模式安装

  本例构建伪集群模式,即在机器上启动三个zookeper实例组成集群。真正的集群模式只不过是不同的实例IP地址,施工方法没有区别

  Step1:JAVA环境的配置,环境的检验:java -version

  Step2:下载并解压zookeper # cd /usr/local # wget http://mirror.bit.edu.cn/apache/zookeeper/stable/zookeeper-3.4.12.tar.gz # tar -zxvf zookeeper-3.4.12.tar.gz # cd zookeeper-3.4.12

  Step3:重命名 zoo_sample.cfg文件 # cp conf/zoo_sample.cfg conf/zoo-1.cfg

  Step4:修改配置文件zoo-1.cfg,原配置文件中有一些修改为以下值,没有的则添加 # vim conf/zoo-1.cfg dataDir=/tmp/zookeeper-1 clientPort=2181 server.1=127.0.0.1:2888:3888 server.2=127.0.0.1:2889:3889 server.3=127.0.0.1:2890:3890

  配置说明

  tickTime:这个时间就是行动 Zookeeper 保持服务器或客户端和服务器之间心跳的时间间隔,即每个服务器之间的时间间隔 tickTime 时间会发出心跳。 initLimit:该配置项用于配置 Zookeeper 接受客户端(这里提到的客户端不是用户连接) Zookeeper 相反,服务器的客户端 Zookeeper 连接到服务器集群 Leader 的 Follower 服务器)初始化连接时最长能忍受多少心跳时间间隔。当已经超过 10个心跳时间(即心跳时间) tickTime)长度后 Zookeeper 服务器还没有收到客户端的返回信息,这表明客户端连接失败。总时间长度为 10*2000=20 秒 syncLimit:本配置项标识 Leader 与 Follower 发送信息、请求和响应时间的长度不能超过多少 tickTime 时长,总时间长度为 5*2000=10秒 dataDir:顾名思义就是 Zookeeper 默认情况下,保存数据的目录,Zookeeper 在此目录中还保存了编写数据的日志文件。 clientPort:这个端口是客户端连接 Zookeeper 服务器端口,Zookeeper 会监控此端口,接受客户端的访问请求。 server.A=B:C:D:其中 A 它是一个数字,表示这是服务器的数量;B 是这个服务器 ip 地址;C 它表示服务器和集群中的服务器 Leader 服务器交换信息的端口;D 这意味着以防集群中的情况 Leader 服务器挂断了,需要一个港口重新选举,选择一个新的 Leader,这个端口是用来执行选举时服务器通信的端口。如果是伪集群的配置模式,因为 B 都是一样的,所以不同 Zookeeper 例如,通信端口号不能相同,因此应分配不同的端口号。

  Step5:再从zoo-1.zoo-2cfg复制两个配置文件.cfg和zoo-3.cfg,只需修改datadir和clientport之间的差异 # cp conf/zoo-1.cfg conf/zoo-2.cfg # cp conf/zoo-1.cfg conf/zoo-3.cfg # vim conf/zoo-2.cfg dataDir=/tmp/zookeeper-2 clientPort=2182 # vim conf/zoo-2.cfg dataDir=/tmp/zookeeper-3 clientPort=2183

  Step6:识别Server ID

  创建三个文件夹/tmp/zookeeper-1,/tmp/zookeeper-2,/tmp/zookeeper-2.在每个目录中创建文件myid 写入当前实例的serverr文件 id,即1.2.3 # cd /tmp/zookeeper-1 # vim myid 1 # cd /tmp/zookeeper-2 # vim myid 2 # cd /tmp/zookeeper-3 # vim myid 3

  Step7:启动三个zookeper实例 # bin/zkServer.sh start conf/zoo-1.cfg # bin/zkServer.sh start conf/zoo-2.cfg # bin/zkServer.sh start conf/zoo-3.cfg

  Step8:检测集群状态也可以直接使用命令“zkCli.sh -server IP:PORT”连接zookeper服务端检测:

  到目前为止,即使我们对zookeper有一个入门级的了解,当然zookeper的功能也比我们在这里描述的要多得多,比如用zookeper实现集群管理、分布式锁、分布式队列、zoookeper集群leader选举等。

上一篇 必须掌握的30种SQL语句优化
下一篇 高性能HTTP及反向代理服务器Nginx

文章素材均来源于网络,如有侵权,请联系管理员删除。