单机100k并发调优

最近事情有点多,2019年的时间进度条已经过半,,更新不及时,以后还是得坚持两周一篇

背景

最近在做一件事情,通过tpcc客户端压测一下数据库,tpcc (前段时间阿里oceanbase夺得性能全球第一)公认的数据库压测工具,该客户端采用的是java,
内部嵌套jdbc。我们想实现对多个db分库同时压测,原先的tpcc已经不能满足我们的场景,我们做了多连接,tpcc客户端同时和多个db保持多条连接.我们发现
当想要实现单机100k连接,发现很难,所以开始想着开多个客户端最后汇总收集。但是,机器资源有富余,为什么不能?

WX20191019-083251.png

认真的优化之路

  • 首先,我们先开启100k的连接线程,将业务操作全部干掉,尽量减少资源浪费
  • 其次,我们把已知的参数调整到最大,诸如jvm 参数,操作系统句柄数,还有tcp 参数

JVM 参数 xms40g xmx40g xss256k

  1. 在jdk1.8中xss
    默认是1M,那我们为了尽量减少内存使用,我们使用比较低的设置256k,单线程256k*100k=25600M=25g,所以我们参数xmx要调整的高,当然这是我们初始设定
  2. 操作系统句柄数建议openfiles弄个很大的值,修改完后,ulimit -a查看一下
  3. 调整tcp参数的意义在于让单次连接效率更高
  • 接着,当我们做好这些,准备跑的时候启动到3w并发时候挂了。。。

WX20191019-084213.png

OOM 了,之前遇到的oom,三类

  1. heap space (最常见,增大内存使用就行)
  2. perm space(1.8后使用metaspace)
  3. gc overhead limit exceeded(查看gc使用)

这一下有点懵,stackoverflow 上搜了下

1
2
3
4
5
6
ulimit -s 256 ulimit -i 120000
echo 120000 > /proc/sys/kernel/threads-max
echo 600000 > /proc/sys/vm/max_map_count
echo 200000 > /proc/sys/kernel/pid_max
永久生效使用 sysctl -p 一下
在其他资源可用的前提下,单个JVM能开启的最大线程数是/proc/sys/vm/max_map_count的设置数的一半
  • 修改了配置后,过了一会后,发现又跪了,错误信息是关于memory overcommit的,
    这一次查看了一下系统资源
1
2
3
4
5
6
7
8
9
grep -i commit /proc/meminfo

看到CommitLimit和Committed_As参数。

CommitLimit是一个内存分配上限,CommitLimit = 物理内存 * overcommit_ratio(默认50,即50%) + swap大小

Committed_As是已经分配的内存大小。**(这个值已经超过了commitlimit)**

overcommit_memory参数就是控制分配内存是否可以超过CommitLimit,默认是0,即启发式的overcommitting handle,会尽量减少swap的使用,root可以分配比一般用户略多的内存。1表示允许超过CommitLimit,2表示不允许超过CommitLimit。

将db重启后修复

  • 继续前行,起来之后又报了个错

WX20191019-084114.png

这一次是socket
建立失败,我们看了下db日志,结果啥都没有,jdbc那里加上日志db的端口和ip也正常,这就很茫然了,我们继续看启动的线程数,当跑了多次之后发现,每次总在51072线程的时候,崩掉
我们想了下,每个机器能开的端口就是65536个,因为tcp报文16bit来表示端口,所以这个是改不了了,这下完蛋了。

仔细一想,不对啊,两个db,每个5w端口怎么着都够了啊,netstat -nao|grep
ESTABLISHED,发现确实最高到6w多就崩了,于是调整参数

1
2
net.ipv4.ip_local_port_range =  40000 65535
#表示用于向外连接的端口范围。缺省情况下很小:32768到61000,后来改为10000到65535。

当我们调整完后,好了,我们再回过头来看为什么到51072线程时候挂了呢,经分析是
(65536-40000)*2(两个db)= 51072

至此,100k并发,已经彻底满足,当然1000k并发需要增加db数也是可以玩起来的

那今天先聊到这,休息下眼睛

15d11.jpg

坚持原创技术分享,您的支持将鼓励我继续创作!