首页 > 其他分享 >京东热key探测框架本地压测数据记录,单机(8核)QPS约16万/s,可水平扩展

京东热key探测框架本地压测数据记录,单机(8核)QPS约16万/s,可水平扩展

时间:2023-02-05 21:31:15浏览次数:43  
标签:16 worker 线程 key QPS cpu 测数据


继上一次全链路压测时,热key框架由于Java低版本(1.8.0_131之前的1.8版本)获取docker内cpu核数有问题,实则获取的是宿主机的核数,造成线程数量过多,压测瞬间cpu达到100%,问题也记录在了​​另一篇​​(​​javascript:void(0)​​)。后来找到了问题原因,并成功修复了。然后还修改了一些其他的小问题,总体感觉框架比较稳定了。我就自己做了一些性能方面的压测,分别先后使用了4台、8台、16台、32台机器作为压力源,用死循环发送热key消息的方式,测试worker集群的性能,worker分别使用了8核、16核两种规格,数量都是2台,机器都是部署在docker内的。

首先说一下,我写的热key框架文章没有讲前因后果,会显得比较突兀。所以简单解释一下,worker端是一个Java程序,里面是一个netty server,用来接收来自于后端服务集群发来的字符串,然后对字符串进行归并,对相同的字符串数量进行累加,超过一定阈值的字符串,判定为热key,然后通过netty推送给这些后端服务集群。好比一个用户是个爬虫,他的userId=123456,他一直不停地访问后端集群,那么后端就会陆续把这个userId发往worker集群,worker对这个字符串的频率次数进行累加,譬如超过了设定的2秒10次就算爬虫,超过后worker集群就会把这个key推送给所有的后端服务,然后后端服务会记录到自己内存里,之后就可以对这个热key做操作了,譬如禁止他访问相关接口,做限流等等。

所以,这个worker也就是netty server它的性能就至关重要,后端集群每秒发过来或者几万、几十万、几百万个key信息,我就需要得到worker单机的QPS性能,然后根据实际的量来决定开多少个worker机器,worker是可以水平扩展的。

worker内部是使用netty单线程的bossGroup和cpu核数个workGroup,work接收到消息后自己不处理,全部写入到disruptor内,disruptor是200万的bufferSize,disruptor的消费者也是cpu核数个线程,每个线程只处理特定的key(即hash后取余分到消费者线程)。理论上消费的速度即是该应用的QPS。所以我通过反复调节线程数,缓存量等维度来测试性能表现。

之前老是有人抄我文章,到处乱发,还不注明出处。

来看一下测试过程:

8核8G单机性能表现

worker端是固定2台机器,我用了2台8核8G的,压力机用了4台4核的,代码很简单就是死循环里netty发消息,让worker的netty server来接收并处理。netty server端我做了数量的统计,分别在接收到消息时变量totalReceiveCount数量加1,然后在数量处理完毕的地方totalDealCount加1。

很明显,接收的速率肯定是大于处理的速率的,接收到了没处理肯定是不算QPS的,当然处理的过程也很简单,就是内存计数累加,超过阈值就推送。

京东热key探测框架本地压测数据记录,单机(8核)QPS约16万/s,可水平扩展_京东热key框架

京东热key探测框架本地压测数据记录,单机(8核)QPS约16万/s,可水平扩展_京东中间件_02

我每10秒打印一次接收的数量和处理过的数量,如图

京东热key探测框架本地压测数据记录,单机(8核)QPS约16万/s,可水平扩展_热key探测_03

 

京东热key探测框架本地压测数据记录,单机(8核)QPS约16万/s,可水平扩展_字符串_04

从日志情况来看,每10秒大概处理了160万个key信息,接收量也差不多是160万,也就是基本上接收到的都被处理了,不存在明显的卡顿阻塞。这是单机的情况,两台机器情况是一致的。也就是两台每秒30多万QPS的样子。cpu占有率在70以上,但没有被打满。当前的cpu占用原则上已达到极限,故我们认为8核的单机QPS在16万。

16核单机性能表现

压力源不变,还是每10秒160万个key。

京东热key探测框架本地压测数据记录,单机(8核)QPS约16万/s,可水平扩展_京东中间件_05

从日志上看,16核机器也是每10秒160万比较平稳,接收量和处理量保持一致。

京东热key探测框架本地压测数据记录,单机(8核)QPS约16万/s,可水平扩展_热key探测_06

cpu使用率明显是要比8核的小的多,大概在30%左右。说明在压力源保持不变的情况下,处理端的吞吐量是恒定的,核数多了,相应的只是cpu占用小一些。

16核单机调大线程数后性能表现

随后我把16核机器程序内处理消息的线程数调大一倍,从核数*1个线程,变成核数*2个线程,也就是变成了32个线程,日志如下,发现其实并没有什么变化,甚至有逐步下降的趋势。

京东热key探测框架本地压测数据记录,单机(8核)QPS约16万/s,可水平扩展_京东中间件_07

原因也很明显,这是cpu密集型的应用,单核单线程处理的应该会更快,因为避免了cpu轮转切换,加大线程数并没有实际意义,如果线程过多,甚至导致性能下降。

我又恢复了16个线程,然后加大了disruptor的bufferSize,原来是200万,改成了1600万,同时将内存从16G加大到32G,大幅调大了JVM的新生代和老年代内存,同样是没什么鸟用,除了大幅增加了yong GC的耗时,其他的什么好处也没有。因为200万完全够用了,接收速率并没有比处理速率快很多,产生不了几百万的差距。

京东热key探测框架本地压测数据记录,单机(8核)QPS约16万/s,可水平扩展_字符串_08

京东热key探测框架本地压测数据记录,单机(8核)QPS约16万/s,可水平扩展_京东热key框架_09

cpu倒是比内存小时占用更多了,有突破40%的趋势,主要还是因为gc时耗时大、耗cpu也高了。所以还是恢复了200万的bufferSize。

加大压力源后16核单机性能表现

之后我不断加大压力源,从4台到8台又到30台4核4G的。

京东热key探测框架本地压测数据记录,单机(8核)QPS约16万/s,可水平扩展_netty性能_10

可能是我压力源的死循环写的问题,导致压力源自身的发送量迟迟上不去,所以到worker接收端这边,也只是到了10秒200万的水平,看处理量,也是20万/s的样子。

京东热key探测框架本地压测数据记录,单机(8核)QPS约16万/s,可水平扩展_京东热key框架_11

worker端cpu的使用率也达到了50%。从16万/s的35%cpu到20万/s的50%。处理量和cpu的增长还算同步,但性价比其实不算高了。

在实际生产中,单机能到10万的QPS已经算是比较高的场景了,如果不够用,最好还是加个机器以分担峰值。

总结:该框架单机8核16万QPS,处于够用的状态,实际上netty server最高能处理多少,我也不清楚,没有相关的参考标的。如果能远远大于目前我的这个处理速率,可能是我程序写的不够完善。实际生产中如果量级不大,建议8c8g的机器再根据实际情况水平扩容。如果量级有突发特别密集的不确定因素存在,考虑上16核机器,毕竟16核在20万QPS时,cpu也才50%。上限远远大于8核的。

标签:16,worker,线程,key,QPS,cpu,测数据
From: https://blog.51cto.com/u_13706148/6038486

相关文章

  • 163-cas-server5.3 在idea运行的tomcat运行
    下载cas-overlay-template,https://github.com/apereo/cas-overlay-template.git下载分支5.3。其他分支本地暂时无法编译通过。下载完成后,直接运行:mvncleanpackage......
  • 【ABC162E】Sum of gcd of Tuples (Hard)
    updon2022-7-13:修改若干不合适叙述。一、题意很明了,给出\(n,k\),求下面这个复杂式子的值:\[\sum_{a_1=1}^k\sum_{a_1=1}^k\cdots\sum_{a_{n-1}=1}^k\sum_{a_n=1}^k\gc......
  • 【UVA1645】Count
    找递推式。设\(f_i\)为\(i\)个节点的满足要求的树的数量,由于同一深度下每个节点子树相同,那么也就是说,根节点的若干个儿子都要分到同样的节点数。设总共有\(m\)个儿......
  • CF1691D
    MaxGEQSum-洛谷|计算机科学教育新生态(luogu.com.cn)思维+单调栈+数据结构好题所有(i,j)都符合max(a[i],a[i+1],a[i+2],⋯,a[j]) ≥a[i]+a[i+1]+a[......
  • P2016题解
    P2016题解题目描述Bob要建立一个古城堡,城堡中的路形成一棵无根树。他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能瞭望到所有的路。注意,某个士兵在一个结点上时......
  • CF1666K Kingdom Partition 题解
    神仙网络流题。Description传送门Solution考虑最小割,将每个点\(u\)拆成\(L_u,R_u\)两个点。对于每一条原图中的边\((u,v,w)\),连双向边\((L_u,R_v,w),(L_v,R_u,w)......
  • 通过matlab对比不同调制方式下的球形译码误码率仿真,包括BPSK,QPSK,8PSK,4QAM以及16QA
    1.算法描述 在BLAST检测中,目前采用的ZF(迫零)算法,MMSE(最小均方误差)算法,OSIC(排序连续干扰抵消)或ML(最大似然)准则来进行译码。前三种算法,实现起来较简单,但是......
  • PTA 1016 phone bills(把复杂的信息进行打包分类,把对象挑出来单个击破就容易解决的啦。
    #include<stdio.h>#include<stdlib.h>#include<string.h>structrecord{charname[25],time[15],flag[10];inttollTime,onOff;};structcustomers{i......
  • gomonkey不生效
    gomonkey作用在运行时把原函数地址替换为目标函数地址go.modrequiregithub.com/agiledragon/gomonkey/v2v2.3.0a.gopackagemaintypeAstruct{}func(aA)get......
  • 每日一道思维题——CF1691C - Sum of Substrings
    题意:给定一个长度为n的字符串算由SiSi+1构成的子字符串值如00为0,01为1,10为10,11为11F(s)为所有值之和求出此值的最小值思路:优先将1放到最后,其次将1放在开头其余的位置......