ZK in action笔记二

第3章

Session的处理注意点:

如果session不再需要使用,需要立刻[b]close[/b]


[b]CONNECTIONLOSS[/b]

客户端与zk service的连接断开,也就是TCP连接已经断开了。这时候如果进行原语操作,比如create等,就会出现CONNECTIONLOSS。

CONNECTIONLOSS的出现,会引起不确定的问题:即:之前的原语操作是否成功, 有如下3种情况:

1. 原语操作还没有发给服务端
2. 原语操作已经发给服务端,但是服务端还未执行
3. 原语操作已经发给服务端,服务端也执行了,但是客户端没有收到结果

因此应用在处理CONNECTIONLOSS时,需要容错这3种情况,实际上是2种情况,即:操作成功/失败的状态,是不确定的。

有2种处理方式:

1. 可以选择校验看是否成功,比如之前setData,现在可以getData进行确认;
2. 不在乎结果,那就重试发送。

总结:

Remember, ZooKeeper helps organize distributed state and provides a framework for handling failures; it doesnt make failures go away, unfortunately.


第4章

轮询不好,需要watch

watch是一次触发,比如exists原语,可以监控多个事件 create/delete/change,但是只要有1个事件触发,watch就结束了,而应用中很多时候是要连续watch,可参考curator等lib

一次触发,会不会导致丢失事件? 是会的,参考第2章的图,但是数据不会丢失。

watch生命周期是随着session的,只要session不过期,watch就是有效的。 比如zk server宕机,发生了重连,客户端的watch也会发给重连的zk server。 如果watch需要触发,则立刻触发,否则注册到zk server上。

session state:

SyncConnected
Disconnected
Expired
AuthFailed
ConnectedReadOnly
SaslAuthenticated

事件:
NodeCreated,
NodeDeleted
NodeDataChanged
NodeChildrenChanged
None

事件watch对应的操作原语:

NodeCreated
A watch is set with a call to exists.
NodeDeleted
A watch is set with a call to either exists or getData.
NodeDataChanged
A watch is set with either exists or getData.
NodeChildrenChanged
A watch is set with getChildren.

看一下示例代码:

这里主要是监控 session的状态变化,即 生命周期
/**
* This method implements the process method of the
* Watcher interface. We use it to deal with the
* different states of a session.
*
* @param e new session event to be processed
*/
public void process(WatchedEvent e) {
LOG.info("Processing event: " + e.toString());
// 事件为NONE,标明是Session状态变化
if(e.getType() == Event.EventType.None){
switch (e.getState()) {
case SyncConnected:
connected = true;
break;
case Disconnected:
connected = false;
break;
case Expired:
expired = true;
connected = false;
LOG.error("Session expiration");
default:
break;
}
}
}

这里是普通的exists API
// 判断事件类型
Watcher masterExistsWatcher = new Watcher(){
public void process(WatchedEvent e) {
if(e.getType() == EventType.NodeDeleted) {
assert "/master".equals( e.getPath() );

runForMaster();
}
}
};



watch设置后,是否可以删除呢? 目前无法直接删除,只能通过 session 过期 或者 主动close。

这个功能在3.5.0已经增加了,可以看下3.5.0的release notes:
http://zookeeper.apache.org/doc/r3.5.0-alpha/releasenotes.html


* [ZOOKEEPER-442] - need a way to remove watches that are no longer of interest


Description
currently the only way a watch cleared is to trigger it. we need a way to enumerate the outstanding watch objects, find watch events the objects are watching for, and remove interests in an event.


总结一下,watch可以用在2个地方:

1. 监视session的状态变化
2. 监视znode的节点变化

这里采用的是同一套机制,需要区分。 如果event是None,则是Session状态变化;如果event不是Node,则是znode变化


顺序性保证

写的顺序性

zk server对于写操作,是顺序进行的;在zk集群中,多个zk server的数据同步,也是按照顺序进行的,不会造成写乱序的情况。

当时因为延迟的情况,不能保证zk server的数据强一致,在某个时间点存在不一致的情况,比如某个数据还未同步过来。


读的顺序性

多个客户端,连接zk集群中不同的server,依然能保证按照顺序读到相应的修改。

但是因为 同步的不一致性, 不能保证同一个时间点,各个客户端读到的数据完全是一致的,一般来说,是没有问题的。 只有某个特殊情况会有问题,称为hidden channel,应该避免这种情况


notification的顺序性


第5章

对于失败,有不同的情况,这里说明一种情况:

假设是竞争/master,如果 当前的master因为网络等原因,与ZK已经断开连接,但是master不知道,还以为自己活着,而且自己做了master的事情。

而slave与zk是正常的, 从zk上发现/master已经挂掉了,就转换为master角色。

这时候出问题了,我们有2个master。 而如果某些操作 必须是互斥的,比如写文件, 这时候如果2个一起写,就导致数据错乱,系统挂掉了。


recoverable failures

unrecoverable failures

session过期

session认证错误

对于这种情况,只有2种处理方式:
1. 重启
2. 不重启,清除内部资源,重新初始化,重新创建session
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值