ZooKeeper基础知识

    ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现。它提供了简单原始的功能,分布式应用可以基于它实现更高级的服务,比如分布式同步,配置管理,集群管理,命名管理,队列管理。它被设计为易于编程,使用文件系统目录树作为数据模型。服务端跑在java上,提供java和C的客户端API

    众所周知,协调服务非常容易出错,但是却很难恢复正常,例如,协调服务很容易处于竞态以至于出现死锁。我们设计ZooKeeper的目的是为了减轻分布式应用程序所承担的协调任务

    ZooKeeper是集群的管理者,监视着集群中各节点的状态,根据节点提交的反馈进行下一步合理的操作。最终,将简单易用的接口和功能稳定,性能高效的系统提供给用户。

 

  • ZooKeeper提供了什么

    1、文件系统

    ZooKeeper的命名空间就是ZooKeeper应用的文件系统,它和Linux的文件系统很像,也是树状,这样就可以确定每个路径都是唯一的,对于命名空间的操作必须都是绝对路径操作。与linux文件系统不同的是,linux文件系统有目录和文件的区别,而ZooKeeper统一叫做znode,一个znode节点可以包含子znode,同时也可以包含数据。

    所以总结说来,znode即是文件夹又是文件的概念,所以在ZooKeeper这里面就不叫文件也不叫文件夹,叫znode,每个znode有唯一的路径标识,既能存储数据,也能创建子znode。但是znode只适合存储非常小量的数据,不能超过1M,最好小于1k。

下面是关于Znode的介绍(非常重要):

1、Znode有两个类型:

        短暂(ephemeral)(断开连接自己删除)

        持久(persistent)(断开连接不删除)

2、Znode有四种形式的目录节点(默认是persistent)

 

PERSISTENT持久化znode节点,一旦创建这个znode点存储的数据不会主动消失,除非是客户端主动的delete
PERSISTENT_SEQUENTIAL自动增加顺序编号的znode节点,比如ClientA去zk service上建立一个znode名字叫做/zk/conf,指定了这种类型的节点后zk会创建/zk/conf0000000000, ClientB再去创建就是创建/zk/conf0000000001,ClientC是创建/zk/conf0000000002,以后任意Client来创建这个znode都会得到一个比当前zk命名空间最大znode编号+1的znode,也就是说任意一个Client去创建znode都是保证得到的znode是递增的,而且是唯一的
EPHEMERAL临时znode节点,Client连接到zk service的时候会建立一个session,之后用这个zk连接实例创建该类型的znode,一旦Client关闭了zk的连接,服务器就会清除session,然后这个session建立的znode节点都会从命名空间消失。总结就是,这个类型的znode的生命周期是和Client建立的连接一样的。比如ClientA创建了一个EPHEMERAL的/zk/conf0000000011的znode节点,一旦ClientA的zk连接关闭,这个znode节点就会消失。整个zk service命名空间里就会删除这个znode节点
EPHEMERAL_SEQUENTIAL临时自动编号节点,znode节点编号会自动增加,但是会随session消失而消失

3、创建znode是设置顺序标识,znode名称会附加一个值,顺序号是一个单词递增的计数器,由父节点维护

4、在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序

5、EPHENERAL类型的节点不能有子节点

6、客户端可以在znode上设置监听器

 

  • 2、监听机制

    客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、节点删除、子目录节点增加删除)时,ZooKeeper会通知客户端。监听机制保证ZooKeeper保存的任何的数据的任何改变都能快速的响应到监听了该节点的应用程序

    监听器的工作机制,其实是在客户端会专门创建一个监听线程,在本机的一个端口上等待zk集群发送过来的事件

注意:监听只生效一次

 

  • 监听工作原理

ZooKeeper的Watcher机制主要包括客户端线程、客户端WatcherManager、ZooKeeper服务器三部分。客户端在向ZooKeeper服务器注册的同时,会将Watcher对象存储在客户端的WatcherManager当中。当ZooKeeper服务器触发Watcher事件后,会向客户端发送通知,客户端线程从WatcherManager中取出对应的Watcher对象来执行回调逻辑

 

  • ZooKeeper典型应用场景

1、命名服务

命名服务是分布式系统中较为常见的一类场景,分布式系统中,被命名的实体通常可以是集群中的机器、提供的服务地址或远程对象等,通过命名服务,客户端可以根据指定名字来获取资源的实体、服务地址和提供者的信息。Zookeeper也可帮助应用系统通过资源引用的方式来实现对资源的定位和使用,广义上的命名服务的资源定位都不是真正意义上的实体资源,在分布式环境中,上层应用仅仅需要一个全局唯一的名字。Zookeeper可以实现一套分布式全局唯一ID的分配机制。

2、配置管理

程序总是需要配置的,如果程序分散部署在多台机器上,要逐个改变配置就变得困难。现在把这些配置全部放到Zookeeper上去,保存在Zookeeper的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到Zookeeper的通知,然后从Zookeeper获取新的配置信息应用到系统中就好

                                                       

3、集群管理

所谓集群管理无在乎两点:是否有机器退出和加入、选举master。

对于第一点,所有机器约定在父目录GroupMembers下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与Zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道:有兄弟挂了。新机器加入也是类似,所有机器收到通知:新兄弟目录加入,又多了个新兄弟。

对于第二点,我们稍微改变一下,所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好。当然,这只是其中的一种策略而已,选举策略完全可以由管理员自己制定。

                                            

4、分布式锁

有了ZooKeeper的一致性文件系统,锁的问题变得容易。

锁服务可以分为两三类

一个是写锁,对写加锁,保持独占,或者叫做排它锁,独占锁

一个是读锁,对读加锁,可共享 访问,释放锁之后才可以进行事务操作,也叫共享锁

一个是控制时序,叫时序锁

对于第一类,我们将ZooKeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建/distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建的distribute_lock节点就释放出锁

对于第二类, /distribute_lock已经预先存在,所有客户端在它下面创建临时顺序编号目录节点,和选master一样,编号最小的获得锁,用完删除,依次有序

                                                 

5、队列管理

两种类型的队列:

1、同步队列:当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。

2、先进先出队列:队列按照FIFO方式进行入队和出队操作。

第一类,在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。

第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。

同步队列的流程图:

  • ZooKeeper特点/设计目的

ZooKeeper作为一个集群提供数据一致的协调服务,自然,最好的方式就是整个集群中的各服务节点进行数据的复制和同步。

数据复制的好处:

1、容错:一个节点出错,不至于让整个集群无法提供服务。

2、扩展性:通过增加服务器节点能提高ZooKeeper系统的负载能力,把负载分布到多个节点上。

3、高性能:客户端可访问本地ZooKeeper节点或者访问就近的节点,依次提高用户的访问速度。

从客户端读写访问的透明度来看,数据复制集群系统分下面两种:

1、写主:对数据修改的请求提交给主节点,对读数据请求没有限制,任何节点都能响应。

1.最终一致性: client不论连接到哪个Server,展示给它都是同一个视图,这是ZooKeeper最重要的性能。

2.可靠性:具有简单、健壮、良好的性能,如果消息m被一台服务器接受到,那么它将被所有的服务器接受。

3.实时性:ZooKeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,ZooKeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。

4.等待无关(wait-free):慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待。

5.原子性:更新只能成功或者失败,没有中间状态。

6.顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

R_记忆犹新

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值