并发消费与顺序消费TPS

这里只考虑允许并发消费与顺序消费的业务场景。

首先我们明确一点因为顺序消费会对messageQueue加锁,相同情况下,性能必然远小于并发消费;

先说结论:假设消息消费速度恒定0.5秒。

消费者线程总数 :threadNumtopic

总队列数:msgQueue

并发消费的TPS等同于:

            tps = threadNum/0.5s

顺序消费的速度等同于: 

            tps = min(msgQueue,threadNum)/0.5s ;

ps:因为加锁引起的性能损耗更能达到理论性能。

ps: 如果消费线程较少,并且pullThresholdForQueue较大,将容易导致部分队列饥饿;

接下来分析topic 为什么在消息多时挤压尤为严重。 首先佐证一下consumer 的pullThresholdForQueue这个参数是否存在:每次重启或者新增client,topic的tps 总是瞬间飙升,但是很快就下降了,就是因为这个参数将大量的message缓存至客户端,从而引起Broker错误计算tps。(实际上broker计算tps是非常简陋的,不是严格按照offset计算)接下来看一下线上真实的consumer tps变化:


2022-06-19 08:59:00 INFO - Stats In One Minute, SUM:148 TPS:2.47 AVGPT:1.01

2022-06-19 09:00:00 INFO - Stats In One Minute, SUM:826 TPS:13.77 AVGPT:1.01

2022-06-19 09:00:00 INFO - Stats In One Hour, SUM:6930 TPS:1.93 AVGPT:1.01

2022-06-19 09:01:00 INFO - Stats In One Minute, SUM:703 TPS:11.72 AVGPT:1.00

2022-06-19 09:02:00 INFO - Stats In One Minute, SUM:501 TPS:8.35 AVGPT:1.00

2022-06-19 09:03:00 INFO - Stats In One Minute, SUM:956 TPS:15.93 AVGPT:1.00

2022-06-19 09:04:00 INFO - Stats In One Minute, SUM:498 TPS:8.30 AVGPT:1.00

2022-06-19 09:05:00 INFO - Stats In One Minute, SUM:1663 TPS:27.72 AVGPT:1.01

2022-06-19 09:06:00 INFO - Stats In One Minute, SUM:2126 TPS:35.43 AVGPT:1.01

2022-06-19 09:07:00 INFO - Stats In One Minute, SUM:1912 TPS:31.87 AVGPT:1.01

2022-06-19 09:08:00 INFO - Stats In One Minute, SUM:1180 TPS:19.67 AVGPT:1.01

2022-06-19 09:09:00 INFO - Stats In One Minute, SUM:1633 TPS:27.22 AVGPT:1.01

2022-06-19 09:10:00 INFO - Stats In One Minute, SUM:1230 TPS:20.50 AVGPT:1.01

2022-06-19 09:11:00 INFO - Stats In One Minute, SUM:1848 TPS:30.80 AVGPT:1.00

2022-06-19 09:12:00 INFO - Stats In One Minute, SUM:1147 TPS:19.12 AVGPT:1.02

2022-06-19 09:13:00 INFO - Stats In One Minute, SUM:1665 TPS:27.75 AVGPT:1.04

2022-06-19 09:14:00 INFO - Stats In One Minute, SUM:1017 TPS:16.95 AVGPT:1.01

2022-06-19 09:15:00 INFO - Stats In One Minute, SUM:1478 TPS:24.63 AVGPT:1.01

2022-06-19 09:16:00 INFO - Stats In One Minute, SUM:1274 TPS:21.23 AVGPT:1.02

2022-06-19 09:17:00 INFO - Stats In One Minute, SUM:1371 TPS:22.85 AVGPT:1.04

2022-06-19 09:18:00 INFO - Stats In One Minute, SUM:1256 TPS:20.93 AVGPT:1.01

2022-06-19 09:19:00 INFO - Stats In One Minute, SUM:1189 TPS:19.82 AVGPT:1.01

2022-06-19 09:20:00 INFO - Stats In One Minute, SUM:1216 TPS:20.27 AVGPT:1.02

2022-06-19 09:21:00 INFO - Stats In One Minute, SUM:2558 TPS:42.63 AVGPT:1.01

2022-06-19 09:22:00 INFO - Stats In One Minute, SUM:2222 TPS:37.03 AVGPT:1.02

2022-06-19 09:23:00 INFO - Stats In One Minute, SUM:1616 TPS:26.93 AVGPT:1.01

2022-06-19 09:24:00 INFO - Stats In One Minute, SUM:1200 TPS:20.00 AVGPT:1.01

2022-06-19 09:25:00 INFO - Stats In One Minute, SUM:1087 TPS:18.12 AVGPT:1.06

2022-06-19 09:26:00 INFO - Stats In One Minute, SUM:564 TPS:9.40 AVGPT:1.01

2022-06-19 09:27:00 INFO - Stats In One Minute, SUM:236 TPS:3.93 AVGPT:1.02

2022-06-19 09:28:00 INFO - Stats In One Minute, SUM:1160 TPS:19.33 AVGPT:1.04

2022-06-19 09:29:00 INFO - Stats In One Minute, SUM:793 TPS:13.22 AVGPT:1.05

2022-06-19 09:30:00 INFO - Stats In One Minute, SUM:230 TPS:3.83 AVGPT:1.02

2022-06-19 09:31:00 INFO - Stats In One Minute, SUM:727 TPS:12.12 AVGPT:1.02

而在我测试顺序消费能力时如果

  threadNum<messageQueue,

发现1000条消息消费顺序变化为

  0-100左右无序排列,之后无限接近于101-996,  102-997,103-998,104-999

明显看出有部分队列发生饥饿,没有资源消费。

但是当我将pullThresholdForQueue设置为1,将无法复现这个情况。

关于饥饿的研究:

整个ConsumeRequest与pullRequest相当于一个生产者、消费者模型;他们共同持有的ProcessQueue对象(对象中维护一个读写锁、一个treeMap(消息对象数组),一个消费reentrantLock)。但是在DefaultMQpullConsumer的任务队列中


每个pullRequest只会拉pullbatchSize条消息,即32条,但是每个pullRequest在到达最大值前不间断启动。

那么假设最坏的情况

即第一个任务在工作过程中,之后的每一个队列都已经将message缓存完毕,那么最终线程池task队列最大数量等同于队列数量;

简化为一个thread多个queue的的模型,如果第一个ConsumerRequest只有一个messageExt对象;那么假设需要0.5秒消费完毕,而在这0.5s内,下一个pullRequest拉取了32个messageExt对象。即消费完第二个ConsumerRequest16秒后以Mq的发送速度完全可以让之后的每个ConsumerRequest缓存到达满值

此时存在四个ConsumerRequest,每个ConsumerRequest有pullThresholdForQueue条messageExt对象。

这样每pullThresholdForQueue条消息会按照顺序被消费者线程分别消费;如下图所示:

pullBatch一直是32,每个consumerRequest的数组长度最开始也的确是32,但是阻塞消费者线程时,每个consumeRequest的treemap将持有250条消息,并且只有四个task;



下一个节点来看consumerThread:

如果consumerThread小于线程池的任务数量,之后的task必然需要等待前面的任务执行完毕,hz13的一个jvm 消费线程只有5个,任务队列至少有16个任务。那么后续11个任务只能饥饿等待。

显而易见,从这64000条消息并不是 64000/64*0.5=500秒执行完毕;而是:

64000/20*0.5=1600秒=26.6分钟

才能执行完毕,而对于最后的ConsumerRequest乃至64000之后的消息都是二十多分钟显然有较大的影响。

PS:这里要分清楚两种对象,最后一个任务队列TreeMap里的头节点CR任务和尾结点CR任务;其实在这种场景下消息量超过64000后消费时间是恒定的,但是头节点和尾节点显然不是同一个时间进入队列的;即头节点的这个任务应该很早就被消费、但是因为线程资源问题、他只能等到最后、整体来看消费时间是不平滑的、是不公平的消费机制。

而我们显示在业务繁忙时刚好延迟半小时左右,理论符合计算值。

从这儿就可以解释之前的各种奇怪现象

解决方案:

必然要保证threadNum>=messageQueue,但是不能一刀切;

①:对延迟要求高的topic 增加threadNum

②:减小对延时要求不高的topic的messageQueue;(有个考虑是环境内所有的topic如果是都是64个队列,这对broker的cpu、内存资源消耗较大)

③:利用并发消费,并发消费task完全不依赖于队列数量,基本整体有序消费,不存在上述问题

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • 简介 /proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据...
    小蜗牛1218阅读 1,410评论 0 0
  • 常用语句: sql/plus sqlplus 'amdocs/Amdocs.Jx.China.110#@ysdb1...
    好好学习的蜗牛阅读 2,961评论 0 0
  • 一、常用日期函数 1. unix_timestamp:返回当前或指定时间的时间戳 select unix_time...
    无知小虾阅读 514评论 0 1
  • body { width: 35em; margin: 0 auto; font-famil...
    联旺阅读 274评论 0 0
  • Elasticsearch 7.x 简介 Elasticsearch是一个开源,基于Apache Lucene库构...
    方穹轩阅读 1,810评论 1 4