Zookeeper主要用在分布式应用中实现一致性协调调度服务。它的命名空间相似传统文件系统,每一个节点都以惟一的路径进行标识,不一样的是,每一个节点除了能够拥有子节点外,还可拥有相对性的data数据。node
1、Zookeeper命名空间数据库
上图是一个典型的Zookeeper命名空间结构,经过路径"/app1/p_1"可访问znode1节点,每一个节点可存储少许数据,如状态、配置、位置信息等等,且data信息量很小,通常在byte到KB级别。节点znode维护一个状态stat结构(包括数据变化的版本号、ACL变化、时间戳),以容许缓存验证与协调更新。每当节点数据内容改变时,多一个版本号,相似HBase。客户端获取数据的同时也获取相对应的版本号。节点数据内容以原子方式读写,读操做会读取该znode的所有data数据,一样写操做也会覆盖该znode的所有data数据,不存在部分读写的状况。同时,每一个节点有一个访问控制列表ACL(Access Control List)来约束访问操做,即具备权限控制。缓存
znode存在两种:session
常规的znode: 由用户显式建立和删除app
ephemeral znode:临时型znode, 其生命周期伴随于建立它的session, session结束后,ZooKeeper Server会自动删除它,固然用户也能够显式的删除框架
2、Zookeeper的Watches异步
Zookeeper对Node的增删改查均可触发监听,每一个client可对一个znode设置一个watch事件。当watch监视的数据发生变化时,会通知设置了该watch的client,即watcher。watch事件是一次性触发器,即触发一次就会被取消,该client若是还要监视该znode的变化,须要再次设置相应的watch事件。分布式
注:ide
watch事件异步发送至观察者,可能致使当两次触发时间间隔过短的时候,不一样的接收者收到的事件不一致3d
watch是一次性触发的且在获取watch事件和设置watch事件之间有延迟,因此不能可靠的观察到节点的每一次变化
客户端监视一个节点,老是先获取watch事件,再发现节点的数据变化。
watch事件的顺序对应于zookeeper服务所见的数据更新顺序
3、Zookeeper读写流程
读请求到来时,将直接从replicated database获取数据,replicated database是一个内存数据库,所以读写效率高
写请求到来时,全部的写请求都会先发送给一个称之为leader的server,而后由该leader广播给各个follower(server),在收到超过一半的server反馈的ack以后,认为这次写操做成功。同时,再写操做更新到内存数据库以前,会先持久化到磁盘,用于恢复。以下图所示:
4、在dubbo中的应用
在分布式系统中,经过使用命名服务,客户端应用可以根据指定名字来获取资源或服务的地址,提供者等信息。被命名的实体一般能够是集群中的机器,提供的服务地址,远程对象等等——这些咱们均可以统称他们为名字(Name)。其中较为常见的就是一些分布式服务框架中的服务地址列表。经过调用ZK提供的建立节点的API,可以很容易建立一个全局惟一的path,这个path就能够做为一个名称。好比dubbo应用中:
服务提供者在启动的时候,向ZK上的指定节点/dubbo/${serviceName}/providers目录下写入本身的URL地址,这个操做就完成了服务的发布。
服务消费者启动的时候,订阅/dubbo/${serviceName}/providers目录下的提供者URL地址, 并向/dubbo/${serviceName} /consumers目录下写入本身的URL地址。
注意,全部向ZK上注册的地址都是临时节点,这样就可以保证服务提供者和消费者可以自动感应资源的变化。
另外,Dubbo还有针对服务粒度的监控,方法是订阅/dubbo/${serviceName}目录下全部提供者和消费者的信息。