【上木Debug Zookeeper】数据同步之 LearnerHandler.syncFollower()

Leader 同步数据给 Follower,由 LearnerHandler.syncFollower() 方法完成。

Case 1: 设置了 zookeeper.forceSnapshotSync 参数(一般测试使用),则强制用 snapshot 进行同步
Case 2: lastProcessedZxid == peerLastZxid Leader发送空的 DIFF 包给 Follower
Case 3: peerLastZxid > maxCommittedLog && !isPeerNewEpochZxid Leader发送 TRUNC 包给 Follower
Case 4: minCommittedLog <= peerLastZxid <= maxCommittedLog 用 commitlog 同步
Case 5: peerLastZxid < minCommittedLog && txnLogSyncEnabled 用 事务日志和commitlog 同步

画了个大致流程,如下图:

【上木Debug Zookeeper】数据同步之 LearnerHandler.syncFollower()_第1张图片

有几个 ID 这里说明下

lastProcessedZxid  —— 故名思意,就是最近一次处理的事务 zxid。该值最初由最新的 snapshot 文件名中取得,如下图所示。

【上木Debug Zookeeper】数据同步之 LearnerHandler.syncFollower()_第2张图片

若 事务 日志中保存了更大的值,则在系统重启回放(playback 见下面第二张图)事务日志时,会再次更新 lastProcessedZxid 同时 也会设置 minCommittedLog maxCommitedLog.

【上木Debug Zookeeper】数据同步之 LearnerHandler.syncFollower()_第3张图片

【上木Debug Zookeeper】数据同步之 LearnerHandler.syncFollower()_第4张图片

【上木Debug Zookeeper】数据同步之 LearnerHandler.syncFollower()_第5张图片

关于 minCommittedLog maxCommitedLog

上面说的 minCommittedLog maxCommitedLog 定义于 ZKDatabase 具体如下:

protected long minCommittedLog, maxCommittedLog;
protected LinkedList committedLog = new LinkedList();

这里需要提下 committedLog 列表,这个 list 干啥的呢,看下面的源码注释,原来是为了 leader 和 follower 之间快速完成数据同步用的缓存。
/**
 * maintains a list of last committedLog
 *  or so committed requests. This is used for
 * fast follower synchronization.
 * @param request committed request
 */
public void addCommittedProposal(Request request) {   
    WriteLock wl = logLock.writeLock();
    try {
        wl.lock();
        if (committedLog.size() > commitLogCount) {
            committedLog.removeFirst();  // 1
            minCommittedLog = committedLog.getFirst().packet.getZxid();  // 2
        }
        if (committedLog.isEmpty()) {
            minCommittedLog = request.zxid;
            maxCommittedLog = request.zxid;
        }

        byte[] data = SerializeUtils.serializeRequest(request);
        QuorumPacket pp = new QuorumPacket(Leader.PROPOSAL, request.zxid, data, null);
        Proposal p = new Proposal();
        p.packet = pp;
        p.request = request;
        committedLog.add(p);   // 3
        maxCommittedLog = p.packet.getZxid();  // 4
    } finally {
        wl.unlock();
    }
}
这个缓存的大小由 commitLogCount 控制,默认值为 500. 当 committedLog 长度大于 500,就把列表头部第一个 commit log 删除(见 1 处),而 minCommittedLog 的值永远是 committedLog 列表中第一个元素(见 2 处)。maxCommittedLog 指向 committedLog 列表的最后一个元素(见 34 处)。此外,每当有新提交的议案,都会调用 addCommittedProposal 添加到 committedLog 列表中。

你可能感兴趣的:(JAVA,Zookeeper,hadoop,bigdata,service)