`
BruceChan_GY
  • 浏览: 7010 次
社区版块
存档分类
最新评论

ZK in action笔记二

zk 
阅读更多
第3章

Session的处理注意点:

如果session不再需要使用,需要立刻close


CONNECTIONLOSS

客户端与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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics