RocketMQ源码 索引文件/indexFile 和 消费队列/ConsumeQueue

indexFile(索引文件)和 ConsumeQueue(消费队列),都是为了更快的查找而建立的索引,后者是根据topic,前者是根据key。在ReputMessageService(一个ServiceThread的实现类)的doReput方法中,

会循环遍历每一条新收到的消息,

DefaultMessageStore.this.doDispatch(dispatchRequest)-->CommitLogDispatcherBuildIndex/CommitLogDispatcherBuildConsumeQueue .doDispatch,

先看前者,到了indexService.buildIndex,key分为两种,一种是UniqKey,系统自动生成的,相当于uuid?在之前的事务消息里提到过?还有一种是自定义的key,放在message的property中的

indexFile的数据结构最关键:20个字节的header + 500万*4个字节的slotSize + 2000万 * 20个字节的indexSize,先用hash值对500万取余确定slot位置,如果该位置上的4个字节有数据了(slotValue),

说明有hash冲突,假设是和message A冲突,slotValue是A在2000万个indexSize中的位置,那么就把自己的slotValue存到该slot处,把A的slotValue存到自己的20个自己的indexSize的最后4个字节。

这样就形成了链表结构,解决了hash冲突。code为QUERY_MESSAGE(12)的请求,会调用本方法,所以我们实现的DefaultMQPushConsumer等consumer是有queryMessage()方法的。注意收到的消息列表,

key可能是其他hash冲突的key,要过滤,这是因为indexFile只存hash值不存key值,没办法帮我们过滤

原文地址:https://www.cnblogs.com/chuliang/p/15173191.html