rtb的base性能要求是 ,处理时间100ms内,qps 2000

普遍测下来tps在2000+后,rtb的正常处理时间在1~3ms之间 (因为只需要做筛选判断逻辑,没有复杂计算) 但是偶尔会有一些处理时间会跳跃到40ms+ 猜测和gc策略有关,所以下面对主流的两种收集器进行了测试比对(因为测试数据组并不多,所以存在一些偏差,每个数据都是测了两组平均下来的,但是还是不可避免的误差比较大)

1.单机测试

每次测试50w组数据,tps 2500-2700左右(压测线程在200)

2G堆内存 4G堆内存

20ms >30ms >50ms >20ms >30ms >50ms
并行收集器(ps收集) 14493 9486 3655 17405 11963 4785
并发收集器(parnew+cms) 18507 13439 6311 15264 11155 5141

测试结果初步看起来是 小内存会比大内存处理起来更优秀,尽管更频繁触发gc,但是处理时间短,是在容忍范围之内的.单机情况下 小内存并行收集器是最优的,但是考虑到 测试数据总量少(一共50w)不排除在量上来后major gc会消耗更多的时间。另外其实暂时看起来差别不是特别大,所以下面采取小内存集群测试查看优化空间

2.集群测试(4台server)

每次测试50w组数据,tps在3700(压测线程在200)

重启后压测

2G堆内存

30ms >40ms
并行收集器(ps收集) 7929 4918
并发收集器(parnew+cms) 7032 3715

每次测试50w组数据,tps在2300(压测线程在40)

重启后压测

2G堆内存

30ms >40ms
并行收集器(ps收集) 没统计 没统计
并发收集器(parnew+cms) 1084 671

一段时间之后压测

2G堆内存

30ms >40ms
并行收集器(ps收集) 357 206
并发收集器(parnew+cms) 288 219

可以看到,在集群环境下,对原来2000+的tps要求处理起来已经压力不大,只有少量延迟超标,两种收集器都比较优秀,因为测试数据量并不够大,所以没太大区别。另外重启之后不久就执行和 一段时间之后再执行差别明显,java在code cache做的处理优化 会让后面执行的 处理起来更快一些。

另外由于最后的结果在预期之内(99.9%+的响应率)所以最后采用CMS收集器(处理老年代更优秀一些)

最后的配置参数是

-Xms2048m -Xmx2048m 初始化堆和最大堆2G

-Xmn512m 年轻代大小

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC 年轻代parnew 老年代cms 策略

-XX:+CMSClassUnloadingEnabled 允许收集永久代

-XX:+CMSScavengeBeforeRemark 在majorgc前进行一次young gc,这样提高整个gc效率

-XX:+DisableExplicitGC 不允许System.gc()

-XX:+MaxTenuringThreshold=15 年轻代在被收集了多少次后进入老年代,加大之后增加了进入老年代的难度(据说只在串行收集中生效,先配上吧,后面再观察)

-Xss128k 线程栈大小(配小了可以多启一下线程,因为rtb用到几个线程池,配小了减少线程压力)

-XX:+CMSParallelRemarkEnabled 降低标记停顿

附测试中并行收集器的参数

-server -Xms1024m -Xmx1024m -XX:MaxPermSize=320m -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=16 -XX:MaxGCPauseMillis=25 -XX:+UseAdaptiveSizePolicy -XX:+DisableExplicitGC -Xloggc:/app/GD3.0/rtb/current/logs/gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:MaxTenuringThreshold=15

其中几个参数

-XX:ParallelGCThreads=16 配置并行收集的线程数(这里=cpu core size)

-XX:MaxGCPauseMillis=25 配置每次收集阀值,jvm根据此值会自动调整年轻代大小

另外详细的jvm启动参数可以参见http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html

另附淘宝使用的启动参数配置 (可以对照上面链接解释各个参数的意思)

-Xms4g -Xmx4g -XX:PermSize=256m -XX:MaxPermSize=256m -Xmn2000m -XX:SurvivorRatio=10 -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:+CMSParallelRemarkEnabled -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=82

linkedin的
// JVM sizing options
-server -Xms40g -Xmx40g -XX:MaxDirectMemorySize=4096m -XX:PermSize=256m -XX:MaxPermSize=256m
// Young generation options
-XX:NewSize=6g -XX:MaxNewSize=6g -XX:+UseParNewGC -XX:MaxTenuringThreshold=2 -XX:SurvivorRatio=8 -XX:+UnlockDiagnosticVMOptions -XX:ParGCCardsPerStrideChunk=32768
// Old generation options
-XX:+UseConcMarkSweepGC -XX:CMSParallelRemarkEnabled -XX:+ParallelRefProcEnabled -XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSInitiatingOccupancyOnly
// Other options
-XX:+AlwaysPreTouch -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime -XX:-OmitStackTraceInFastThrow

野路子:
-Dfile.encoding=UTF-8 -J-server -Xms10000M -Xmx10000M -Xmn5000M -XX:MaxTenuringThreshold=1 -XX:SurvivorRatio=30 -XX:TargetSurvivorRatio=50 -Xnoclassgc -Xss256K -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=80 -XX:ParallelGCThreads=24 -XX:ConcGCThreads=24 -XX:+CMSParallelRemarkEnabled -XX:+CMSScavengeBeforeRemark -XX:+ExplicitGCInvokesConcurrent -XX:+UseTLAB -XX:TLABSize=64K

最后附上一段主流收集器的 简要介绍以及默认使用情况

http://blog.csdn.net/java2000_wl/article/details/8030172

« Java并发编程:Callable、Future和FutureTask Codis-安装篇 »