7.3.1 按照 Message Id 查询消息
MsgId 总共 16 字节,包含消息存储主机地址,消息 Commit Log offset。从 MsgId 中解析出 Broker 的地址和Commit Log 的偏移地址,然后按照存储格式所在位置消息 buffer 解析成一个完整的消息。
7.3.2 按照 Message Key 查询消息
- 根据查询的key的hashcode%slotNum得到具体的槽的位置 (slotNum是一个索引文件里面包含的最大槽的数目,例如图中所示 slotNum=5000000) 。
- 根据 slotValue(slot 位置对应的值)查找到索引项列表的最后一项(倒序排列,slotValue 总是指向最新的一个索引项) 。
- 遍历索引项列表返回查询时间范围内的结果集(默认一次最大返回的 32 条记录)
- Hash 冲突;寻找 key 的 slot 位置时相当于执行了两次散列函数,一次 key 的 hash,一次 key 的 hash 值取模,因此这里存在两次冲突的情况;第一种,key 的 hash 值不同但模数相同,此时查询的时候会在比较一次 key 的hash 值(每个索引项保存了 key 的 hash 值) ,过滤掉 hash 值不相等的项。第二种,hash 值相等但 key 不等,出于性能的考虑冲突的检测放到客户端处理(key 的原始值是存储在消息文件中的,避免对数据文件的解析) ,客户端比较一次消息体的 key 是否相同。
- 存储;为了节省空间索引项中存储的时间是时间差值(存储时间-开始时间,开始时间存储在索引文件头中) ,整个索引文件是定长的,结构也是固定的。索引文件存储结构参见图 7.4.3-3 。