commitlog管理文件,通过MappedFileQueue管理一个MappedFile列表,用的是RandomAccessFile和堆外内存MappedByteBuffer(零拷贝,更快)。
commitlog本身是顺序写,broker收到的所有message,一个一个的拼到后面,因为每个MappedFile是固定大小的,而且文件名是存储的首个消息的物理offset,所以根据每个消息的物理offset可以直接算出在哪个文件里,避免遍历读取文件
同时有定时任务在建立索引,一个是CommitLogDispatcherBuildIndex,之前有说过,这个是根据key建立索引的。另一个就是CommitLogDispatcherBuildConsumeQueue。先根据消息里的topic和queueId找到consumerqueue,这两个信息是producer传过来的,producer有topic好理解,之所以有queueid是因为producer发消息会对同一topic-broker下的所有queueID有一个轮询机制(除非指定queueId)。找到consumerqueue后,这个和commitlog其实很像,也是把每个消息在commitlog的offset顺序往后放,之所以可以这么做,是因为根据key查找消费的索引已经有了,当前的ConsumeQueue就是为了消费用的,而消费的逻辑,就是consumer根据message到达broker的顺序往后面一条一条的消费,consumer消费的时候,传过来要消费的消息在topic和queueid维度下的offset(consumeQueue里的消息长度是定长的,所以队列维度下的消息序号乘以定长,就是offset),除一下mappedfile的大小,就能直接找到文件的名字,找到索引,同样的道理,找到commitlog的mappedfile,读取。