ZooKeeper学习总结 第一篇:ZooKeeper快速入门
1. 概述
Zookeeper是Hadoop的一个子项目,它是分布式系统中的协调系统,可提供的服务主要有:配置服务、名字服务、分布式同步、组服务等。
它有如下的一些特点:
- 简单
Zookeeper的核心是一个精简的文件系统,它支持一些简单的操作和一些抽象操作,例如,排序和通知。
- 丰富
Zookeeper的原语操作是很丰富的,可实现一些协调数据结构和协议。例如,分布式队列、分布式锁和一组同级别节点中的“领导者选举”。
- 高可靠
Zookeeper支持集群模式,可以很容易的解决单点故障问题。
- 松耦合交互
不同进程间的交互不需要了解彼此,甚至可以不必同时存在,某进程在zookeeper中留下消息后,该进程结束后其它进程还可以读这条消息。
- 资源库
Zookeeper实现了一个关于通用协调模式的开源共享存储库,能使开发者免于编写这类通用协议。
2. ZooKeeper的安装
- 独立模式安装
Zookeeper的运行环境是需要java的,建议安装oracle的java6.
可去官网下载一个稳定的版本,然后进行安装:http://zookeeper.apache.org/
解压后在zookeeper的conf目录下创建配置文件zoo.cfg,里面的配置信息可参考统计目录下的zoo_sample.cfg文件,我们这里配置为:
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/opt/zookeeper-data/ clientPort=2181
tickTime:指定了ZooKeeper的基本时间单位(以毫秒为单位);
initLimit:指定了启动zookeeper时,zookeeper实例中的随从实例同步到领导实例的初始化连接时间限制,超出时间限制则连接失败(以tickTime为时间单位);
syncLimit:指定了zookeeper正常运行时,主从节点之间同步数据的时间限制,若超过这个时间限制,那么随从实例将会被丢弃;
dataDir:zookeeper存放数据的目录;
clientPort:用于连接客户端的端口。
- 启动一个本地的ZooKeeper实例
% zkServer.sh start
检查ZooKeeper是否正在运行
echo ruok | nc localhost 2181
若是正常运行的话会打印“imok”。
3. ZooKeeper监控
- 远程JMX配置
默认情况下,zookeeper是支持本地的jmx监控的。若需要远程监控zookeeper,则需要进行进行如下配置。
默认的配置有这么一行:
ZOOMAIN="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=$JMXLOCALONLY org.apache.zookeeper.server.quorum.QuorumPeerMain"
咱们在$JMXLOCALONLY后边添加jmx的相关参数配置:
ZOOMAIN="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=$JMXLOCALONLY -Djava.rmi.server.hostname=192.168.1.8 -Dcom.sun.management.jmxremote.port=1911 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false org.apache.zookeeper.server.quorum.QuorumPeerMain"
这样就可以远程监控了,可以用jconsole.exe或jvisualvm.exe等工具对其进行监控。
- 身份验证
这里没有配置验证信息,如果需要请参见我的博文jvisualvm远程监控tomcat:http://www.cnblogs.com/leocook/p/jvisualvmandtomcat.html
4. Zookeeper的存储模型
Zookeeper的数据存储采用的是结构化存储,结构化存储是没有文件和目录的概念,里边的目录和文件被抽象成了节点(node),zookeeper里可以称为znode。Znode的层次结构如下图:
最上边的是根目录,下边分别是不同级别的子目录。
5. Zookeeper客户端的使用
- zkCli.sh
可使用./zkCli.sh -server localhost来连接到Zookeeper服务上。
使用ls /可查看根节点下有哪些子节点,可以双击Tab键查看更多命令。
- Java客户端
可创建org.apache.zookeeper.ZooKeeper对象来作为zk的客户端,注意,java api里创建zk客户端是异步的,为防止在客户端还未完成创建就被使用的情况,这里可以使用同步计时器,确保zk对象创建完成再被使用。
- C客户端
可以使用zhandle_t指针来表示zk客户端,可用zookeeper_init方法来创建。可在ZK_HOME\src\c\src\ cli.c查看部分示例代码。
6. Zookeeper创建Znode
Znode有两种类型:短暂的和持久的。短暂的znode在创建的客户端与服务器端断开(无论是明确的断开还是故障断开)连接时,该znode都会被删除;相反,持久的znode则不会。
public class CreateGroup implements Watcher{ private static final int SESSION_TIMEOUT = 1000;//会话延时 private ZooKeeper zk = null; private CountDownLatch countDownLatch = new CountDownLatch(1);//同步计数器 public void process(WatchedEvent event) { if(event.getState() == KeeperState.SyncConnected){ countDownLatch.countDown();//计数器减一 } } /** * 创建zk对象 * 当客户端连接上zookeeper时会执行process(event)里的countDownLatch.countDown(),计数器的值变为0,则countDownLatch.await()方法返回。 * @param hosts * @throws IOException * @throws InterruptedException */ public void connect(String hosts) throws IOException, InterruptedException { zk = new ZooKeeper(hosts, SESSION_TIMEOUT, this); countDownLatch.await();//阻塞程序继续执行 } /** * 创建group * * @param groupName 组名 * @throws KeeperException * @throws InterruptedException */ public void create(String groupName) throws KeeperException, InterruptedException { String path = "/" + groupName; String createPath = zk.create(path, null, Ids.OPEN_ACL_UNSAFE/*允许任何客户端对该znode进行读写*/, CreateMode.PERSISTENT/*持久化的znode*/); System.out.println("Created " + createPath); } /** * 关闭zk * @throws InterruptedException */ public void close() throws InterruptedException { if(zk != null){ try { zk.close(); } catch (InterruptedException e) { throw e; }finally{ zk = null; System.gc(); } } } }
这里我们使用了同步计数器CountDownLatch,在connect方法中创建执行了zk = new ZooKeeper(hosts, SESSION_TIMEOUT, this);之后,下边接着调用了CountDownLatch对象的await方法阻塞,因为这是zk客户端不一定已经完成了与服务端的连接,在客户端连接到服务端时会触发观察者调用process()方法,我们在方法里边判断一下触发事件的类型,完成连接后计数器减一,connect方法中解除阻塞。
还有两个地方需要注意:这里创建的znode的访问权限是open的,且该znode是持久化存储的。
测试类如下:
public class CreateGroupTest { private static String hosts = "192.168.1.8"; private static String groupName = "zoo"; private CreateGroup createGroup = null; /** * init * @throws InterruptedException * @throws KeeperException * @throws IOException */ @Before public void init() throws KeeperException, InterruptedException, IOException { createGroup = new CreateGroup(); createGroup.connect(hosts); } @Test public void testCreateGroup() throws KeeperException, InterruptedException { createGroup.create(groupName); } /** * 销毁资源 */ @After public void destroy() { try { createGroup.close(); createGroup = null; System.gc(); } catch (InterruptedException e) { e.printStackTrace(); } } }
由于zk对象的创建和销毁代码是可以复用的,所以这里我们把它分装成了接口:
/** * 连接的观察者,封装了zk的创建等 * @author leo * */ public class ConnectionWatcher implements Watcher { private static final int SESSION_TIMEOUT = 5000; protected ZooKeeper zk = null; private CountDownLatch countDownLatch = new CountDownLatch(1); public void process(WatchedEvent event) { KeeperState state = event.getState(); if(state == KeeperState.SyncConnected){ countDownLatch.countDown(); } } /** * 连接资源 * @param hosts * @throws IOException * @throws InterruptedException */ public void connection(String hosts) throws IOException, InterruptedException { zk = new ZooKeeper(hosts, SESSION_TIMEOUT, this); countDownLatch.await(); } /** * 释放资源 * @throws InterruptedException */ public void close() throws InterruptedException { if (null != zk) { try { zk.close(); } catch (InterruptedException e) { throw e; }finally{ zk = null; System.gc(); } } } }
7. Zookeeper删除Znode
/** * 删除分组 * @author leo * */ public class DeleteGroup extends ConnectionWatcher { public void delete(String groupName) { String path = "/" + groupName; try { List<String> children = zk.getChildren(path, false); for(String child : children){ zk.delete(path + "/" + child, -1); } zk.delete(path, -1);//版本号为-1, } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }
zk.delete(path,version)方法的第二个参数是znode版本号,如果提供的版本号和znode版本号一致才会删除这个znode,这样可以检测出对znode的修改冲突。通过将版本号设置为-1,可以绕过这个版本检测机制,无论znode的版本号是什么,都会直接将其删除。
测试类:
public class DeleteGroupTest { private static final String HOSTS = "192.168.1.137"; private static final String groupName = "zoo"; private DeleteGroup deleteGroup = null; @Before public void init() throws IOException, InterruptedException { deleteGroup = new DeleteGroup(); deleteGroup.connection(HOSTS); } @Test public void testDelete() throws IOException, InterruptedException, KeeperException { deleteGroup.delete(groupName); } @After public void destroy() throws InterruptedException { if(null != deleteGroup){ try { deleteGroup.close(); } catch (InterruptedException e) { throw e; }finally{ deleteGroup = null; System.gc(); } } } }
8. Zookeeper的相关操作
ZooKeeper中共有9中操作:
create:创建一个znode
delete:删除一个znode
exists:测试一个znode
getACL,setACL:获取/设置一个znode的ACL(权限控制)
getChildren:获取一个znode的子节点
getData,setData:获取/设置一个znode所保存的数据
sync:将客户端的znode视图与ZooKeeper同步
这里更新数据是必须要提供znode的版本号(也可以使用-1强制更新,这里可以执行前通过exists方法拿到znode的元数据Stat对象,然后从Stat对象中拿到对应的版本号信息),如果版本号不匹配,则更新会失败。因此一个更新失败的客户端可以尝试是否重试或执行其它操作。
9. ZooKeeper的API
ZooKeeper的api支持多种语言,在操作时可以选择使用同步api还是异步api。同步api一般是直接返回结果,异步api一般是通过回调来传送执行结果的,一般方法中有某参数是类AsyncCallback的内部接口,那么该方法应该就是异步调用,回调方法名为processResult。
10. 观察触发器
可以对客户端和服务器端之间的连接设置观察触发器(后边称之为zookeeper的状态观察触发器),也可以对znode设置观察触发器。
- 状态观察器
zk的整个生命周期如下:
可在创建zk对象时传入一个观察器,在完成CONNECTING状态到CONNECTED状态时,观察器会触发一个事件,该触发的事件类型为NONE,通过event.getState()方法拿到事件状态为SyncConnected。有一点需要注意的就是,在zk调用close方法时不会触发任何事件,因为这类的显示调用是开发者主动执行的,属于可控的,不用使用事件通知来告知程序。这一块在下篇博文还会详细解说。
- 设置znode的观察器
可以在读操作exists、getChildren和getData上设置观察,在执行写操作create、delete和setData将会触发观察事件,当然,在执行写的操作时,也可以选择是否触发znode上设置的观察器,具体可查看相关的api。
当观察的znode被创建、删除或其数据被更新时,设置在exists上的观察将会被触发;
当观察的znode被删除或数据被更新时,设置在getData上的观察将会被触发;
当观察的znode的子节点被创建、删除或znode自身被删除时,设置在getChildren上的观察将会被触发,可通过观察事件的类型来判断被删除的是znode还是它的子节点。
对于NodeCreated和NodeDeleted根据路径就能发现是哪个znode被写;对于NodeChildrenChanged可根据getChildren来获取新的子节点列表。
注意:在收到收到触发事件到执行读操作之间,znode的状态可能会发生状态,这点需要牢记。
至此,编写简单的zookeeper应该是可以的了,下篇博文咱们来深入探讨zookeeper的相关知识。
原文:http://www.cnblogs.com/leocook/p/zk_0.html
相关推荐
**Zookeeper系列1:入门** Zookeeper是一款分布式协调服务,由Apache基金会开发,广泛应用于分布式系统中的数据共享、配置管理、命名服务、集群同步等场景。它的设计目标是简化分布式环境下的复杂问题,提供高可用...
这个"Zookeeper入门练习Demo"旨在帮助初学者快速掌握Zookeeper的基本操作和概念,通过实际操作来加深理解。 **一、搭建Zookeeper集群服务器** 1. **系统需求**:首先确保你有一组运行Java的服务器,Zookeeper要求...
观看这个视频,你可以获得ZooKeeper入门的第一手经验,了解如何在本地环境中设置和运行ZooKeeper服务器,以及如何通过命令行工具进行交互。 总的来说,"Zookeeper 学习资料 上篇"会带你走进ZooKeeper的世界,从基础...
本套课程中,第一阶段深入Zookeeper原理和源码,分析Zookeeper的核心实现,并通过多个应用场景说明,体现出其重要性和广泛的应用性。第二阶段深入Dubbo RPC、SPI等核心功能点,列举多个示例加以应用说明,期望能够...
总结来说,Hadoop快速入门的第四章主要介绍了Zookeeper的安装和配置,这对于理解和实践Hadoop分布式计算至关重要。通过学习Zookeeper,你可以更好地理解分布式系统的协调机制,提升你在大数据领域的专业能力。
内容概要:本文档分为三个主要部分介绍了如何开始使用 ZooKeeper:第一部分是首次启动并体验ZooKeeper,涉及服务器的启动和基本的状态查询;第二部分则是关于ZooKeeper配置的基本理解和修改,特别是客户端的最大连接...
ZooInspector是Zookeeper的一个图形化管理工具,可以从ZooKeeper入门简介及配置使用.pdf中了解到如何使用。它可以帮助开发者直观地查看和调试Zookeeper集群的状态,包括节点结构、节点数据和会话信息等。 **应用...
第一阶段:JavaSE+MySql+Linux * Java 语言入门:掌握 Java 语言的基本语法和数据类型 * OOP 编程:掌握面向对象编程的基本概念和设计模式 * Java 常用 Api:掌握 Java 的常用 API 和工具类 * 集合:掌握 Java 的...
【大数据入门笔记系列】第二节 Zookeeper简介 Zookeeper是一个分布式协调服务,它是Apache Hadoop项目的一个子项目,专为大规模分布式应用设计。Zookeeper的主要功能包括配置管理、命名服务、分布式同步、组服务等...
第1节:kafka简史.avi-z;i\'L.R#P0X.E 第2节:部署开发环境.avi 第3节:安装VM虚拟机.avi%f;P)^!W"z5O/f/N 第4节:添加Centos镜像.avi 第5节:安装CentOS7.avi 第6节:SSH远程连接工具的使用.avi 第7节:环境准备常见问题...
### Kafka入门知识点详解 #### 一、概述与系统环境 Kafka是一款强大的分布式消息系统,主要应用于实时数据处理场景。其高效的数据传输能力和高吞吐量特性使其在大数据领域受到广泛青睐。 - **系统环境**:本文档...
"Zookeeper入门到精通"这个压缩包文件可能包含一系列教程、代码示例、实践案例,帮助读者逐步掌握ZooKeeper的使用。通过学习这个资源,你可以从基础理论到实际操作,全面掌握ZooKeeper,从而在大数据领域更进一步。
第一章 大数据基础和Zookeeper入门 第二章 Zookeeper操作和Hadoop环境搭建 第三章 HDFS操作 第四章 HDFS的JavaAPI操作和MapReduce入门 第五章 MapReduce的WordCount案例和分区 第六章 MapReduce的排序和序列化 第七...
在后端开发中,选择合适的编程语言是至关重要的第一步。以下几种编程语言被广泛应用于后端开发: 1. **Java**:Java 是一种跨平台的面向对象编程语言,以其稳定性、安全性以及强大的生态系统而闻名。它适用于构建...
### 二、快速入门:服务端项目创建与配置 1. 创建服务端项目,首先需要在`pom.xml`中引入Dubbo依赖: ```xml <groupId>org.apache.dubbo <artifactId>dubbo <version>2.7.4.1 ``` 2. 编写服务端代码,定义...
推荐《鸟哥的 Linux 私房菜 基础学习篇 第四版》、《Maven 实战》、《深入理解 Apache Dubbo 与实战》、《ZooKeeper 分布式过程协同技术详解》、《Nginx 高性能 Web服务器详解》和《Spring Cloud 微服务:入门、实战...
在【压缩包子文件的文件名称列表】中的"storm入门@www.java1234.com.pdf"很可能是一个详细教程或指南,它会逐步讲解如何安装Storm,设置开发环境,编写第一个拓扑,以及如何理解和使用Storm的各个组件。这份PDF文件...
--第05章选举模式和ZooKeeper的集群安装---第06章使用ZooKeeper原生JavaAPI进行客户端开发---第07章ApacheCurator客户端的使用---第08章Dubbo入门到重构服务---第09章分布式锁---第10章课程总结---project.zip---zk_...
格式化NameNode是启动Hadoop集群的第一步,使用`hdfs namenode –format`命令。然后,通过`start-dfs.sh`脚本启动Hadoop DFS服务。在所有节点上运行`jps`命令,检查Hadoop进程是否正确启动。 为了验证Hadoop集群的...
3. **文档**:可能包含API文档、用户指南、快速入门教程等,帮助开发者理解和使用Zookeeper。 4. **示例代码**:可能有预编译好的示例程序,用于演示如何连接和操作Zookeeper。 5. **开发工具**:如zkCli,Zookeeper...