美文网首页Zookeeper
ZooKeeper顺序节点之Sequence原理

ZooKeeper顺序节点之Sequence原理

作者: 超人也害羞 | 来源:发表于2020-11-15 00:25 被阅读0次

    sequence自增原理是什么?

    为什么get命令看到的cversion和实际存储的cversion不一样?

    sequence自增怎么保证无并发问题?单节点和多节点?

    1. sequence自增原理是什么?

      // 代码取自(服务端代码)org.apache.zookeeper.server.PrepRequestProcessor#pRequest2TxnCreate
      ChangeRecord parentRecord = getRecordForPath(parentPath);
      checkACL(zks, parentRecord.acl, ZooDefs.Perms.CREATE, request.authInfo);
      int parentCVersion = parentRecord.stat.getCversion();
      if (createMode.isSequential()) {
          // 如果是顺序节点的话,从父节点中取出cversion的值作为sequence.
          path = path + String.format(Locale.ENGLISH, "%010d", parentCVersion);
      }
      
    2. 为什么get命令看到的cversion和实际存储的cversion不一样?

      知道了sequence取值逻辑后,用get命令查看父节点的cversion字段,却发现总是和新生成节点的sequence不一致?最后定位到get命令的代码.

      // 代码取自(服务端代码)org.apache.zookeeper.server.DataNode#copyStat
      synchronized public void copyStat(Stat to) {
              to.setAversion(stat.getAversion());
              to.setCtime(stat.getCtime());
              to.setCzxid(stat.getCzxid());
              to.setMtime(stat.getMtime());
              to.setMzxid(stat.getMzxid());
              to.setPzxid(stat.getPzxid());
              to.setVersion(stat.getVersion());
              to.setEphemeralOwner(getClientEphemeralOwner(stat));
              to.setDataLength(data == null ? 0 : data.length);
              int numChildren = 0;
              if (this.children != null) {
                  numChildren = children.size();
              }
           // 重点!
              // when we do the Cversion we need to translate from the count of the creates
              // to the count of the changes (v3 semantics)
              // for every create there is a delete except for the children still present
           // 当我们进行Cversion时,我们需要从create的数量中进行翻译更改计数(v3语义)对于每个创建都有一个删除,除了仍然存在的孩子(Google 翻译)
              to.setCversion(stat.getCversion()*2 - numChildren);
              to.setNumChildren(numChildren);
      }
      
    3. sequence自增怎么保证无并发问题?单节点和多节点?

      先来说多节点吧,(参考网上通常的说法)当一个客户端进行写数据请求时,会指定ZooKeeper集群中的一个Server节点,如果该节点为Follower,则该节点会把写请求转发给Leader,Leader通过内部的协议进行原子广播,直到一半以上的server节点都成功写入数据,这次写请求便算是成功,然后Leader便会通过通知相应的Follower节点写请求成功,该节点向client返回写入成功.
      本质上说还是把多节点写操作转换成了单节点的写操作,这样就可以在单节点进行并发控制了,效率更高.而在单节点做并发控制的话就方便的多了,通过PrepRequestProcessor->SyncRequestProcessor->FinalRequestProcessor->ZooKeeperServer->ZKDatabase->DataTree链路处理.有兴趣可以自己翻翻代码哦.

    相关文章

      网友评论

        本文标题:ZooKeeper顺序节点之Sequence原理

        本文链接:https://www.haomeiwen.com/subject/gcigbktx.html