摘要: 众所周知,分布式的系统协作服务很难有让人满意的产品。这些协作服务产品很容易陷入一些诸如竞争选择条件或者死锁的陷阱中。那Zookeeper又是怎么解决这个问题的呢?
博主福利
给大家推荐一套hadoop视频课程
[百度hadoop核心架构师,首次内部分享的企业级项目视频,价值3980元]
免费赠送100份,先到先得。联系老师微信ganshiyu1026,备注OSchina。
部分视频截图展示
上一篇文章我们详细介绍了mapreduce计算框架,此时你已经了解hadoop集群的数据处理方式,接下来我们讲解
分布式的,开源的,应用于分布式应用的协作服务的--Zookeeper
众所周知,分布式的系统协作服务很难有让人满意的产品。这些协作服务产品很容易陷入一些诸如竞争选择条件或者死锁的陷阱中。那Zookeeper又是怎么解决这个问题的呢?
Zookeeper提供了一些简单的操作,使得分布式应用可以基于这些接口实现诸如同步、配置维护和分集群或者命名的服务。Zookeeper很容易编程接入,它使用了一个和文件树结构相似的数据模型。可以使用Java或者C来进行编程接入。它的目的就是将分布式服务不再需要由于协作冲突而另外实现协作服务。
本篇内容:
1) Zookeeper数据模型
2) Zookeeper访问控制
3) Zookeeper应用场景
1. Zookeeper数据模型
ZooKeeper拥有一个层次的命名空间,这个和标准的文件系统非常相似
从图中我们可以看出ZooKeeper的数据模型,在结构上和标准文件系统的非常相似,都是采用这种树形层次结构,ZooKeeper树中的每个节点被称为—Znode。和文件系统的目录树一样,ZooKeeper树中的每个节点可以拥有子节点。但也有不同之处:
1) 引用方式:
Zonde通过路径引用,如同Unix中的文件路径。路径必须是绝对的,因此他们必须由斜杠字符来开头。除此以外,他们必须是唯一的,也就是说每一个路径只有一个表示,因此这些路径不能改变。在ZooKeeper中,路径由Unicode字符串组成,并且有一些限制。字符串"/zookeeper"用以保存管理信息,比如关键配额信息。
2) Znode结构
ZooKeeper命名空间中的Znode,兼具文件和目录两种特点。既像文件一样维护着数据、元信息、ACL、时间戳等数据结构,又像目录一样可以作为路径标识的一部分。图中的每个节点称为一个Znode。 每个Znode由3部分组成:
l stat:此为状态信息, 描述该Znode的版本, 权限等信息
l data:与该Znode关联的数据
l children:该Znode下的子节点
ZooKeeper虽然可以关联一些数据,但并没有被设计为常规的数据库或者大数据存储,相反的是,它用来管理调度数据,比如分布式应用中的配置文件信息、状态信息、汇集位置等等。这些数据的共同特性就是它们都是很小的数据,通常以KB为大小单位。ZooKeeper的服务器和客户端都被设计为严格检查并限制每个Znode的数据大小至多1M,但常规使用中应该远小于此值。
3) 数据访问
ZooKeeper中的每个节点存储的数据要被原子性的操作。也就是说读操作将获取与节点相关的所有数据,写操作也将替换掉节点的所有数据。另外,每一个节点都拥有自己的ACL(访问控制列表),这个列表规定了用户的权限,即限定了特定用户对目标节点可以执行的操作。
4) 节点类型
Persistent Nodes:永久有效地节点,除非client显式的删除,否则一直存在。
Ephemeral Nodes:临时节点,仅在创建该节点client保持连接期间有效,一旦连接丢失,zookeeper会自动删除该节点。
Sequence Nodes:顺序节点,client申请创建该节点时, ZooKeeper会自动在节点路径末尾添加递增序号,这种类型是实现分布式锁,分布式queue等特殊功能的关键。
5) 监控
客户端可以在节点上设置watch,我们称之为监视器。当节点状态发生改变时(Znode的增、删、改)将会触发watch所对应的操作。当watch被触发时,ZooKeeper将会向客户端发送且仅发送一条通知,因为watch只能被触发一次,这样可以减少网络流量。
ZooKeeper可以为所有的读操作设置watch,这些读操作包括:exists()、getChildren()及getData()。watch事件是一次性的触发器,当watch的对象状态发生改变时,将会触发此对象上watch所对应的事件。watch事件将被异步地发送给客户端,并且ZooKeeper为watch机制提供了有序的一致性保证。理论上,客户端接收watch事件的时间要快于其看到watch对象状态变化的时间。
2. Zookeeper访问控制
传统的文件系统中,ACL分为两个维度,一个是属组,一个是权限,子目录/文件默认继承父目录的ACL。而在Zookeeper中,node的ACL是没有继承关系的,是独立控制的。Zookeeper的ACL,可以从三个维度来理解:一是scheme; 二是user; 三是permission,通常表示为scheme:id:permissions, 下面从这三个方面分别来介绍:
1) scheme: scheme对应于采用哪种方案来进行权限管理,zookeeper实现了一个pluggable的ACL方案,可以通过扩展scheme,来扩展ACL的机制。
模式 |
描述 |
World |
它下面只有一个id, 叫anyone, world:anyone代表任何人,zookeeper中对所有人有权限的结点就是属于world:anyone的 |
Auth |
已经被认证的用户 |
Digest |
通过username:password字符串的MD5编码认证用户 |
Host |
匹配主机名后缀,如,host:corp.com匹配host:host1.corp.com, host:host2.corp.com,但不能匹配host:host1.store.com |
IP |
通过IP识别用户,表达式格式为 addr/bits |
2) User:与scheme是紧密相关的,具体的情况在上面介绍scheme的过程都已介绍,这里不再赘述。
3) permission: zookeeper目前支持下面一些权限:
权限 |
描述 |
备注 |
Create |
有创建子节点的权限 |
|
Read |
有读取节点数据和子节点列表的权限 |
|
Write |
有修改节点数据的权限 |
无创建和删除子节点的权限 |
Delete |
有删除子节点的权限 |
|
Admin |
有设置节点权限的权限 |
3. Zookeeper应用场景
1) 数据发布与订阅(配置中心)
发布与订阅模型,即所谓的配置中心,顾名思义就是发布者将数据发布到ZK节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。例如全局的配置信息,服务式服务框架的服务地址列表等就非常适合使用。
2) 分布式锁服务
分布式锁,这个主要得益于ZooKeeper为我们保证了数据的强一致性。锁服务可以分为两类,一个是保持独占,另一个是控制时序。
3) 分布式队列
队列方面,简单地讲有两种,一种是常规的先进先出队列,另一种是要等到队列成员聚齐之后的才统一按序执行。对于第一种先进先出队列,和分布式锁服务中的控制时序场景基本原理一致,这里不再赘述。 第二种队列其实是在FIFO队列的基础上作了一个增强。
通常可以在 /queue 这个znode下预先建立一个/queue/num 节点,并且赋值为n(或者直接给/queue赋值n),表示队列大小,之后每次有队列成员加入后,就判断下是否已经到达队列大小,决定是否可以开始执行了。这种用法的典型场景是,分布式环境中,一个大任务Task A,需要在很多子任务完成(或条件就绪)情况下才能进行。
这个时候,凡是其中一个子任务完成(就绪),那么就去 /taskList 下建立自己的临时时序节点(CreateMode.EPHEMERAL_SEQUENTIAL),当 /taskList 发现自己下面的子节点满足指定个数,就可以进行下一步按序进行处理了。
此时你已经学会了安装hadoop集群,了解了HDFS文件系统,MapReduce计算框架和Zookeeper协作服务(Zookeeper数据模型、访问控制、应用场景),下一篇文章会继续介绍高可靠的分布式存储系统--HBase 。
此时,你已经掌握了hadoop的半壁江山。