对存疑部分编写了代码进行测试。测试结果果然如推测所想。测试结果如下:
场景 |
写入 |
读取 |
大小 (单位) |
CPU |
||||
次数 |
时间 |
平均 |
次数 |
时间 |
平均 |
|||
本地缓存 |
10000 |
0.03125 |
0 |
10000 |
0 |
0 |
1k |
0 |
MemClient |
10000 |
19.2656 |
0.001926 |
10000 |
22.75 |
0.002275 |
1k |
|
Json1k |
1000 |
2.8437 |
0.002843 |
1000 |
5.375 |
0.005375 |
1k |
|
Json8k |
1000 |
3.8593 |
0.003859 |
1000 |
29.0312 |
0.029031 |
8k |
|
直播1000人次 |
1000 |
38.9375 |
0.038937 |
1000 |
|
|
50k |
|
直播8000人次 |
100 |
18.25 |
0.1825 |
100 |
|
|
350k |
|
500k |
100 |
7.375 |
0.07375 |
100 |
7.09375 |
0.070937 |
500k |
|
场景 |
写入 |
读取 |
大小 (单位) |
CPU |
||||
次数 |
时间 |
平均 |
次数 |
时间 |
平均 |
|||
本地缓存 |
10000 |
0.03125 |
3.125E-06 |
10000 |
0.015625 |
1.5625E-06 |
1k |
0 |
MemClient |
10000 |
19.78125 |
0.001978 |
10000 |
21.953125 |
0.002195 |
1k |
|
Json1k |
1000 |
2.03125 |
0.002031 |
1000 |
6.078125 |
0.006078 |
1k |
|
Json8k |
1000 |
2.765625 |
0.002765 |
1000 |
55.375 |
0.055375 |
8k |
|
直播1000人次 |
1000 |
38.53125 |
0.038531 |
1000 |
|
|
50k |
|
直播8000人次 |
100 |
17.96875 |
0.179687 |
1000 |
|
|
350k |
|
500k |
100 |
7.5 |
0.075 |
100 |
6.5625 |
0.065625 |
500k |
|
场景 |
写入 |
读取 |
大小 (单位) |
CPU |
||||
次数 |
时间 |
平均 |
次数 |
时间 |
平均 |
|||
本地缓存 |
10000 |
0.015625 |
1.5625E-06 |
10000 |
0.015625 |
1.5625E-06 |
1k |
0 |
MemClient |
10000 |
18.015625 |
0.001801 |
10000 |
25.96875 |
0.002596 |
1k |
6% |
Json1k |
1000 |
1.15625 |
0.001156 |
1000 |
3.078125 |
0.003078 |
1k |
40% |
Json8k |
1000 |
1.859375 |
0.001859 |
1000 |
32.484375 |
0.032484 |
8k |
50% |
直播1000人次 |
1000 |
45.046875 |
0.045046 |
1000 |
|
|
50k |
30-40% |
直播8000人次 |
100 |
31.703125 |
0.317031 |
100 |
|
|
350k |
50% |
500k |
100 |
7.0625 |
0.070625 |
100 |
6.421875 |
0.064218 |
500k |
6% |
直播1000人次(当天一共有1000人访问,数据来源于运营检测),留言内容为30条时,Room体积大概为:57K
直播1000人次(当天一共有8000人访问,数据来源于运营检测),留言内容为30条时,Room体积大概为:350k
根据图表可以看到以下情况:处理时间、CPU利用率和数据量大小,序列化,类复杂性都有关系。
序列化问题(类型转换)对性能影响最为明显(可在场景”json1k”、场景直播中看到)。在Json1k中,存储对象和前几个场景是相同的,处理时间也相差不大,较大区别是CPU利用率由5%左右增长到40%左右(反序列化时尤为明显)。在场景直播系统中,不存在序列化问题,但是其对象属性中存在”访客”, ”繁衍”等多个复杂对象,造成其在处理时需要处理过多的类型转换,同时其体积不断增大。
存储对象的大小和处理时间存在一定关系,例如场景”500k”,其处理时间增长,但是其CPU利用率并未提高,其时间增长是由于对象传输造成。
本地缓存在内存中进行寻址和类型转换,涉及不到Socket连接,网络传输,序列化操作,所以其处理相当快。
就测试结果看:
本地缓存性能大约是分布式缓存性能的100倍左右。而出问题的聊天室除了CPU增高以外,其性能更比分布式缓存再降低40倍(直播1000人次)到200倍(直播8000人次)。综合来看,聊天室的分布式缓存比本地缓存降了4000倍,甚至更多。
但是,还没有完。
对于第二个问题,更改类设计,清楚无效访客,即可解决。
但是第一个问题,为什么用户在存储之前,先进行json序列化呢?嗯,这是一个问题。
遂问之。
答曰,有些类直接使用第三方客户端存储时,直接存储报错,所以先序列化为json类型,取值时再反序列化回来。
嗯,还有这事?
开发人员说了相关代码。
他说:Game对象在直接使用memCachedClient时,是不能被二进制序列化的,因为其User属性类型为IUser,为一个接口。因此想了一个解决方法,即先将Game对象进行 json序列化将其变为字符串,然后将字符串存储到memCached。
原来是这样。
接着又查看了memCachedClient源代码,其需要将对象进行二进制序列化,然后进行存储。接口属性不能被序列化,遂又对序列化问题进行了测试(见附件)。测试结果显示上述代码直接进行二进制序列化是可以的,同时直接使用第三方客户端也是可以可行的。
问题出在哪?难道是没有加[Serializable]。
一查果然:一个Serializable引发的血案。。。
记得有人说过,慎用分布式,能不用尽量不用。
一方面在性能上确实下降很多,分布式存储主要性能消耗在以下几个方面:协议解析,Socket连接,数据传输,序列化/类型转换。
一方面在使用场景和类设计上要求也更加严格。个人认为memCached是不太适合存储特别大的文件的。虽然有人说网上已经有用来存储视频的。
还有几个问题希望知道的朋友回答下:
1 有没有.Net方面的memCached客户端支持二进制协议和一致性的?
2 测试中发现,当memCached设置缓存过小时(例如64M),当其内存使用已经到62M时,再进行存储,新存储的内容再取出来就是空值,不知道是什么原因。
文章中用到的源码:下载源码
原文链接:http://www.cnblogs.com/hellofox2000/archive/2010/08/17/1801329.html