ZooKeeper学习笔记(五)之基本概念-续
ACL 权限
ZooKeeper支持以下权限:
CREATE : you can create a child node
READ : you can get data from a node and list its children.
WRITE : you can set data for a node
DELETE : you can delete a child node
ADMIN : you can set permissions
创建和删除被从写的权限中抽离出来以实现更细粒度的控制.
因为ZooKeeper并无znode拥有者的概念,所以设计了ADMIN
权限。ZooKeeper默认所有人拥有excute/lookup权限。
内建ACL策略
ZooKeeeper有以下内建策略。
world : 有唯一id,anyone,表示任何人
auth : 不使用id, 代表认证用户
digest : 用 username:password 来生成 MD5 hash作为id. 认证使用username:password形式的明文, ACL中密码采用base64 编码的密码 的SHA1哈希.
ip :使用client IP 作为id. expression为
addr/bits
形式.
C client API
const int ZOO_PERM_READ; //can read node’s value and list its children
const int ZOO_PERM_WRITE;// can set the node’s value
const int ZOO_PERM_CREATE; //can create children
const int ZOO_PERM_DELETE;// can delete children
const int ZOO_PERM_ADMIN; //can execute set_acl()
const int ZOO_PERM_ALL;// all of the above flags OR’d together
以下是标准ID:
struct Id ZOO_ANYONE_ID_UNSAFE; //(‘world’,’anyone’)
struct Id ZOO_AUTH_IDS;// (‘auth’,’’)
其中ZOO_AUTH_IDS 中的空id代表 “creator”.
Client标准ACL
struct ACL_vector ZOO_OPEN_ACL_UNSAFE; //(ZOO_PERM_ALL,ZOO_ANYONE_ID_UNSAFE)
struct ACL_vector ZOO_READ_ACL_UNSAFE;// (ZOO_PERM_READ, ZOO_ANYONE_ID_UNSAFE)
struct ACL_vector ZOO_CREATOR_ALL_ACL; //(ZOO_PERM_ALL,ZOO_AUTH_IDS)
ZOO_OPEN_ACL_UNSAFE
完全开放权限. ZOO_READ_ACL_UNSAFE
只读. CREATE_ALL_ACL
对znode创建者完全开放权限.
ACL相关操作
int zoo_add_auth (zhandle_t zh,const char scheme,const char cert, int certLen, void_completion_t completion, const void data);
应用通过zoo_add_auth
完成认证,如果想应用不同的schema和id,可以多次调用该函数。
>
int zoo_create (zhandle_t zh, const char path, const char value,int valuelen, const struct ACL_vector acl, int flags,char realpath, int max_realpath_len);
创建node,acl参数是一个代表znode授权的List
>
int zoo_get_acl (zhandle_t zh, const char path,struct ACL_vector acl, struct Stat stat);
返回ACL信息
>
int zoo_set_acl (zhandle_t zh, const char path, int version,const struct ACL_vector acl);
必须且有ADMIN权限才能执行,更新ACL设置
一致性保证
序列一致性
更新操作的执行顺序等于指令发送的顺序
原子性Atomicity
只有成功或失败,没有半完成的可能。
单系统镜像
client看到的内容与其连接到的具体Server无关
可靠性
更新完成后,效果会保持到一下次更新前,包含以下两层含义:
如果client得到成功的返回码,意味着操作生效。有时client并不知道操作是否成功(网络延迟等),系统会尽量完成操作,但正确的返回码才能确认操作成功的唯一标识。
client看到的任何更新,即使系统从错误中恢复也都不会回滚。
时间线 / Timeliness
client对系统的视图在一定限度内(十秒级)是保持更新的,如果更新不能发送给client, client将检测到服务过期。
利用这种一致性可以方便地在client端构建高级功能,例如leader选拔,barrier,队列和可撤销读写锁。
注,ZooKeeper并不提供以下保障
ZooKeeper并不保证每个实例是实时的,不同的client对系统的视图可能不一致。由于延时的存在,某一client可能在另一client得到通知之前已经完成了更改。如果要确保client得到最新的数据,在read之间应该执行sync操作。
所以ZooKeeper本身并不保证更改在所有Server中同时发生,但ZooKeeper的基元可用于构建提供client同步的高级功能。
Binding
ZooKeeper提供两种语言的client库,c和java。
Java Binding
由两个package组成,org.apache.zookeeper
和 org.apache.zookeeper.data
,其它的包用于构成内部或者是以上两个包的一部分。org.apache.zookeeper.data
完全由container组成。
一般主要使用的是ZooKeeper类,它的两个构造方法只差一个可选的session id 和 password参数. ZooKeeper支持跨进程间的会话恢复。进程可以保存会话到永久存储,重启和恢复程序中更早的实例使用过的会话。
创建ZooKeeper对象的同时也新建了两个线程,io线程和event线程。所有的io在io线程中进行,所有的回调在event线程中进行。会话维持如心跳在IO线程完成,所有异步方法的响应和watch处理在事件线程中完成。这样设计的考虑有:
所有异步调用完成的回调 和 watch的回调都被设计为有序的,一次一个。调用者可以自由做任何事,回调不阻塞IO线程和同步调用。
同步调用可能不会以相同的顺序返回,例如假设一个client执行如下操作:发出一个read /a 的异步请求同时设置watch,在请求完成的回调中执行同步的read /a 操作(不算好的例子,但是完全合法)。
如果在两次read间 /a 有变化,client库 在同步read操作收到响应之前 会收到watch事件,但因为异步操作的完成回调会阻塞事件队列(event thread),同步的read将 在watch事件处理之前 返回新的 /a 值。
最后,关闭操作的规则十分直接:当ZooKeeper对象被关闭或者收到一个致命错误事件 (SESSION_EXPIRED and AUTH_FAILED),ZooKeeper对象变成无效的。关闭时,两个线程被终止,之后任何对handle的访问都是未被定义的行为,应该避免。