Hadoop之Zookeeper
来源:互联网 发布:linux上安装oracle11g 编辑:程序博客网 时间:2024/06/06 02:41
Hadoop之Zookeeper
ZooKeeper是一个分布式的,开放源码的分布式应用程序协同服务。是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件
简介
曾是Hadoop子项目,现为顶级项目ZooKeeper是协同服务ZooKeeper为分布式应用提供服务ZooKeeper支持Java和C语言
提供服务
配置维护名字服务分布式同步组服务等。
目标
封装复杂、易错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户
ZooKeeper流程
1.选举Leader2.同步数据3.选举Leader过程中算法有很多,但要达到的选举标准是一致的4.Leader要具有最高的zxid5.集群中大多数的机器得到响应并follow选出的Leader
存放数据的数据结构
通过/分隔开路径名每个路径代表一个节点Znode(zookeeper node)
子节点–Znode
每个Znode有自身信息,数据、长度、创建时间、修改时间。Znode维护数据、ACL(access control list,访问控制列表)、时间戳等交换版本号等数据结构,它通过对这些数据的管理来让缓存生效并且令协调更新。每当Znode中的数据更新后版本号将增加。
读写操作
读写数据原子性,读就读取所有数据,写入时完全覆盖。Znode的ACL存储用户操作权限。
临时节点
和session相关,session结束,节点删除
ZooKeeper安装
略
ZooKeeper 常用四字命令
ZooKeeper 支持某些特定的四字命令字母与其的交互。它们大多是查询命令,用来获取ZooKeeper 服务的当前状态及相关信息。用户在客户端可以通过 telnet 或 nc 向 ZooKeeper 提交相应的命令
1. 可以通过命令:echo stat|nc 127.0.0.1 2181 来查看哪个节点被选择作为follower或者leader2. 使用echo ruok|nc 127.0.0.1 2181 测试是否启动了该Server,若回复imok表示已经启动。3. echo dump| nc 127.0.0.1 2181 ,列出未经处理的会话和临时节点。4. echo kill | nc 127.0.0.1 2181 ,关掉server5. echo conf | nc 127.0.0.1 2181 ,输出相关服务配置的详细信息。6. echo cons | nc 127.0.0.1 2181 ,列出所有连接到服务器的客户端的完全的连接 / 会话的详细信息。7. echo envi |nc 127.0.0.1 2181 ,输出关于服务环境的详细信息(区别于 conf 命令)。8. echo reqs | nc 127.0.0.1 2181 ,列出未经处理的请求。9. echo wchs | nc 127.0.0.1 2181 ,列出服务器 watch 的详细信息。10. echo wchc | nc 127.0.0.1 2181 ,通过 session 列出服务器 watch 的详细信息,它的输出是一个与 watch 相关的会话的列表。11. echo wchp | nc 127.0.0.1 2181 ,通过路径列出服务器 watch 的详细信息。它输出一个与 session 相关的路径。
Zookeeper的简单操作
Zookeeper的shell操作
- Zookeeper命令工具
启动Zookeeper服务之后,输入以下命令,连接到Zookeeper服务:
zkCli.sh -server localhost:2181
执行结果如下所示:
[root@master ~]# zkCli.sh -server master:2181Connecting to master:21812017-07-18 03:00:34,503 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.6-1569965, built on 02/20/2014 09:09 GMT2017-07-18 03:00:34,508 [myid:] - INFO [main:Environment@100] - Client environment:host.name=master2017-07-18 03:00:34,509 [myid:] - INFO [main:Environment@100] - Client environment:java.version=1.8.0_1312017-07-18 03:00:34,514 [myid:] - INFO [main:Environment@100] - Client environment:java.vendor=Oracle Corporation2017-07-18 03:00:34,514 [myid:] - INFO [main:Environment@100] - Client environment:java.home=/usr/local/java/jre2017-07-18 03:00:34,514 [myid:] - INFO [main:Environment@100] - Client environment:java.class.path=/usr/local/zookeeper/bin/../build/classes:/usr/local/zookeeper/bin/../build/lib/*.jar:/usr/local/zookeeper/bin/../lib/slf4j-log4j12-1.6.1.jar:/usr/local/zookeeper/bin/../lib/slf4j-api-1.6.1.jar:/usr/local/zookeeper/bin/../lib/netty-3.7.0.Final.jar:/usr/local/zookeeper/bin/../lib/log4j-1.2.16.jar:/usr/local/zookeeper/bin/../lib/jline-0.9.94.jar:/usr/local/zookeeper/bin/../zookeeper-3.4.6.jar:/usr/local/zookeeper/bin/../src/java/lib/*.jar:/usr/local/zookeeper/bin/../conf:2017-07-18 03:00:34,514 [myid:] - INFO [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib2017-07-18 03:00:34,515 [myid:] - INFO [main:Environment@100] - Client environment:java.io.tmpdir=/tmp2017-07-18 03:00:34,515 [myid:] - INFO [main:Environment@100] - Client environment:java.compiler=<NA>2017-07-18 03:00:34,516 [myid:] - INFO [main:Environment@100] - Client environment:os.name=Linux2017-07-18 03:00:34,516 [myid:] - INFO [main:Environment@100] - Client environment:os.arch=amd642017-07-18 03:00:34,517 [myid:] - INFO [main:Environment@100] - Client environment:os.version=2.6.32-696.el6.x86_642017-07-18 03:00:34,517 [myid:] - INFO [main:Environment@100] - Client environment:user.name=root2017-07-18 03:00:34,517 [myid:] - INFO [main:Environment@100] - Client environment:user.home=/root2017-07-18 03:00:34,517 [myid:] - INFO [main:Environment@100] - Client environment:user.dir=/root2017-07-18 03:00:34,521 [myid:] - INFO [main:ZooKeeper@438] - Initiating client connection, connectString=master:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@531d72caWelcome to ZooKeeper!2017-07-18 03:00:34,572 [myid:] - INFO [main-SendThread(master:2181):ClientCnxn$SendThread@975] - Opening socket connection to server master/192.168.1.151:2181. Will not attempt to authenticate using SASL (unknown error)JLine support is enabled2017-07-18 03:00:34,770 [myid:] - INFO [main-SendThread(master:2181):ClientCnxn$SendThread@852] - Socket connection established to master/192.168.1.151:2181, initiating session[zk: master:2181(CONNECTING) 0] 2017-07-18 03:00:34,856 [myid:] - INFO [main-SendThread(master:2181):ClientCnxn$SendThread@1235] - Session establishment complete on server master/192.168.1.151:2181, sessionid = 0x5d51e6be550002, negotiated timeout = 30000WATCHER::WatchedEvent state:SyncConnected type:None path:null
连接成功之后,系统会输出Zookeeper的相关环境及配置信息,并在屏幕输出“welcome to Zookeeper!”等信息。输入help之后,屏幕会输出可用的Zookeeper命令
[zk: master:2181(CONNECTED) 3] helpZooKeeper -server host:port cmd argsstat path [watch]set path data [version]ls path [watch]delquota [-n|-b] pathls2 path [watch]setAcl path aclsetquota -n|-b val pathhistory redo cmdnoprintwatches on|offdelete path [version]sync pathlistquota pathrmr pathget path [watch]create [-s] [-e] path data acladdauth scheme authquit getAcl pathclose connect host:port
- 使用Zookeeper命令的简单操作步骤
(1) 使用ls命令查看当前Zookeeper中所包含的内容:ls /
[zk: master:2181(CONNECTED) 4] ls /[zookeeper, hbase][zk: master:2181(CONNECTED) 5]
(2) 创建一个新的Znode节点”zk”,以及和它相关字符,执行命令:create /zk myData
[zk: master:2181(CONNECTED) 5] create /zk myDataCreated /zk
(3) 使用ls命令来查看现在Zookeeper的中所包含的内容:ls /
[zk: master:2181(CONNECTED) 0] ls /[zk, zookeeper, hbase]
(4) 使用get命令来确认所创建的Znode是否包含创建的字符串,执行命令:get /zk
[zk: master:2181(CONNECTED) 1] get /zkmyDatacZxid = 0x100000055ctime = Tue Jul 18 03:16:47 CST 2017mZxid = 0x100000055mtime = Tue Jul 18 03:16:47 CST 2017pZxid = 0x100000055cversion = 0dataVersion = 0aclVersion = 0ephemeralOwner = 0x0dataLength = 6numChildren = 0
(5) 通过set命令来对zk所关联的字符串进行设置,执行命令:set /zk hello
[zk: master:2181(CONNECTED) 2] set /zk hellocZxid = 0x100000055ctime = Tue Jul 18 03:16:47 CST 2017mZxid = 0x100000058mtime = Tue Jul 18 03:19:33 CST 2017pZxid = 0x100000055cversion = 0dataVersion = 1aclVersion = 0ephemeralOwner = 0x0dataLength = 5numChildren = 0
(6) 使用get命令来查看,上次修改的内容,执行命令:get /zk
[zk: master:2181(CONNECTED) 3] get /zkhellocZxid = 0x100000055ctime = Tue Jul 18 03:16:47 CST 2017mZxid = 0x100000058mtime = Tue Jul 18 03:19:33 CST 2017pZxid = 0x100000055cversion = 0dataVersion = 1aclVersion = 0ephemeralOwner = 0x0dataLength = 5numChildren = 0
(7) 将刚才创建的Znode删除,执行命令:delete /zk
(8) 最后再次使用ls命令查看Zookeeper中的内容,执行命令:ls /
[zk: master:2181(CONNECTED) 5] ls /[zookeeper, hbase]
Zookeeper的api的简单使用
- ZookeeperAPI简介
- 所用jar包 zookeeper-3.4.6.jar,jline-0.9.94.jar,log4j-1.2.16.jar,netty-3.7.0.Final.jar,slf4j-api-1.6.1.jar,slf4j-log4j12-1.6.1.jar
Zookeeper API共包含五个包,分别为:
(1)org.apache.zookeeper (2)org.apache.zookeeper.data (3)org.apache.zookeeper.server (4)org.apache.zookeeper.server.quorum (5)org.apache.zookeeper.server.upgrade
其中org.apache.zookeeper,包含Zookeeper类,他是编程时最常用的类文件。这个类是Zookeeper客户端的主要类文件。如果要使用Zookeeper服务,应用程序首先必须创建一个Zookeeper实例,这时就需要使用此类。一旦客户端和Zookeeper服务建立起了连接,Zookeeper系统将会给次连接会话分配一个ID值,并且客户端将会周期性的向服务器端发送心跳来维持会话连接。只要连接有效,客户端就可以使用Zookeeper API来做相应处理了。
Zookeeper类提供了如下图所示的几类主要方法
- Zookeeper API的使用
简单状态查询,stat对象为放回状态对象
public static void main(String[] args) throws IOException, KeeperException, InterruptedException { String connectString = "master:2181,slave1:2181,slave2:2181"; /** * 异步完成 * connectString 连接串 * sessionTimeout 超时时间 * watcher 不检查null */ ZooKeeper zk = new ZooKeeper(connectString, 2000, null); Stat stat = new Stat(); zk.getData("/", null, stat); }
创建路径
//创建路径 @Test public void createPath() throws Exception{ ZooKeeper zk = new ZooKeeper(connectString, 2000, null); String path ="/hello"; String data = "hello_data"; //Ids访问控制列表 控制权限 String retPath=zk.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); System.out.println(retPath); }
删除路径
//删除路径 @Test public void deletePath() throws Exception{ ZooKeeper zk = new ZooKeeper(connectString, 2000, null); String path ="/hello"; //version要删除的版本号dataVersion,数据版本 zk.delete(path, 0); }
设置数据
// 设置数据 添加子节点只需向path路径下添加路径 @Test public void setData() throws Exception { ZooKeeper zk = new ZooKeeper(connectString, 2000, null); String path = "/hello/hello_data"; Stat stat = zk.setData(path, "t1".getBytes(), 0); System.out.println(stat.getVersion()); }
获取子节点
@Test public void getChildren() throws Exception { ZooKeeper zk = new ZooKeeper(connectString, 2000, null); List<String> list = zk.getChildren("/", null); for (String string : list) { System.out.println(string); } }
观察者
// 观察者 zk发生变化时触发 @Test public void testWatcher() throws Exception { // 内部类 // zk事件激活是一次性触发 Watcher w = new Watcher() { @Override public void process(WatchedEvent event) { // TODO Auto-generated method stub System.out.println("有事情发生" + event.getType()); } }; ZooKeeper zk = new ZooKeeper(connectString, 2000, w); String path = "/hello"; zk.getData(path, w, null); zk.setData(path, "t2".getBytes(), 1); while (true) { Thread.sleep(5000); } }
ZooKeeper示例
假设一组服务器,用于为客户端提供一些服务。我们希望每个客户端都能够能够找到其中一台服务器,使其能够使用这些服务,挑战之一就是维护这组服务器列表。这组服务器的成员列表明显不能存在网络中的单个节点上,因为如果那个节点发生故障,就意味着是整个系统的故障(我们希望这个列表有很高的可用性)。假设我们有了一个可靠的方法解决了这个成员列表的存储问题。如果其中一台服务器出现故障,我们仍然需要解决如何从服务器成员列表中将它删除的问题。某个进程需要负责删除故障服务器,但注意不能由故障服务器自己来完成,因为故障服务器已经不再运行。
我们所描述的不是一个被动的分布式数据结构,而是一个主动的、能够在某个外部事件发生时修改数据项状态的数据结构。ZooKeeper提供这种服务,所以让我们看看如何使用它来实现这种众所周知的组成员管理应用。
ZooKeeper中的组成员关系
理解ZooKeeper的一种方法就是将其看作一个具有高可用性的文件系统。但这个文件系统中没有文件和目录,而是统一使用“节点”(node)的概念,称为znode。znode既可以作为保存数据的容器(如同文件),也可以作为保存其他znode的容器(如同目录)。所有的znode构成一个层次化的命名空间。一种自然的建立组成员列表的方式就是利用这种层次结构,创建一个以组名为节点名的znode作为父节点,然后以组成员名(服务器名)为节点名来创建作为子节点的znode。如下图给出了一组具有层次结构的znode。
创建组
//为组名为/zoo的组创建一个znodepublic class CreateGroup implements Watcher {private static final String connectString = "master:2181";private static final String groupName = "zoo";private static final int SESSION_TIMEOUT = 5000;private ZooKeeper zk;// 使用Java的CountDownLatch类来阻止使用新建的ZooKeeper对象,直到这个ZooKeeper对象已经准备就绪private CountDownLatch connectedSignal = new CountDownLatch(1);/** * 客户端已经与ZooKeeper建立连接后,Watcher的process()方法会被调用 参数是一个表示该连接的事件 * SyncConnected连接事件 */@Overridepublic void process(WatchedEvent event) { // TODO Auto-generated method stub if (event.getState() == KeeperState.SyncConnected) { /** * 调用CountDownLatch的countDown()方法来递减它的计数器 * 锁存器(latch)被创建时带有一个值为1的计数器,用于表示在它释放所有等待线程之前需要发生的事件数。 * 在调用一欢countDown()方法之后,计数器的值变为0,则await()方法返回 */ connectedSignal.countDown(); }}public static void main(String[] args) throws IOException, InterruptedException, KeeperException { /** * connect方法实例化了一个新的ZooKeeper类的对象,这个类是客户端API中的主要类, * 并且负责维护客户端和ZooKeeper服务之间的连接 * */ CreateGroup createGroup = new CreateGroup(); createGroup.connect(connectString); createGroup.create(groupName); createGroup.close();}private void close() throws InterruptedException { zk.close();}private void create(String groupName) throws KeeperException, InterruptedException { String path = "/" + groupName; if (zk.exists(path, false) == null) { /** * 使用ZooKeeper实例中的create()方法来创建一个新的ZooKeeper的znode 路径:用字符串表示。 * znode的内容:字节数组,本例中使用空值。 * 访问控制列表:简称ACL,本例中使用了完全开放的ACL,允许任何客户端对znode进行读写。 * 创建znode的类型:有两种类型的znode:短暂的和持久的。 PERSISTENT为持久 */ zk.create(path, null/* data */, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } System.out.println("Created:" + path);}private void connect(String hosts) throws IOException, InterruptedException { /** * ZooKeeper类的构造函数有三个参数 第一个是:ZooKeeper服务的主机地址,可指定端口,默认端口是2181。 * 第二个是:以毫秒为单位的会话超时参数,这里我们设成5秒。 第三个是:参数是一个Watcher对象的实例。 * Watcher对象接收来自于ZooKeeper的回调,以获得各种事件的通知 * CreateGroup是一个Watcher对象,因此我们将它传递给ZooKeeper的构造函数 */ zk = new ZooKeeper(hosts, SESSION_TIMEOUT, this); connectedSignal.await();}}
ConnectionWatcher基类
public class ConnectionWatcher implements Watcher {private static final int SESSION_TIMEOUT = 5000;protected ZooKeeper zk;CountDownLatch connectedSignal = new CountDownLatch(1);public void connect(String host) throws IOException, InterruptedException { zk = new ZooKeeper(host, SESSION_TIMEOUT, this); connectedSignal.await();}@Overridepublic void process(WatchedEvent event) { // TODO Auto-generated method stub if (event.getState() == KeeperState.SyncConnected) { connectedSignal.countDown(); }}public void close() throws InterruptedException { zk.close();}}
加入组
public class JoinGroup extends ConnectionWatcher {public void join(String groupName, String memberName) throws KeeperException, InterruptedException { String path = "/" + groupName + "/" + memberName; /** * EPHEMERAL为短暂 * 创建短暂znode,作为组znode的子节点,然后通过休眠来模拟正在做某种工作,直到该进程被强行终止 * 随着进程终止,这个短暂znode被ZooKeeper删除 */ String createdPath = zk.create(path, null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); System.out.println("Created:" + createdPath);}private static final String connectString = "master:2181";private static final String groupName = "zoo";//private static final String memberName = "duck";//private static final String memberName = "cow";private static final String memberName = "goat";public static void main(String[] args) throws InterruptedException, IOException, KeeperException { JoinGroup joinGroup = new JoinGroup(); joinGroup.connect(connectString); joinGroup.join(groupName, memberName); // stay alive until process is killed or thread is interrupted Thread.sleep(Long.MAX_VALUE);}}
显示成员列表
public class ListGroup extends ConnectionWatcher {public void list(String groupNmae) throws KeeperException, InterruptedException { String path = "/" + groupNmae; try { /** * 调用了getChildren()方法来检索并打印输出一个znode的子节点列表 * 用参数为:该znode的路径和设为false的观察标志 */ List<String> children = zk.getChildren(path, false); if (children.isEmpty()) { System.out.printf("No memebers in group %s\n", groupNmae); System.exit(1); } for (String child : children) { System.out.println(child); } } catch (KeeperException.NoNodeException e) { System.out.printf("Group %s does not exist \n", groupNmae); System.exit(1); }}private static final String connectString = "master:2181";private static final String groupName = "zoo";public static void main(String[] args) throws IOException, InterruptedException, KeeperException { ListGroup listGroup = new ListGroup(); listGroup.connect(connectString); listGroup.list(groupName); listGroup.close();}}
删除组
public class DeleteGroup extends ConnectionWatcher {private static final String connectString = "master:2181";private static final String groupName = "zoo";public void delete(String groupName) throws InterruptedException, KeeperException { String path = "/" + groupName; List<String> children; try { children = zk.getChildren(path, false); for (String child : children) { zk.delete(path + "/" + child, -1); } zk.delete(path, -1); } catch (KeeperException.NoNodeException e) { System.out.printf("Group %s does not exist\n", groupName); System.exit(1); }}public static void main(String[] args) throws InterruptedException, IOException, KeeperException { DeleteGroup deleteGroup = new DeleteGroup(); deleteGroup.connect(connectString); deleteGroup.delete(groupName); deleteGroup.close();}}
- zookeeper+hadoop+hbase 之 zookeeper
- zookeeper+hadoop+hbase 之 hadoop
- hadoop学习之ZooKeeper
- 7-hadoop之zookeeper
- Hadoop之Zookeeper
- hadoop之zookeeper
- Hadoop之Zookeeper
- hadoop学习之ZooKeeper
- Hadoop之ZooKeeper
- zookeeper+hadoop+hbase 之 hbase
- Hadoop 基础知识---之Zookeeper篇
- hadoop之zookeeper集群搭建
- Hadoop系列五:Hadoop之Zookeeper篇
- hadoop学习之zookeeper(6):zookeeper的安装配置
- Hadoop学习之zookeeper(1)
- Hadoop学习之zookeeper(集群安装)
- Hadoop学习之zookeeper(2)
- Hadoop之关键技术(四)--Zookeeper
- SSO单点登录三种情况的实现方式详解
- 常用正则表达式大全
- WINDOWS核心编程——DLL基础和实操
- centos安装用yum的方式安装svn,并创建库
- SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
- Hadoop之Zookeeper
- IntentFilter的匹配规则
- 有关分组、帧、报文、比特流的问题
- 使用div调试出现界面乱掉的情况
- 进程之间通信和线程间通信
- Mininet的配置与使用(1)
- Spring MVC Restful风格
- Linux下获取文件大小的方法
- 909422229_Axis配合Eclipse发布接口