一些猜想:
MCache的基本概念是对象引用在堆内,对象序列化之后存到堆外。可能存在问题:
1、directmemory将对象存在堆外,涉及到对象在堆内与堆外内存之间的的拷贝,对性能有影响。这一点前面通过调整测试对象的大小对QPS的影响己经初步显现,但是在一般的应用场景下,QPS能到10W左右,这里不会成为瓶颈;
2、序列化与反序列化对性能的影响。这个点预计会对CPU消耗比较大,需要单独优化:
a)特定场景直接使用byte数组,避免序列化与反序列化开销;
b)采用一种高效的序列化策略,准备对比:protobuf与protostuff的情况;
3、堆内中间对象对诱发的GC对性能的影响。这个点会存在,优化的方向:
a)尽可能减少中间对象,使用基本类似,优化对象大小等等。但是只能一定程序上减少GC频率;
b)对GC调优,存储对象采用有效期,GC需要对过期的对象进行清理。首先有效期时长就需要有平衡策略,直接影响对象生命周期和JVM中对象数,最主要会影响缓存命中率。其次,调整GC代的分配比例,如果多数中间对象能在Eden区或Surv区完成生命周期,那FullGC势必会降低,又或者,调大Old的大小,如果有效期30分钟,Old能容下1-2小时的对象,那也可以接受了。再次,考虑采用CMS分散GC对应用暂停的时长;
4、内存泄漏问题。directmemory因不在heap中,GC无法涉及,direct的回收时机是DirectByteBuffer对象被GC时释放本地内存,没有触发GC就可能出现OOM了。在我们的应用中direct会预分配好,运行时不再涉及到分配与回收的问题,也就是说ByteBuffer是一直在Old中的,因而理论上不会产生泄露的情况;
5、内存分片均衡策略的有效性。MCache采用根据运行时反馈对分片容量以Page为单位作自动调整,采用一种跟memcached很相似的算法,经过几次测试,还是比较有效的,好钢都往刀刃上移动。
机器配置:
Summary:Unknown,4xXeonE55202.27GHz,7.3GB
System:Unknown
Processors:4xXeonE55202.27GHz
Memory:7.3GB
Network:eth0:00:16:3e:e8:15:81
OS:RHELServer5.4(Tikanga),Linux2.6.18-164.el5xenx86_64,64-bit
用例条件:
对象大小在128byte~500k之间随机,key在0~1000000随机,过期时间3s,并发线程数5个.
curl“localhost:8088/perf.do?method=mcache×=90000000000&min=128&max=502400&key=1000000&expire=3000&threads=5″
MCache配置:
mcache.capacity.total=860m//总direct内存
mcache.capacity.page=1m//分片大小
mcache.capacity.chunk=512//最小块大小
mcache.factor=2//块增长因子
堆分区:
Eden340m,Surv3m,Old700mPerm130m,GC:CMS详见前一篇。
通过几次测试,MCache和QPS、GC、CPU等都比较稳定在一个范围内(如下图),接下来将调整GC策略。
OldGC:
topload基本稳定在5:
top�C14:48:38up273days,16:12,4users,loadaverage:5.34,5.21,5.35
Tasks:114total,1running,112sleeping,0stopped,1zombie
Cpu(s):78.4%us,1.8%sy,0.0%ni,19.7%id,0.0%wa,0.0%hi,0.0%si,0.2%st
Mem:7680000ktotal,6732512kused,947488kfree,800864kbuffers
Swap:2096472ktotal,92kused,2096380kfree,3339640kcached
PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND
8455dafu2002360m1.9g11mS320.125.7250:17.07java
QPS相关数据:
12/04/0614:39:27get:36334put:978hit:97.31%qps:18112avgtime:0
12/04/0614:39:29get:40511put:970hit:97.61%qps:19975avgtime:0
12/04/0614:39:31get:38543put:1006hit:97.39%qps:19175avgtime:0
12/04/0614:39:33get:37736put:994hit:97.37%qps:15915avgtime:0
12/04/0614:39:35get:38849put:1141hit:97.06%qps:19213avgtime:0
12/04/0614:39:37get:42149put:1003hit:97.62%qps:20752avgtime:0
SLAB均衡情况
slot:0chunksize:4096perslab:2freechunk:158573inusechunk:3219evicted:0
slot:1chunksize:2048perslab:2freechunk:68422inusechunk:4282evicted:0
slot:2chunksize:1024perslab:2freechunk:27502inusechunk:8534evicted:0
slot:3chunksize:512perslab:2freechunk:1126inusechunk:16904evicted:0
slot:4chunksize:8832perslab:69freechunk:0inusechunk:9074evicted:24266
slot:5chunksize:4544perslab:71freechunk:0inusechunk:4544evicted:55718
slot:6chunksize:2272perslab:71freechunk:0inusechunk:2272evicted:109926
slot:7chunksize:1184perslab:74freechunk:0inusechunk:1216evicted:263250
slot:8chunksize:808perslab:101freechunk:0inusechunk:1198evicted:495395
slot:9chunksize:1224perslab:306freechunk:0inusechunk:2095evicted:858828
slot:10chunksize:316perslab:158freechunk:0inusechunk:1186evicted:1281537
slot:11chunksize:2perslab:2freechunk:71inusechunk:0evicted:0
通过jmap将heapdump,观察:
参考:
http://www.kdgregory.com/index.php?page=java.byteBuffer
http://code.google.com/p/gperftools/downloads/list?redir=1