Zookeeper 概览
zookeeper的适用场景
zookeeper是一个分布式的协同系统,在分布式环境下,不同运行实例之间的协同是一个必须要考虑的问题,例如在单机模式下的锁用synchronized关键字或信号量就可以解决,但在分布式环境下就需要借助应用程序以外的存储来实现(如数据库或redis)。分布式协同还需考虑性能、一致性、高可用,在分布式锁这个场景中还需要提供通用的同步原语能力。
zookeeper就提供了这样一个机制,简化了分布式协同的开发。
zookeeper适用于存储一些协同数据,或元数据,不适合做海量数据存储。在CAP理论中,zookeeper属于CP类系统,对数据有强一致性保证,在可用性上相对较弱(主要体现在选主时不可用)。另外,为保证一致性,zookeeper在数据更新操作上使用类似两阶段提交技术,有一定的性能损耗,不适合做高并发操作。
zookeeper的节点类型
zookeeper上存储的数据是一个树状结构,有点类似于目录树,每一个目录都称作一个节点,也称为znode,znode通常可以表示为一个路径,例如/path,znode上可以包含数据(字节数组),也可以不包含数据,数据的序列化和反序列化由应用实现。
znode有以下几种类型:
持久(persistent)节点。只能通过delete来删除
临时(ephemeral)节点。当创建该节点的客户端崩溃或关闭了连接时,节点会被删除。也可以主动调用delete删除
无序节点。
有序(sequential)节点。在创建有序znode时,会在路径之后追加一个单调递增的整数。
以上节点类型可以两两组合,一共有4种类型。
提示
由于临时节点在创建者会话过期时会被删除,因此临时节点不可以有子节点
基本操作
- 创建节点:create /path "data"
- 创建临时节点:create -e /path "data"
- 查看当前节点内容:get /path
- 查看子节点:ls /path
- ls2 /path = ls + get
- 修改节点内容:set /path "data"
- 删除节点:delete /path
zxid
每一个可能会改变zookeeper状态的请求,例如create、delete、set等都会被转发给leader来执行,并生成新的状态,这个过程在一个事务内,zookeeper为每一个事务分配了一个zxid。zxid保证了整个zookeeper集群对事务处理的有序性和一致性,也用于选举过程。
zxid是一个64bit的整数,又分为32bit的两个部分:epoch和counter。
zxid具有以下特性:
- zookeeper的状态每变更一次(创建、删除节点、更新节点数据),zxid都会变更
- zxid是递增的,如果zxid1 < zxid2,那么zxid1一定先于zxid2发生
- epoch表示leader的关系是否改变,每次一个新的leader被选出,都会有一个新的epoch
zookeeper Server的状态
- LOOKING
- LEADING
- FOLLOWING
- OBSERVING
其中前三种状态在选举过程中用到,而OBSERVING状态表示服务器是一个观察者,观察者不参与投票,但可以接收leader的proposal,观察者可以看做是一个只读的zookeeper服务器。