【mq读书笔记】如何保证三个消息文件的最终一致性。

考虑转发任务未成功执行,此时消息服务器Broker宕机,导致commitlog,consumeQueue,IndexFile文件数据不一致。

commitlog,consumeQueue遍历每一条消息,将flushedPosition,committedWhere设置到最后一条正常消息处,并删除在这之后的消息,commitlog在不正常停机重启后,重新转发最后一个mappedFile的消息到consumeQueue,等一系列实现

看一下mq关于存储文件的加载流程:

public boolean load() {
        boolean result = true;

        try {
            boolean lastExitOK = !this.isTempFileExist();
            log.info("last shutdown {}", lastExitOK ? "normally" : "abnormally");

            if (null != scheduleMessageService) {
                result = result && this.scheduleMessageService.load();
            }

            // load Commit Log
            result = result && this.commitLog.load();

            // load Consume Queue
            result = result && this.loadConsumeQueue();

            if (result) {
                this.storeCheckpoint =
                    new StoreCheckpoint(StorePathConfigHelper.getStoreCheckpoint(this.messageStoreConfig.getStorePathRootDir()));

                this.indexService.load(lastExitOK);

                this.recover(lastExitOK);

                log.info("load over, and the max phy offset = {}", this.getMaxPhyOffset());
            }
        } catch (Exception e) {
            log.error("load exception", e);
            result = false;
        }

        if (!result) {
            this.allocateMappedFileService.shutdown();
        }

        return result;
    }

【mq读书笔记】如何保证三个消息文件的最终一致性。_第1张图片

 

判断上一次退出是否正常,broker在启动时创建abort文件,在退出时通过注册jvm钩子函数删除abort文件。如果下一次启动时存在abort文件。说明Broker是异常退出的。 

加载延迟队列,与定时消息有关

 

【mq读书笔记】如何保证三个消息文件的最终一致性。_第2张图片

 

 

 

【mq读书笔记】如何保证三个消息文件的最终一致性。_第3张图片

 

加载commitlog,置wrotePosition,flushedPosition,committedPosition三个指针都设置为文件大小。

【mq读书笔记】如何保证三个消息文件的最终一致性。_第4张图片

 

加载消息消费队列。

 

 

【mq读书笔记】如何保证三个消息文件的最终一致性。_第5张图片

 

加载存储检查点,检查点主要记录commitlog文件,consumequeue文件,index索引文件的刷盘点,将在下文的文件刷盘机制中再次提交。

【mq读书笔记】如何保证三个消息文件的最终一致性。_第6张图片

 

【mq读书笔记】如何保证三个消息文件的最终一致性。_第7张图片

 

根据是否正常停机,执行不同的恢复策略。

 

【mq读书笔记】如何保证三个消息文件的最终一致性。_第8张图片

正常停止时从倒数第三个文件开始进行恢复,不足3个文件从第一个文件开始恢复。以及获取crc检查配置

 

【mq读书笔记】如何保证三个消息文件的最终一致性。_第9张图片

 

遍历commitlog文件,每次取出一条消息,如果查找结果为true并且消息的长度大于0表示消息正确,mappedFileOffset指针向前移动本条消息的长度,如果为false,表明该文件未填满所有消息,跳出循环,结束遍历文件

【mq读书笔记】如何保证三个消息文件的最终一致性。_第10张图片

 

【mq读书笔记】如何保证三个消息文件的最终一致性。_第11张图片

更新MappedFileQueue的flushedWhere与commiteedWhere指针

【mq读书笔记】如何保证三个消息文件的最终一致性。_第12张图片

 

删除offset之后的所有文件。遍历目录下的文件,如果文件的起始偏移量大于offset,加入到带删除文件列表,如果小于offset且尾部偏移量大于offset则设置mappedFile的flushedPosition,commitedPosition。

 

不正常停机:

异常停止需要从最后一个文件往前走,找到第一个消息存储正常的文件。并且如果commitlog目录没有消息文件,如果在消息消费队列目录下存在文件,则需要销毁。

 

【mq读书笔记】如何保证三个消息文件的最终一致性。_第13张图片

 1.魔数判断。2.第一条消息存储时间为0,返回false。如果第一条消息存储时间合法则认为是可用的

 

 

【mq读书笔记】如何保证三个消息文件的最终一致性。_第14张图片

恢复commitlog实例中保存每个消息消费队列当前的存储逻辑偏移量,这也是消息中不仅存储主题,消息队列ID还存储了消息队列偏移量的关键所在。

 

你可能感兴趣的:(【mq读书笔记】如何保证三个消息文件的最终一致性。)