代码@1:如果开启 DLedger ,commitlog 的实现类为 DLedgerCommitLog,也是本文需要关注的关键所在。
代码@2:如果未开启 DLedger,则使用旧版的 Commitlog实现类。
2.2 增加节点状态变更事件监听器
BrokerController#initialize
if (messageStoreConfig.isEnableDLegerCommitLog()) {
DLedgerRoleChangeHandler roleChangeHandler = new DLedgerRoleChangeHandler(this, (DefaultMessageStore) messageStore);
((DLedgerCommitLog)((DefaultMessageStore) messageStore).getCommitLog()).getdLedgerServer().getdLedgerLeaderElector().addRoleChangeHandler(roleChangeHandler);
}
主要调用 LedgerLeaderElector 的 addRoleChanneHandler 方法增加 节点角色变更事件监听器,DLedgerRoleChangeHandler 是实现主从切换的另外一个关键点。
2.3 调用 DefaultMessageStore 的 load 方法
DefaultMessageStore#load
// load Commit Log
result = result && this.commitLog.load(); // @1
// load Consume Queue
result = result && this.loadConsumeQueue();
if (result) {
this.storeCheckpoint = new StoreCheckpoint(StorePathConfigHelper.getStoreCheckpoint(this.messageStoreConfig.getStoreP
《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》
【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享
athRootDir()));
this.indexService.load(lastExitOK);
this.recover(lastExitOK); // @2
log.info(“load over, and the max phy offset = {}”, this.getMaxPhyOffset());
}
代码@1、@2 最终都是委托 commitlog 对象来执行,这里的关键又是如果开启了 DLedger,则最终调用的是 DLedgerCommitLog。
经过上面的铺垫,主角 DLedgerCommitLog “闪亮登场“了。
温馨提示:由于 Commitlog 的绝大部分方法都已经在《RocketMQ技术内幕》一书中详细介绍了,并且 DLedgerCommitLog 的实现原理与 Commitlog 文件的实现原理类同,本文会一笔带过关于存储部分的实现细节。
3.1 核心类图
DLedgerCommitlog 继承自 Commitlog。让我们一一来看一下它的核心属性。
- DLedgerServer dLedgerServer
基于 raft 协议实现的集群内的一个节点,用 DLedgerServer 实例表示。
- DLedgerConfig dLedgerConfig
DLedger 的配置信息。
- DLedgerMmapFileStore dLedgerFileStore
DLedger 基于文件映射的存储实现。
- MmapFileList dLedgerFileList
DLedger 所管理的存储文件集合,对比 RocketMQ 中的 MappedFileQueue。
- int id
节点ID,0 表示主节点,非0表示从节点
- MessageSerializer