This article is intended for those of you who have some knowledge of Zookeeper and want to know the source code or are currently learning the source code. It takes about five minutes

A few days ago, I read a post about the sequence consistency of Zookeeper and explained it mathematically. It was so confusing to me. Here I would like to explain my understanding of the sequence consistency

Zookeeper is often used for distributed coordination services (i.e., services or metadata registration scenarios, such as Dubbo, Kafka: Register the producer or metadata information to the Zookeeper cluster, so that other participants in the distributed system can see it in time, because Zookeeper implements the Zab protocol similar to Paxos to solve the problem of distributed data consistency), distributed lock, etc

What is sequential consistency?

Assume that there is a Zookeeper cluster (N>=3, N is odd), then there is only one Leader (selected by the FastLeaderElection main policy), and all write operations (write operations requested by the client from the Leader or Follower) are handled by the Leader. Although the followers provide read and write operations, the write operations are submitted to the Leader. The Leader and followers jointly ensure the sequence of the same Follower requests. The Leader generates an ZXID for each request (the high 32 bits is the epoch, which identifies the Leader election cycle). Each time a leader is elected, there is a new epoch that identifies the current reign of the leader, with the lower 32 bits used for incremental counting.)

For the write requests 1 and 2 submitted by the same Follower A, some followers may not be able to see the two requests immediately after they are successfully submitted (i.e., strong consistency). However, after the synchronization between themselves and the Leader, when these two requests are seen, You must see request1 first and then request2, and there is no out-of-order between the two requests, i.e. order consistency

When processing the ACK reply from the followers in step 4, the Leader adopts the “success” principle, that is, some followers have not processed or successfully processed the request at this time

So the question is, how do you make sure that the order is consistent?

  • FollowerRequestProcessor is the first processor of followers. If the FollowerRequestProcessor requests are written to queuedRequests of the Commitprocessor (for checking whether the requests are submitted by followers). Then turn Leader
  • The Leader generates an ZXID for each request and sends a proposal to the Follower. The Follower writes the request toPendingTxns blocks the queue and txnLogAnd then sends an ACK to the Leader
public void logRequest(TxnHeader hdr, Record txn) {
    Request request = new Request(hdr.getClientId(), hdr.getCxid(), hdr.getType(), hdr, txn, hdr.getZxid());
    if((request.zxid & 0xffffffffL) ! = 0) { pendingTxns.add(request); } syncProcessor.processRequest(request); }Copy the code

This proposal step will be sent to all followers (one for each follower in the LearnerHandler request processing queue), after which the ack of the follower may not all be returned

  • After the Leader sends a commit request to all the followers, the followers compare the zxID of the commit request with the zxID of the pendingTxns mentioned above. If the zxID of the commit request is inconsistent with that of the pendingTxns, the followers exit and synchronize with the Leader again
long firstElementZxid = pendingTxns.element().zxid;
if(firstElementZxid ! = zxid) { LOG.error("Committing zxid 0x" + Long.toHexString(zxid)
        + " but next pending txn 0x"
        + Long.toHexString(firstElementZxid));
    System.exit(12);
}
Copy the code
  • The Follower processes the commit request. If the write request is not submitted by the Follower, the Follower directly calls FinalRequestProcessor for persistence to trigger the watches. If it is submitted by the Follower, special processing is performed (mainly for scenarios where the client is disconnected) and subsequent processing processes such as FinalRequestProcessor are invoked
  • FinalRequestProcessor persists and returns to the client

To sum up, followers ensure that requests are processed in sequence through sequential identifiers such as queues and ZXids. If a Follower fails to respond, it will exit or resynchronize with the Leader

Welcome to follow my wechat official account