rocketMQ之ConsumeQueue

聪明的你是不是早就猜到了这一篇,小望所归下consumeQueue她来啦!

ConsumeQueue

这是咱们消息消费队列 ,消息到了咱们commitlog将被异步转发到consumequeue,来方便消费;毕竟生产了消息不被消费,那纯是海底捞月---------白费劲;大家会不会好奇呀,这个队列是什么队列,这个Queue呀是某opic的一个queue

通过queue名字,大家的第六感应该能想到这里面应该有一个异步,咱们rocketmq为了提高消息存储性能,设计了ReputMessageService异步将consumequeue对象构建出来,让FlushConsumeQueueService将consumequeu数据异步写入磁盘;大神的源码两个异步设计大概能想出来这个性能是多高了,当然涉及到异步过程也会复杂一些。

大致看一下源码更好理解一些:

首先咱们看到了MappedFileQueue,不难猜到读写consumequeue是借助MappedFile,自然也是要借助buffer了,这都写到明面上了,再说都一个团队写的,没必要整其他的多余的 显得生分不和了

当然咱们上面commitlog已经将信息给了buffer在刷到磁盘,所以consumequeue没必要再存一份占用资源,所以consumequeue存储了

1、offset:8字节,路由到queue中的消息在所指定的commitlog中的偏移量(绝对位置);

2、消息大小,4字节,1是头 2是尾巴,这样定位到完整的消息;

3、tagCode:8字节,消息tag的hash(MurmurHash2 算法,做一个标记方便订阅的时候好定位、过滤,毕竟订阅了再在大海中捞针那可不地道)

复制代码
┌───────────────────────────────────────────────────────────────────┐
│ ConsumeQueue 文件(QueueId=0,文件名=000000)                       │
│  ┌─────────────────────────────────────────────────────────────┐  │
│  │  索引项1(20字节)                                          │  │
│  │  ┌──────────┬──────────┬──────────┐                        │  │
│  │  │物理偏移量│  消息长度 │  标签哈希 │                        │  │
│  │  │  8字节   │  4字节   │  8字节   │                        │  │
│  │  └──────────┴──────────┴──────────┘                        │  │
│  ├─────────────────────────────────────────────────────────────┤  │
│  │  索引项2(20字节)                                          │  │
│  │  ┌──────────┬──────────┬──────────┐                        │  │
│  │  │物理偏移量│  消息长度 │  标签哈希 │                        │  │
│  │  │  8字节   │  4字节   │  8字节   │                        │  │
│  │  └──────────┴──────────┴──────────┘                        │  │
│  ├─────────────────────────────────────────────────────────────┤  │
│  │  索引项3(20字节)  ......  索引项N                        │  │
│  └─────────────────────────────────────────────────────────────┘  │
│  └─────────────────────────────────────────────────────────────────┘

可以看出这个文件里面干货满满!消费点很密,为了更多的消息,文件里面都没有分隔符,就应了那就"约定大于配置"大家都是20字节,到节了就让位!

通过上面结构的介绍,聪明当你应该也能看到咱们consumeQueue的设计目的:为了将不同topic的消息分离,按需要去拉取!

再看咱们queue文件的目录结构:

$HOME/store/consumequeue/{Topic}/{QueueId}/{FileName}

  • queueid逻辑队列id(0开始)

  • fileName表示文件开始的偏移量,也就是20位补0命令

    ┌───────────────────────────────────────────────────────────────────┐
    │ store/consumequeue/ 根目录 │
    │ ├─────────────────── TopicA/ (按 Topic 分目录) │
    │ │ ├────────────── 0/ (QueueId=0,读写队列分离可配置) │
    │ │ │ ├─ 000000 (文件1:逻辑偏移量0开始,固定≈600MB)◄───┐ │
    │ │ │ │ ┌─────────────────────────────────────────────┐ │ │
    │ │ │ │ │ 索引项1(20字节) │ 索引项2(20字节) │ ... │ │ │
    │ │ │ │ │ [物理偏移量] │ [物理偏移量] │ │ │ │
    │ │ │ │ │ [消息长度] │ [消息长度] │ │ │ │
    │ │ │ │ │ [Tag哈希] │ [Tag哈希] │ │ │ │
    │ │ │ │ └─────────────────────────────────────────────┘ │ │
    │ │ │ ├─ 000001 (文件2:文件1写满后新建)◄───────────────┘ │
    │ │ │ │ ┌─────────────────────────────────────────────┐ │
    │ │ │ │ │ 索引项N │ 索引项N+1 │ ... │ 空闲空间 │ │
    │ │ │ │ └─────────────────────────────────────────────┘ │
    │ │ │ └─ ...... (后续文件按逻辑偏移量命名) │
    │ │ ├────────────── 1/ (QueueId=1,独立索引文件) │
    │ │ └────────────── N/ (QueueId=N,队列数决定并发消费能力) │
    │ └─────────────────── 其他 Topic/ (同理) │
    └───────────────────────────────────────────────────────────────────┘

咱们rockermq把偏移量作为文件名这个巧妙,一目了然起到了多个作用,之前commitlog的命名也是这样的逻辑,咱们忘记写了好像,在这里补一下

一个文件默认5.72M,大概有30W条记录;30w也不多再说水满则溢 :恰到好处才是最舒服、快捷的,像money这种,如果拥有的太多,人的嘴角就会控制不住的上扬。

说回到我们的主角consumequeue,根据上面的情况,大家也可能了解了,简单来说咱们可以把她当成索引文件,因为她"别有用心"的设计咱们可以找到主题下的消息,这样消费者来了能够在consumequeue快速找到topic对应log文件偏移量,进而快速定位到消息

consumequeue类似(密集型)索引的设计,很小巧就可以将它读到内存中(小巧的一米八五壮汉),这样消费是不是更快了,这速度如果是真消费,那钱包可要锁好了;当然为了防止数据丢失,consumequeue也会持久化到磁盘,不过本身不大,这持久化不是什么事

调优

1、文件大小调优秀

咱们上面说了默认大小,默认配置是mappedFileSizeConsumeQueue=30W * 20B = 600MB大概30w记录,建议增大到1G(大概可以存50w条记录)这样在文件里面能直接找到更多的数据,不需要切换、IO,当然这要考虑到硬件的感受,一般来说都用到mq了,问题应该不大

2、批量更新

根据上面咱们知道queue的记录固定20字节,批量写就可以减少磁盘io,这用脚趾头都能想出来对吧各位道友;具体呢那当然是在关键地方:写的时候下刀子做手术

  • 可以批量发送消息batchSize给他加大
  • 异步刷盘,这异步受限制肯定是少些,也不影响主线,这就很懂事,具体配置是flushDiskType=async_flush,flushIntervalCommitLog=2ms提高吞吐(推荐操作 不一定)

3、消息设计要优美

在现在以瘦为美,咱们消息也不能太胖,减少body消息体大小,可以考虑上狠活:压缩gzip/snappy

在那三个里面还有个tagCode可以嚯嚯,合理设计消息tga,起到真正的过滤作用,避免冲突,像数据表你把type列当索引,就2值还拿来当索引,那二叉树得长成什么鬼样子!所以咱们tag要争气,具有"辨识度"好不好!

4、配置参数

broker线程池大小要调整,适当增加线程数SendMessageThreadPool

增加jvm堆内存,对吧,本身以来jdk别不舍得给划拉一亩三分地,万一GC大家谁面子都挂不住

5、客户端

消费者你来消费,首先要有一个良好的态度和方法,你要使用异步拉取模式,这样你也不要写同步死死滴在那嘎达等着,减少阻塞,省的自己闹心

毕竟一个消息也不大,能一回给他们拉过来就批量全拉来,别客气,pullBatchSize

相关推荐
用户0203388613141 天前
RocketMQ知识点梳理
rocketmq
sww_10261 天前
Kafka和RocketMQ存储模型对比
分布式·kafka·rocketmq
星辰_mya3 天前
rocketMQ的消息存储CommitLog
rocketmq
虎啊兄弟3 天前
RocketMQ面试题
数据库·rocketmq
予枫的编程笔记3 天前
深度解析Apache RocketMQ:从核心原理到实战应用
java·apache·rocketmq
Psycho_MrZhang3 天前
RocketMQ 设计思想总结
rocketmq
山沐与山4 天前
【MQ】MQ消息队列幂等性设计与踩坑实战
java·开发语言·数据库·rocketmq
怒放吧德德4 天前
RocketMQ从实战到源码:初识RocketMQ
java·后端·rocketmq
huisheng_qaq6 天前
【RocketMq基础篇-05】精通rocketmq核心组件(万字长文)
rocketmq·rocketmq核心组件·rocketmq基本使用·rocketmq底层原理·rocketmq消息队列·rocketmq整体架构·rocketmq核心组成