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

2 篇文章 0 订阅
1 篇文章 0 订阅

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 同步

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

有几个 ID 这里说明下

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

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

关于 minCommittedLog maxCommitedLog

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

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

这里需要提下 committedLog 列表,这个 list 干啥的呢,看下面的源码注释,原来是为了 leader 和 follower 之间快速完成数据同步用的缓存。
/**
 * maintains a list of last <i>committedLog</i>
 *  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 列表中。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值