MemCached 压力测试-eddie -JavaEye技术社区

来源:百度文库 编辑:神马文学网 时间:2024/06/05 08:17:28
MemCached 压力测试
关键字:   MemCached
MemCached安装完成后,进行了压力测试,主要参考了MemCached的javaclient的 类com.danga.MemCached.test.MemCachedTest。它的类主要问题是没有一个总的处理能力的描述。我进行了改写,提供了get和put的总吞吐量的汇总。
测试环境如下,
服务器:RedHat9, 512内存,P4内存,跑2个MemCached实例,运行memcached-1.2.1
客户端:单独一台机器,和服务器在一个局域网,100M网络带宽,运行java_memcached-release_1.5.1, jdk5.0
测试代码:
java 代码
import com.danga.MemCached.MemCachedClient;    import com.danga.MemCached.SockIOPool;       public class TestMemCache {        static SockIOPool pool;           static int threads; // 运行的测试线程数           static int runs; // 每个线程运行的次数           static int size; // 设置到memcache中的数据包大小,单位k           static Integer myLock;// 锁定以下计数器           static long putTimes = 0; // put总时间,单位微秒           static long getTimes = 0; // get总时间,单位微秒           /**        * @param args        */       public static void main(String[] args) {            String[] serverlist = { "192.168.0.56:11211", "192.168.0.56:11212" };               // initialize the pool for memcache servers            pool = SockIOPool.getInstance();            pool.setServers(serverlist);               pool.setInitConn(5);            pool.setMinConn(5);            pool.setMaxConn(50);            pool.setMaintSleep(30);               pool.setNagle(false);            pool.initialize();               if (args.length < 3) {                System.out.println("用法:TestMemCache 启动线程数 每线程执行测试数量 测试数据大小(k)");                System.exit(1);            }               threads = Integer.parseInt(args[0]);            runs = Integer.parseInt(args[1]);            size = 100 * Integer.parseInt(args[2]);               myLock = new Integer(threads);               for (int i = 0; i < threads; i++) {                Thread thread = new WorkerThread();                thread.start();            }        }           private static class WorkerThread extends Thread {               // 构造函数            WorkerThread() {            }               public void run() {                // get client instance                MemCachedClient mc = new MemCachedClient();                   mc.setCompressEnable(false);                mc.setCompressThreshold(0);                   // get object to store                int[] obj = new int[size];                for (int i = 0; i < size; i++) {                    obj[i] = i;                }                   String[] keys = new String[runs];                for (int i = 0; i < runs; i++) {                    keys[i] = "test_key" + i;                }                   for (int i = 0; i < runs; i++) {                    mc.delete(keys[i]);                }                   long startTime = System.currentTimeMillis();                for (int i = 0; i < runs; i++) {                    mc.set(keys[i], obj);                }                long time = System.currentTimeMillis() - startTime;                   synchronized (myLock) {                    putTimes += time;                }                   startTime = System.currentTimeMillis();                for (int i = 0; i < runs; i++) {                    mc.get(keys[i]);                }                time = System.currentTimeMillis() - startTime;                   synchronized (myLock) {                    getTimes += time;                    myLock--;                       if (myLock.equals(0)) {                        System.out.println("测试完成! 启动线程数:" + threads                                + ", 每线程执行测试数量: " + runs + ", 测试数据大小(byte):" + size);                           System.out.println("put处理时间:" + putTimes                                + "微秒,处理put速度: 每秒 " + runs * threads * 1000 / time                                + " 次");                        System.out.println("get处理时间:" + getTimes                                + "微秒,处理get速度: 每秒 " + runs * threads * 1000 / time                                + " 次");                           pool.shutDown();                    }                }            }        }       }
测试结果:
测试完成! 启动线程数:1, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:2515微秒,处理put速度: 每秒 789 次
get处理时间:1266微秒,处理get速度: 每秒 789 次
测试完成! 启动线程数:2, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:3595微秒,处理put速度: 每秒 1471 次
get处理时间:2734微秒,处理get速度: 每秒 1471 次
测试完成! 启动线程数:3, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:6250微秒,处理put速度: 每秒 1846 次
get处理时间:4829微秒,处理get速度: 每秒 1846 次
测试完成! 启动线程数:4, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:8673微秒,处理put速度: 每秒 2063 次
get处理时间:7858微秒,处理get速度: 每秒 2063 次
测试完成! 启动线程数:5, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:10655微秒,处理put速度: 每秒 2352 次
get处理时间:10625微秒,处理get速度: 每秒 2352 次
测试完成! 启动线程数:6, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:14702微秒,处理put速度: 每秒 2042 次
get处理时间:16844微秒,处理get速度: 每秒 2042 次
测试完成! 启动线程数:7, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:18766微秒,处理put速度: 每秒 2502 次
get处理时间:20265微秒,处理get速度: 每秒 2502 次
测试完成! 启动线程数:8, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:23828微秒,处理put速度: 每秒 2586 次
get处理时间:25062微秒,处理get速度: 每秒 2586 次
测试完成! 启动线程数:9, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:29515微秒,处理put速度: 每秒 2654 次
get处理时间:31141微秒,处理get速度: 每秒 2654 次
测试完成! 启动线程数:10, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:37780微秒,处理put速度: 每秒 2285 次
get处理时间:42876微秒,处理get速度: 每秒 2285 次
没有测试下去了,看来8~9个线程效率最高,服务端测试的时候,CPU一直使用率很低,最多到5%.
以上测试结果最多到了2500左右,但有位朋友的测试结果非常惊人,一个线程都超过了3300和4800的处理量,他的传输数据量小点,只有0.1k,我测试了下,用这个数据量,顶多也是到3000多的并发。他的测试结果请看如下网址:
 http://hi.baidu.com/jabber/blog/category/Memcached
最后更新:2007-05-18 13:39
18:03  |  永久链接  |   浏览 (702)  |  评论 (5)  |   收藏  |  MemCached  |  进入论坛  |
永久链接
http://eddie.javaeye.com/blog/77560
评论    共 5 条发表评论
rtdb     2007-05-07 19:25
我认为你这个测试,数据处理速度应当是受限于网络,
线程数量则是受限于客户机,
没有测试到SERVER的性能。
eddie     2007-05-08 10:11
rtdb 写道
我认为你这个测试,数据处理速度应当是受限于网络,
线程数量则是受限于客户机,
没有测试到SERVER的性能。
我们的局域网就这速度,没办法。客户端应该没啥限制的,我的客户机是个IBM笔记本,配置还可以,1.5G内存,双核CPU。
 
iunknown     2007-05-17 00:48
引用
#
# System.out.println("put处理时间:" + putTimes
# + "微秒,处理put速度: 每秒 " + runs * threads * 1000 / time
# + " 次");
# System.out.println("get处理时间:" + getTimes
# + "微秒,处理get速度: 每秒 " + runs * threads * 1000 / time
# + " 次");
 
runs * threads * 1000 / time
这个怀疑是写错了吧?应该分别是
runs * threads * 1000 / putTimes
runs * threads * 1000 / getTimes
eddie     2007-05-17 09:37
iunknown 写道
引用
#
# System.out.println("put处理时间:" + putTimes
# + "微秒,处理put速度: 每秒 " + runs * threads * 1000 / time
# + " 次");
# System.out.println("get处理时间:" + getTimes
# + "微秒,处理get速度: 每秒 " + runs * threads * 1000 / time
# + " 次");
 
runs * threads * 1000 / time
这个怀疑是写错了吧?应该分别是
runs * threads * 1000 / putTimes
runs * threads * 1000 / getTimes
 
哈哈,这个都让你看出来了,厉害,确实错了。我重新测试了下,结果如下:
测试完成! 启动线程数:1, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:2344微秒,处理put速度: 每秒 426 次
get处理时间:1187微秒,处理get速度: 每秒 842 次
测试完成! 启动线程数:2, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:3422微秒,处理put速度: 每秒 584 次
get处理时间:2656微秒,处理get速度: 每秒 753 次
测试完成! 启动线程数:3, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:6266微秒,处理put速度: 每秒 478 次
get处理时间:4219微秒,处理get速度: 每秒 711 次
测试完成! 启动线程数:4, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:7078微秒,处理put速度: 每秒 565 次
get处理时间:6642微秒,处理get速度: 每秒 602 次
测试完成! 启动线程数:5, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:10469微秒,处理put速度: 每秒 477 次
get处理时间:10234微秒,处理get速度: 每秒 488 次
测试完成! 启动线程数:6, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:14422微秒,处理put速度: 每秒 416 次
get处理时间:14080微秒,处理get速度: 每秒 426 次
测试完成! 启动线程数:7, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:20125微秒,处理put速度: 每秒 347 次
get处理时间:20233微秒,处理get速度: 每秒 345 次
iunknown     2007-05-18 13:38
eddie 写道
哈哈,这个都让你看出来了,厉害,确实错了。我重新测试了下,结果如下:
 
我建议的做法也是有问题的。我认为比较合理的做法应该像这样子:
http://code.google.com/p/spcached/wiki/benchmarktool
代码
public static void main(String[] args) throws Exception {
......
long begin = System.currentTimeMillis();
for (int i = 0; i < threads; i++) {
statArray[i] = new WorkerStat();
statArray[i].start = start + i * runs;
statArray[i].runs = runs;
threadArray[i] = new SetterThread( statArray[i] );
threadArray[i].start();
}
for( int i = 0; i < threads; i++ ) {
threadArray[i].join();
}
mainStat.setterTime = System.currentTimeMillis() - begin;
......
}
 
应该在主线程中 join 等待线程结束,在主线程中测量所用的时间(mainStat.setterTime)。用这个时间计算出来的 RequestPerSecond 就代表从整个程序的角度来计算的结果。而上面我提到的计算方法,计算的是每个线程的角度来计算的结果。
MemCached 压力测试-eddie -JavaEye技术社区 Flare-兼容Memcached协议的分布式key/value存储系统 - 张沈鹏,在路上... - JavaEye技术网站 XRuby发布了!-dreamhead -JavaEye技术社区 再说一些 J2EE-mazhao -JavaEye技术社区 java面试题-andyaohui -JavaEye技术社区 [转帖]Jvm Tuning-feidi -JavaEye技术社区 memcached分布测试报告(一致性哈希情况下的散列函数选择) - 庄周梦蝶 - JavaEye技术网站 Java Web Service之客户端实现-schnell18 -JavaEye技术社区 Window.ShowModalDialog使用手册-键盘寄生物 -JavaEye技术社区 dojo.io.bind的编码问题-cfans -JavaEye技术社区 Freemarker在web.xml配置说明-kenshinlk -JavaEye技术社区 ubuntu7.04上配置proftpd手记-zjumty -JavaEye技术社区 JFreeChart中文API-amozon‘s galaxy -JavaEye技术社区 [转贴] Eclipse快捷键-天使不喜欢看代码 -JavaEye技术社区 外行人谈压力测试 - BlueDavy之技术Blog - BlogJava apache本地测试启动不了的解决方法 - 林张慧 - JavaEye技术网站 卡布奇诺 - JavaEye技术网站 女孩应该偷偷知道一些事情-糖人GG -JavaEye技术社区 Tomcat 实用小技巧-路是爬出来的(无花) -JavaEye技术社区 使用rails时碰到的几个常见的问题--补充中-airport -JavaEye技术社区 一个production模式下的Ror环境搭建-airport -JavaEye技术社区 请问对于实际的Web项目应该怎样进行TDD-读书.编程.思考 -JavaEye技术社区 JSF中Tree2组件使用方法-过儿oO -JavaEye技术社区 jBPM学习(六)----Hello World JBPM @net -JavaEye技术社区