分析Zookeeper不提供永久Watcher的原因并如何保证获取最新数据

(1)在使用ZooKeeper的过程中,相信很多人都有这样的疑问,为什么不提供一个持久的Watcher注册机制呢?


不支持用持久Watcher的原因很简单,如果Watcher的注册是持久的,那么必然导致服务端的每次数据更新都会通知到客户端——这在数据变更非常频繁且监听客户端特别多的场景下,ZooKeeper无法保证性能。

(2)那么你或许还会问,“服务端的每次数据更新都会通知到客户端”,这不正式用户希望达到的效果么?


我们仔细考虑这个问题,就可以发现,很多时候,我们需要的是最新数据,而不是每次变更!


(3)那么下面来看我们如何保证Watcher到最新的数据


每次在注册watcher之后都getData,保证数据版本是最新的,但相比较每次都通知优势还是很明显的,这样的处理在非常频繁更新数据的情况下少了许多中间数据变更的过程。


接下来我们来分析如果做到注册Watcher以后并获取最新数据的


client客户端执行getData方法后在zookeeper服务器端将执行FinalRequestProcessor的processRequest方法:


case OpCode.getData: {
                lastOp = "GETD";
                GetDataRequest getDataRequest = new GetDataRequest();
                ByteBufferInputStream.byteBuffer2Record(request.request,
                        getDataRequest);
                DataNode n = zks.getZKDatabase().getNode(getDataRequest.getPath());
                if (n == null) {
                    throw new KeeperException.NoNodeException();
                }
                Long aclL;
                synchronized(n) {
                    aclL = n.acl;
                }
                PrepRequestProcessor.checkACL(zks, zks.getZKDatabase().convertLong(aclL),
                        ZooDefs.Perms.READ,
                        request.authInfo);
                Stat stat = new Stat();
                byte b[] = zks.getZKDatabase().getData(getDataRequest.getPath(), stat,
                        getDataRequest.getWatch() ? cnxn : null);
                rsp = new GetDataResponse(b, stat);
                break;
            }

并执行到以下代码:


public byte[] getData(String path, Stat stat, Watcher watcher)
            throws KeeperException.NoNodeException {
        DataNode n = nodes.get(path);
        if (n == null) {
            throw new KeeperException.NoNodeException();
        }
        synchronized (n) {
            n.copyStat(stat);
            if (watcher != null) {
                dataWatches.addWatch(path, watcher);
            }
            return n.data;
        }
    }

我们可以清楚的看到首先将watch加入到dataWatches,换句话说就是先注册了watch然后返回了path的最新数据,这样就保证了如果在没有注册watch的这段时间内如果没有件听到数据的变化那么将通过n.data返回给client客户端


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值