神级 zookeeper

zk的数据模型

一、ZNodes:

  1.  znode 可以被监测,客户端可以设置监控某个znode   
  2. .数据访问,节点上的数据可以读和写,读的时候会读出与该节点关联的所有数据的字节,写的时候会替换掉所有的数据,每个节点上都有访问控制节点来限制读和 写。zookeeper被设计不是用来左右数据库或者大数据存储的,她是用来管理这里有协作关系的数据,比如配置文件等,一般一个节点上的数据都在几千 K,不超过1M,因为大数据的存储会话费较多的时间。如果需要存储大数据,可以把数据存在大存储里,如NFS,HDFS等,然后把文件的位置存在zk里。
  3. 临时节点   临时节点的存活时间是和session的时间一样长的,如果session断开,临时节点就会被删除,也正是因为这个特性,临时节点不允许有子节点。
  4. 顺序节点  当你创建一个节点的时候,你可以请求zk给你追加一个单调递增的数字,这个数字在父节点中是唯一的。如<path>-2147483647
二、zookeeper中的时间      zookeeper里有多种时间记录
  1. zxid,zookeeper transaction id,只要zookeeper的状态发生改变就会收到新的zxid,它是全局唯一的一个标志。
  2. version number,只要zonde发生改变version number就会增加,有三中version number。1,version 表示znode的数据变化。2,cversion 表示znode children的变化。3,表示znode acl的变化。
  3. ticks
  4. real time,zookeeper不会使用真实时间(时钟时间),除非在创建或修改znode时把时间戳加到状态里面去。

三、zookeeper的状态

       每个znode的状态都有以下几个部分组成:

  1. czxid 创建zxid
  2. mzxid 修改zxid
  3. ctime 创建时间(毫秒)
  4. mtime 最后修改时间(毫秒)
  5. version 该节点数据变化
  6. cversion 该节点子节点变化
  7. aversion 该节点ACL变化
  8. ephemeralOwner 如果该节点是临时节点,表示临时节点拥有者的sessionid,如果不是临时节点为0
  9. datalength 该节点数据的长度
  10. numchildren 该节点子节点的数量

    zookeeper的session状态有CONNECTING 、CONNECTED 、CLOSED几个状态,客户端通过编程语言建立到zookeeper的连接,这时候的状态就是CONNECTING,客户端的库开始连上zookeeper的时候状态就是CONNECTED,如果由于主机不能访问、session超时或者客户端断开连接就是CLOSED状态

  1.    为了创建客户端的session,需要提供逗号分隔开的连接字符串,eg:127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002,客户端选择一个server连接,如果连接失败会尝试连接下一个sever,直到建立连接。
  2. 可选的"chroot"后缀也可以增加到连接字符串后面,(这个类似Linux的chroot命令,有什么用暂时不晓得)
  3. 当客户端得到一个服务处理器,说明他已经连接到了zookeeper上了,zookeeper创建一个64位的数字代表session,如果客户端连接到zookeeper的不同的server上,他会发送这个sessionid作为连接握手的一部分,作为一种安全措施,zookeeper 会创建与这个sessionid关联的密码。zookeeper在建立session的时候,密码和sessionid都会发送给客户端,当客户端重新建立和一个新的server的连接的时候就会发送这个sessionid和密码。
  4. zookeeper客户端库在创建session的时候有一个session超时的参数(毫秒),当前要求超时时间的最小值是ticktime的2倍,最大值是20倍。zookeeper客户端api允许协商超时
  5. session超时是由zookeeper集群来管理的,不是由客户端管理的,当zk客户端建立到集群的session时,会提供超时的值,集群会使用这个值来界定客户端session是否超时。当集群在超时时间内没有收到客户端的回复就认为是超时(没有心跳),一旦session超时,集群会删除这个session拥有的所有的临时节点,并立即通知所有监控这些节点的客户端。如果这个时候客户端仍然处于失联的状态,他不会收到超时的通知除非他重新建立了到集群的连接,一旦建立了tcp连接,客户端就会收到超时的通知。
  6. 还有一个和session建立相关的参数是观察者(watcher),当状态发生改变,客户端的watcher会受到通知。比如客户端失去连接,session超时等,在一个新session中他收到的第一个事件是session连接事件。
  7. 客户端发送请求会是session保持连接状态,如果session空闲的时间超过timeout的时间间隔,客户端就会发送ping请求来保持客户端的连接状态,同时让集群知道这个客户端还是活动的。ping的时间是相当保守的,这样可以确保客户端及时的监测到session的失联和session重建。
  8. SessionMovedException,session移动异常,这是一个通常客户端看不到的内部异常,这种异常发生在一个请求收到的session连接已经在其他的server上建立了。通常情况下一个客户端发送请求道服务端,但是由于网络延迟,客户端超时又重新连接到其他的server上,然后这个延迟的请求到达后,原来的server发现session已将移动到其他的server上去了于是会关闭客户端连接。客户端也通常不会看到错误消息,因为他不会从这个连接中读取数据。另外一种情况是两个客户端使用相同的sessionid和密码来连接,一个客户端建立的连接另外一个客户端就会失去连接,这时候就会看到这个异常。
  9. 更新server列表(待更新)
                zookeeper watchers       zk中所有的读取操作,getData(),getChildren(),exitsts()都有设置watch这么一个附件的作用,zk是这么来定义一个watch。当watch的数据发生改变,就会发送watch事件给设置了watch客户端,定义一个watch需要考虑三个方面:
  1. 一次性触发器,当数据发生改变时一个事件就会发送给客户端,比如:一个客户端getData("/znode1", true),稍后这个数据发生变化,客户端就会收到一个事件,但是如果数据再次发生改变就不会收到这个数据了。
  2. 待完成
  3. node 的改变包括数据的改变和子节点的改变,data watch用来监控数据的变化例如,getData(),exists方法都是这一类,getChildren方法属于子节点监控。setData方法会触发数据监控,create会触发数据监控和子节点监控。delete会触发数据监控和子节点监控。监控是在zk server上维护的。当一个客户端连接到zkserver上,任何的session事件都会触发这个监控,但当客户端和zkserver失联的时候监控就不会收到这个事件,当客户端重新连接,以前注册的监控会重新注册,如果需要还可以被触发。通常情况下这些都是透明的,有一种情况下监控可能会丢失:监控一个不存在的znode
  4. 监控的语义:下面的列表说明了zk有哪些事件,以及通过那些方法可以监听到这些事件。
  • create--exists
  • delete -- exists、getChildren、getData
  • change -- exists、getData
  • child -- getChildren
  1. 移除监听器,我们可以移除注册的监听器,即使zkclient没有连接到zkserver上去,在本地设置状态为true,如果一个node被成功的移除后,会触发两类事件,child事件,可以通过getChildren来监听和数据事件可以通过exists和getData来监听
  2. 监控器的注意事项:监控都是一次性的,如果你要想得到以后的事件,你必须设置一个新的监听器。其次由于监控是一次性的,很有可能在得到事件和设置新的监听器中间这段时间数据改变了多次。一个监控器对于一个给定的事件只能触发一次,比如一个监听器监听了exists和getData两个调用,然后这个节点被删除了,那么这个监听器只能被触发一次代表这个删除事件。
  3. 当你和zkserver失联的时候,你不会收到事件,除非你又重新建立连接。使用session事件可以进入到安全模式。
                    zookeeper的访问控制 ACL           zk使用ACL来管理zk节点的访问,这种访问很像unix的文件系统权限访问,他也使用权限位来标志是允许还是不允许访问,但是zk没有 owner group other的限制,zk没有节点owner的概念。ACL指定了id和权限的集合,值得注意的是,zk不是递归的,比如说 /app 只允许172.10.1.1访问,但是/app/status可以允许所有人来访问,zk的权限只是和某个特定的节点相关联,不具有递归的概念。zk支持schema:id的这种模式,比如ip:172.1.1.1。当客户端连接到zkserver上的时候并进行授权验证,zk会关联和这个客户端关联的所有id。当客户端去访问某个节点的时候这些id会被检查,ACL是由这种形式组成的:ip:173.45.0.0/16,READ,表示所有ip以173.15开头的ip访问都有读的权限。                                      zk支持下面几种权限:
  1. CREATE,可以新建子节点
  2. READ,可以读取数据和获取子节点列表
  3. WRITE,可以设置节点的数据
  4. DELETE,可以删除子节点
  5. ADMIN,可以设置权限
              zookeeper内建的几种schema:
  • world,只有一个id,代表任何人
  • auth,不使用id,代表授权的人
  • digest,使用username:password生成MD5哈希值,来作为ACL ID,通过发送username:password来验证
  • ip,使用客户端的ip来作为ACL ID
                     可插入式zookeeper认证框架 zookeeper运行在不同的环境上有不同的认证schema,因此他有完整的可插入式认证框架。就连自带的哪几种认证schema都是构建在这个框架上面的。为了理解这个框架的工作原理,你必须要理解2大认证操作,第一是认证客户端,这通常在客户端连接到server上就会认证。第二是查询ACL实体,ACL实体是<ids,permission>对,ids是一个简单的基于连接字符串或者是一个表达式用来计算这个信息,这取决与插件的实现,一个认证插件必须要实现AuthenticationProvider接口,这个接口的方法如下:
  1. getSchema,返回一个标志这个插件的字符串,由于支持多种认证方法,ids往往以schema开头,zkserver会使用插件返回的schema来决定使用哪种schema。
  2. handleAuthention ,当客户端发送认证消息的时候会被调用,客户端会提供schema,zkserver会把这些信息传递给认证插件,如果认证通过那么会把这些信息和连接关联,cnxn.getAuthInfo().add(new Id(getScheme(), data)),如果认证失败,那么会返回一个错误。
  3. 认证插件和ACL的设置和使用都有关系,当为一个znode设置了一个ACL,那么zkserver会把id传到isvalid方法里看看这是不是一个合法的id。
内置的认证插件有ip和digest,可以使用系统属性来指定插件例如 authProvider.1=com.f.MyAuth
authProvider.2=com.f.MyAuth2 要注意这里的 .1 .2都是唯一的                                          一致性保证 zkserver提供高性能,易扩展的服务,无论是读还是写,zkserver都设计的很快,通常读比写要更快,正式由于读很快,zkserver可以服务旧数据,这都归功于zkserver提供的一致性保证。
  1. 顺序的一致性,客户端发来的请求会按照先来后到的顺序进行更新
  2. 原子性,更新成功或者失败,没有中间状态
  3. 单一系统视图,无论你连接的是哪一个server都会看到一致的视图
  4. 可靠性,
       

猜你喜欢

转载自pengfeituzi2010.iteye.com/blog/2148525
今日推荐