ZooKeeper的简介与操作ZooKeeper简介从前面的原理章节中,我们知道分布式程序需要一定的协同功能,以便能够在多个运行的进程之间建立联系•其中一个重要的协同功能就是进行分布式锁,这样就可以在多个应用程序进行共享资源访问的时候起到保护作用ZooKeeper就是一个为分布式应用程序进行协调的服务,这样的话,每一个分布式的应用程序如果需要进行协调的话就可以直接使用ZooKeeper所提供的服务ZooKeeper提供了一系列分布式系统的基本服务或者可以基于ZooKeeper完成分布式系统的基本服务:同步、配置管理、分组和命名ZooKeeper提供了一个易于编程的环境,实现了一个简化的文件系统,提供类似的目录树结构ZooKeeper使用Java编写,支持了Java以及C语言绑定分布式的协调服务coordination非常容易出错,出错之后也很难恢复,例如死锁状态,或者出现资源竞争状态,通过ZooKeeper可以以良好的编程接口将程序员从自己构造协调服务的负担中解放出来ZooKeeper的特性结构简单•ZooKeeper提供了文件系统的树状结构数据备份•数据一致性,快照+WAL(writeaheadlog)有序性•有序的事务编号zxid高效性•所有的server都提供读服务安装过程概述下载并将zookeeper解压缩到任意一个目录修改conf目录下的zoo_sample.cfg为zoo.cfg修改配置参数启动ZooKeeperZooKeeper程序的启动在完成配置之后1,将ZooKeeper拷贝到多个需要执行的对应节点2,注意需要在每个运行的节点中的数据存储目录中创建一个myid文件,在其中写入一个id号分别在多个节点中启动运行多个ZooKeeper服务器的实例ZooKeeper启动完成ZooKeeper的四字命令如同前面一页看到的命令ruok一样,ZooKeeper支持一系列的四个字母的命令,可以询问ZooKeeper的运行状态,用nc工具就可以打印状态,或者如同前一页一样使用telnet工具用echo命令可以直接将命令行输入给nc(尚未试验成功)ZooKeeper四字命令举例ZooKeeper四字命令功能描述conf输出相关服务配置的详细信息。cons列出所有连接到服务器的客户端的完全的连接/会话的详细信息。包括“接受/发送”的包数量、会话id、操作延迟、最后的操作执行等等信息。dump列出未经处理的会话和临时节点。envi输出关于服务环境的详细信息(区别于conf命令)。reqs列出未经处理的请求ruok测试服务是否处于正确状态。如果确实如此,那么服务返回“imok”,否则不做任何相应。stat输出关于性能和连接的客户端的列表。wchs列出服务器watch的详细信息。wchc通过session列出服务器watch的详细信息,它的输出是一个与watch相关的会话的列表。wchp通过路径列出服务器watch的详细信息。它输出一个与session相关的路径。ZooKeeper的命令行工具ZooKeeper命令行工具zkCli.sh–servermaster2181Help命令可以列出支持的命令ZooKeeper的命令操作1使用ls命令来查看当前ZooKeeper中所包含的内容ZooKeeper的操作命令2创建一个新的znode,使用create/mydataIntelData。这个命令创建了一个新的znode节点“mydata”以及与它关联的字符串IntelData。运行get命令获得数据ZooKeeper的命令操作3通过set命令来对mydata所关联的字符串进行设置ZooKeeper的命令操作4删除命令ZooKeeper的编程接口ZooKeeperAPI包含5个包:org.apache.zookeeper,org.apache.zookeeper.data,org.apache.zookeeper.server,org.apache.zookeeper.server.quorum和org.apache.zookeeper.server.upgrade。其中org.apache.zookeeper包含ZooKeeper类是编程时最常用的类文件为了使用ZooKeeper服务,应用程序首先创建一个Zookeeper实例,与ZooKeeper服务建立起连接,ZooKeeper系统将会分配给此连接回话一个ID值,客户端会周期地向服务器发送心跳来维持会话的连接,并调用ZooKeeperAPI来做相应的处理与命令行提供的功能类似,API也提供类似的功能功能描述create在本地目录树中创建一个节点delete删除一个节点exists测试本地是否存在目标节点get/setdata从目标节点上读取/写数据get/setACL获取/设置目标节点访问控制列表信息getchildren检索一个子节点上的列表sync等待要被传送的数据ZooKeeper的客户端工作1与ZooKeeper服务端进行通信,包括:连接,发送消息,接受消息。2发送心跳信息,保持与ZooKeeper服务端的有效连接与Session的有效性。3错误处理,如果客户端当前连接的ZooKeeper服务端失效,自动切换到另一台有效的ZooKeeper服务端。4管理Watcher,处理异常调用和Watcher。ZooKeeper代码举例1ZooKeeper代码举例2ZooKeeper示例代码的执行结果ZNodeZooKeeper树中的节点称作znode。znode会维护一个包含数据修改和ACL修改版本号的Stat结构体,这个结构体还包含时间戳字段。版本号和时间戳让ZooKeeper可以校验缓存,协调更新。每次修改znode数据的时候,版本号会增加。客户端获取数据的同时,也会取得数据的版本号。执行更新或者删除操作时,客户端必须提供版本号。如果提供的版本号与数据的实际版本不匹配,则更新操作失败。Znode上的观察器客户端可以在znode上设置观察器。对znode的修改将触发观察器,然后移除观察器。观察器被触发时,ZooKeeper向客户端发送一个通知。观察器用来让应用程序可以得到异步的通知ZooKeeper的Stat结构体czxid:创建节点的事务的zxidmzxid:对znode最近修改的zxidctime:毫秒数表示的znode创建时间(自从创建开始)mtime:毫秒数表示的znode最近修改时间(自从修改开始)version:znode数据的修改次数cversion:znode子节点修改次数aversion:znode的ACL修改次数ephemeralOwner:如果znode是临时节点,则指示节点所有者的会话ID;如果不是临时节点,则为零。dataLength:znode数据长度。numChildren:znode子节点个数。会话过期的处理会话过期由ZooKeeper集群,而不是客户端来管理。客户端与集群建立会话时会提供上面讨论的超时值。集群使用这个值来确定客户端会话何时过期。集群在指定的超时时间内没有得到客户端的消息时发生会话过期。会话过期时集群将删除会话的所有临时节点,立即通知所有(观察器节点的)客户端。此时已过期会话的客户端还是同集群断开连接的,不会被通知会话已经过期,直到(除非)客户端重新建立到集群的连接,这时候已过期会话的观察器才会收到“会话已过期”通知。ZooKeeper的观察器Watches观察器是ZooKeeper中一个非常重要的概念,实际是一个观察器,ZooKeeper中的所有读操作:getData()、getChildren()和exists(),都有一个设置观察器作为进行触发的选项。ZooKeeper对观察器的定义是:观察器事件是在被观察器数据发生变化时,发送给建立观察器的客户端的一次性观察器。•一次触发:触发一次之后,观察器会被删除•发送给客户端:观察器事件是异步地发送给观察器者(客户端)的。ZooKeeper会保证顺序:在收到观察器事件之前,客户端不会看到已经为之设置观察器的节点的改动。网络延迟或者其他因素可能会让不同的客户端在不同的时间收到观察器事件和更新操作的返回码。但是不同客户端看到的事情都有一致的顺序。ZooKeeper关于观察器Watches的保证观察器与其他事件、其他观察器和异步回应是顺序的。ZooKeeper客户端库保证一切都是按顺序分发的。客户端将在看到znode的新数据之前收到其观察器事件。观察器事件的次序与ZooKeeper服务看到的更新次序一致。ZooKeeper中的权限ZooKeeper使用ACL控制对节点的访问,ACL指定一个ID集合,以及与这些ID相关联的权限。ACL仅仅用于某特定节点,ACL不会应用到子节点。比如说,/app只能被ip:172.16.16.1读取,/app/status可以被所有用户读取。ACL不是递归的。ZooKeeper支持下述权限:•CREATE:可创建子节点•READ:可获取节点数据和子节点列表•WRITE:可设置节点数据•DELETE:可删除子节点•ADMIN:可设置节点权限节点的权限设置(创建节点)ListACLacls=newArrayListACL(2);Idid1=newId(digest,DigestAuthenticationProvider.generateDigest(admin:admin123));ACLacl1=newACL(ZooDefs.Perms.ALL,id1);Idid2=newId(digest,DigestAuthenticationProvider.generateDigest(guest:guest123));ACLacl2=newACL(ZooDefs.Perms.READ,id2);acls.add(acl1);acls.add(acl2);ZooKeeperzk=newZooKeeper(127.0.0.1:2181,10000,newDefaultWatcher());zk.create(/test,newbyte[0],acls,CreateMode.PERSISTENT);ZooKeeper的一致性保证1Zookeeper是一种高性能、可扩展的服务。Zookeeper的读写速度非常快,并且读的速度要比写的速度更快在进行读操作的时候,ZooKeeper依然能够为旧的数据提供服务。这些都是由于ZooKeepe所提供的一致性保证•顺序一致性:客户端的更新顺序与它们被发送的顺序一致•原子性:更新操作要么成功,要么失败,没有第三种结果•单系统镜像:无论客户端连接到哪一个客户端,客户端将看到相同的ZooKeeper视图ZooKeeper一致性保证2可靠性:一旦一个更新操作被应用,那么在客户端再次更新它之前,它的值将不会改变1.如果客户端成功地获得了正确的返回代码,那么说明更新已经成果。如果不能够获得返回代码(由于通信错误、超时等等),那么客户端将不知道更新操作是否生效。2.当从故障恢复的时候,任何客户端能够看到的执行成功的更新操作将不会被回滚。实时性:在特定的一段时间内,客户端看到的系统需要被保证是实时的(在十几秒的时间里)。在此时间段内,任何系统的改变将被客户端看到,或者被客户端侦测到。