RocketMQ 主从同步

吃可爱长大的小学妹 提交于 2019-12-02 05:58:48

RocketMQ 的主和从一直在使用 nio 进行数据同步:

master

master 监听端口
org.apache.rocketmq.store.ha.HAService.AcceptSocketService#beginAccept

master 建立连接
org.apache.rocketmq.store.ha.HAService.AcceptSocketService#run

master 读取 slave 上报的 maxOffset
org.apache.rocketmq.store.ha.HAConnection.ReadSocketService#run

master 传输数据给 slave
org.apache.rocketmq.store.ha.HAConnection.WriteSocketService#run

slave

slave 连接 master
org.apache.rocketmq.store.ha.HAService.HAClient#connectMaster

slave 报告 maxOffset 给 master
org.apache.rocketmq.store.ha.HAService.HAClient#run

slave 接收 master 传输来的数据
org.apache.rocketmq.store.ha.HAService.HAClient#processReadEvent

这里的同步,暂时只涉及到 commitLog。

同步双写的本质,master 写入消息,并且等待从同步消息成功。

broker 写入消息,同步双写的逻辑:

// org.apache.rocketmq.store.CommitLog#handleHA
public void handleHA(AppendMessageResult result, PutMessageResult putMessageResult, MessageExt messageExt) {
    // SYNC_MASTER 则执行逻辑
    if (BrokerRole.SYNC_MASTER == this.defaultMessageStore.getMessageStoreConfig().getBrokerRole()) {
        HAService service = this.defaultMessageStore.getHaService();
        if (messageExt.isWaitStoreMsgOK()) {
            // Determine whether to wait
            // slave 没有落后 master 太多
            if (service.isSlaveOK(result.getWroteOffset() + result.getWroteBytes())) {
                GroupCommitRequest request = new GroupCommitRequest(result.getWroteOffset() + result.getWroteBytes());
                // 创建 GroupCommitRequest 放入 GroupTransferService 的 requestsWrite 中
                // GroupTransferService.run 会一直比较 GroupCommitRequest#nextOffset 和 slave 已提交的位移
                service.putRequest(request);
                service.getWaitNotifyObject().wakeupAll();
                // 等待 5 秒,检查 slave 的同步结果
                boolean flushOK =
                    request.waitForFlush(this.defaultMessageStore.getMessageStoreConfig().getSyncFlushTimeout());
                if (!flushOK) {
                    log.error("do sync transfer other node, wait return, but failed, topic: " + messageExt.getTopic() + " tags: "
                        + messageExt.getTags() + " client address: " + messageExt.getBornHostNameString());
                    putMessageResult.setPutMessageStatus(PutMessageStatus.FLUSH_SLAVE_TIMEOUT);
                }
            }
            // Slave problem
            else {
                // Tell the producer, slave not available
                putMessageResult.setPutMessageStatus(PutMessageStatus.SLAVE_NOT_AVAILABLE);
            }
        }
    }
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!