简介Zookeeper(2010)
Zookeeper 提供分布式协调服务,利用他提供的API我们可以实现一些应用,比如,分布式锁,Leader 选举,分布式队列,配置管理,数据发布/等,著名的dubbo也用到了Zookeeper。
数据模型
节点类型
- Regular:Client 通过正常的创建和删除来操作节点
- Ephemeral: Clientc创建一个节点,这个节点可以被clietn显示的删除或者当Session(用户连接到Zook时初始化一个session,类似于http session)终止时候,系统自动删除
API
create(path,data,flags)
在路径path创建一个节点并存储数据data,flags表明这个节点的类型:regular,Ephemeral
delete(path,version)
如果这个节点的version与参数一致,则删除这个节点
exists(path,watch)
判断path下有无这个节点,并在节点设置watch,当节点被删除或改变后别通知
getData(path,watch)
setData(path,data,verison)
getChildren(path,watch)
sync(path)
等待从调用sync时刻起,所有的更新操作反映到这个客户端连接到的服务器上,
在sync的实现上,并无特别,leader只需要将sync这个系统调用放到leader与这个server之间的更新队列的末尾即可,由于zookeepr的对于写操作的线性一致性,所以当server收到这个sync时刻即表明所需要的更新操作已经反映到server上了。
primitive Example
-
配置管理
设置一个path,z,当server启动时通过读取这个节点并把watch设为true,则当配置改变时候,会受到通知。 -
simple lock
lock用一个znode节点表示,当想要获取lock时,就去创建这个节点(Ephemeral),如果创建成功则表示成功获取了lock,否则,则读取这个节点并把watch设为true,当锁被释放时,会被通知,重新竞争lock。缺点:herd effect。被通知后,所有等待的client会被通知去竞争lock,但是只能有一个能成功获取lock
3 simple lock withhout herd effectLock 1 n = create(l+"/lock-",EPHEMERAL|SEQUENTIAL) 2 C = getChildren(l,false) 3 if n is lowest znode in c,exists (successed to get the lock) 4 p = znode in C ordered just before n 5 if exists(p,true) wait for watch event 6 goto 2 Unlock 1 delete(n)
4 read/write lock
write Lock 同上
Lock
1 n = create(l+"/lock-",EPHEMERAL|SEQUENTIAL)
2 C = getChildren(l,false)
3 if n is lowest znode in c,exists (successed to get the lock)
4 p = znode in C ordered just before n
5 if exists(p,true) wait for watch event
6 goto 2
Unlock
1 delete(n)
Read lock
lock
1 n = create(l+"/lock-",EPHEMERAL|SEQUENTIAL)
2 C = getChildren(l,false)
3 if no write nodes in C lower than n,exists (successed to get the lock)
4 p = write znode in C ordered just before n
5 if exists(p,true) wait for watch event
6 go 2
Zookeeper的一致性保证
1 写请求:Linearizable,Zookeeper将所有的写请求都交给leader来处理,通过Zab(为什么需要两阶段提交why??)然后达到线性一致性
2 读请求: FIFO client order,即在一个client的角度来看,这个客户端的所有请求是顺序的
实现
- 所有的写操作都交给leader来处理,让后通过Zab广播协议。两阶段提交
- read locally,对于读操作返回本地的数据,因此可能得到stale data。若有保证读到的是最新的数据,可以使用sync
注意:由于要保证client的FIFO order,设想这样一个情景,当同一个客户端发起write request之后,立即发起另一个read request,这时候,由于通过zab广播需要时间,所以read请求必须堵塞等待数据更新
Request Processor(不是特别懂,how)
将client request 转化为幂等事务
Atomic Broadcast
Zab,提供 类似于paxos和raft这样的leader选举,和容错机制,两阶段提交
由于传播的message是幂等的,因此在恢复时可以更方便点,即使受到同一个message多次也无妨
aft这样的leader选举,和容错机制,两阶段提交
由于传播的message是幂等的,因此在恢复时可以更方便点,即使受到同一个message多次也无妨