消息存储:
1,消息发送流程:
消息发送->消息存储->ACK确认已发送->消费者消费->ACK确认->消息删除
2,commitLog
真正存储消息的文件-->文件系统,ssd落盘快,1G大小递增的
3,consumerQueue
基于commitLog的索引文件,每个queue都会生成一个consumerQueue consumerQueue维持一个队列,单个数据结构分为offset(8byte),size(4byte),tagCode(8byte) ,因此可以分局tagCode快速找到消息,consumequeue单个文件可以存储30w个条目
4,indexFile
也是索引,不过建立indexFile的字段为key和时间,因此像通过时间恢复基于此索引,indexFile单个文件为400M可以存储的索引条目2000w条,indexFile按时间戳命名 因为indexFile底层是hash,因此可以说RocketMq的底层实现方式是hash
commitLog可以按照三天清理或者达到磁盘的75%清理
5,疑问:
rocketMQ毕竟存储磁盘的,怎么实现的高效
CommitLog的顺序写,通过ConsumerQueue的随机读
利用操作系统的PageCache+零拷贝技术
普通拷贝:1,硬盘---DMA Copy-->内核缓冲区--cpu拷贝-->用户缓冲区--cpu拷贝-->socket缓冲区-DMA Copy->NIC buffer 网卡缓冲区 内核缓冲区可以预读缓存,已经是优化过的方式了
零拷贝两种方式:
1,mmap+writer 由mmap代替read() 用户缓冲区和内核缓冲区共享 减少一次复制次数 ,新问题 DMA 支持不好,如果map文件时,文件被另一个进程截断,系统调用writer()方法就会因为非法地址而被sigbus信号终止
注:sigbus意味着指针所对应的地址是有效地址,但总线不能正常使用该指针。通常是未对齐的数据访问所致。SIGBUS的缺省行为是终止当前进程并产生core dump。
2,mmap+sendfile 避免因为write带来的问题 NIO 方式
6,刷盘机制: 异步刷盘把信息刷到内存中即返回