`
eddie
  • 浏览: 92031 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

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 代码
  1. import com.danga.MemCached.MemCachedClient;   
  2. import com.danga.MemCached.SockIOPool;   
  3.   
  4. public class TestMemCache {   
  5.     static SockIOPool pool;   
  6.   
  7.     static int threads; // 运行的测试线程数   
  8.   
  9.     static int runs; // 每个线程运行的次数   
  10.   
  11.     static int size; // 设置到memcache中的数据包大小,单位k   
  12.   
  13.     static Integer myLock;// 锁定以下计数器   
  14.   
  15.     static long putTimes = 0// put总时间,单位微秒   
  16.   
  17.     static long getTimes = 0// get总时间,单位微秒   
  18.   
  19.     /**  
  20.      * @param args  
  21.      */  
  22.     public static void main(String[] args) {   
  23.         String[] serverlist = { "192.168.0.56:11211""192.168.0.56:11212" };   
  24.   
  25.         // initialize the pool for memcache servers   
  26.         pool = SockIOPool.getInstance();   
  27.         pool.setServers(serverlist);   
  28.   
  29.         pool.setInitConn(5);   
  30.         pool.setMinConn(5);   
  31.         pool.setMaxConn(50);   
  32.         pool.setMaintSleep(30);   
  33.   
  34.         pool.setNagle(false);   
  35.         pool.initialize();   
  36.   
  37.         if (args.length < 3) {   
  38.             System.out.println("用法:TestMemCache 启动线程数 每线程执行测试数量 测试数据大小(k)");   
  39.             System.exit(1);   
  40.         }   
  41.   
  42.         threads = Integer.parseInt(args[0]);   
  43.         runs = Integer.parseInt(args[1]);   
  44.         size = 100 * Integer.parseInt(args[2]);   
  45.   
  46.         myLock = new Integer(threads);   
  47.   
  48.         for (int i = 0; i < threads; i++) {   
  49.             Thread thread = new WorkerThread();   
  50.             thread.start();   
  51.         }   
  52.     }   
  53.   
  54.     private static class WorkerThread extends Thread {   
  55.   
  56.         // 构造函数   
  57.         WorkerThread() {   
  58.         }   
  59.   
  60.         public void run() {   
  61.             // get client instance   
  62.             MemCachedClient mc = new MemCachedClient();   
  63.   
  64.             mc.setCompressEnable(false);   
  65.             mc.setCompressThreshold(0);   
  66.   
  67.             // get object to store   
  68.             int[] obj = new int[size];   
  69.             for (int i = 0; i < size; i++) {   
  70.                 obj[i] = i;   
  71.             }   
  72.   
  73.             String[] keys = new String[runs];   
  74.             for (int i = 0; i < runs; i++) {   
  75.                 keys[i] = "test_key" + i;   
  76.             }   
  77.   
  78.             for (int i = 0; i < runs; i++) {   
  79.                 mc.delete(keys[i]);   
  80.             }   
  81.   
  82.             long startTime = System.currentTimeMillis();   
  83.             for (int i = 0; i < runs; i++) {   
  84.                 mc.set(keys[i], obj);   
  85.             }   
  86.             long time = System.currentTimeMillis() - startTime;   
  87.   
  88.             synchronized (myLock) {   
  89.                 putTimes += time;   
  90.             }   
  91.   
  92.             startTime = System.currentTimeMillis();   
  93.             for (int i = 0; i < runs; i++) {   
  94.                 mc.get(keys[i]);   
  95.             }   
  96.             time = System.currentTimeMillis() - startTime;   
  97.   
  98.             synchronized (myLock) {   
  99.                 getTimes += time;   
  100.                 myLock--;   
  101.   
  102.                 if (myLock.equals(0)) {   
  103.                     System.out.println("测试完成! 启动线程数:" + threads   
  104.                             + ", 每线程执行测试数量: " + runs + ", 测试数据大小(byte):" + size);   
  105.   
  106.                     System.out.println("put处理时间:" + putTimes   
  107.                             + "微秒,处理put速度: 每秒 " + runs * threads * 1000 / putTimes   
  108.                             + " 次");   
  109.                     System.out.println("get处理时间:" + getTimes   
  110.                             + "微秒,处理get速度: 每秒 " + runs * threads * 1000 / getTimes   
  111.                             + " 次");   
  112.   
  113.                     pool.shutDown();   
  114.                 }   
  115.             }   
  116.         }   
  117.     }   
  118.   
  119. }   

 测试结果:

测试完成! 启动线程数: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

 

分享到:
评论
14 楼 iunknown 2007-08-03  
eddie 写道
抱歉,之前的程序有错,误导大家了:

runs * threads * 1000 / time
runs * threads * 1000 / time

应该改为

runs * threads * 1000 / putTimes
runs * threads * 1000 / getTimes

iunknown 已经指出来了,不过我忘记了修改论坛内容,测试性能特别高的别太早高兴。


可以试试用这个工具来测试
http://code.google.com/p/spcached/wiki/benchmarktool
13 楼 eddie 2007-08-02  
抱歉,之前的程序有错,误导大家了:

runs * threads * 1000 / time
runs * threads * 1000 / time

应该改为

runs * threads * 1000 / putTimes
runs * threads * 1000 / getTimes

iunknown 已经指出来了,不过我忘记了修改论坛内容,测试性能特别高的别太早高兴。
12 楼 hata8301 2007-08-02  
GO   TestMemCache
测试完成! 启动线程数:10, 每线程执行测试数量: 10000, 测试数据大小(byte):1000
put处理时间:327687微秒,处理put速度: 每秒 9953 次
get处理时间:120751微秒,处理get速度: 每秒 9953 次
11 楼 hqman 2007-07-27  
测试完成! 启动线程数:8, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:23864微秒,处理put速度: 每秒 335 次
get处理时间:22403微秒,处理get速度: 每秒 357 次
10 楼 hqman 2007-07-27  
测试完成! 启动线程数:7, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:15769微秒,处理put速度: 每秒 443 次
get处理时间:14981微秒,处理get速度: 每秒 467 次
9 楼 hqman 2007-07-27  
测试完成! 启动线程数:7, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:17335微秒,处理put速度: 每秒 403 次
get处理时间:17664微秒,处理get速度: 每秒 396 次
8 楼 hqman 2007-07-27  
测试完成! 启动线程数:9, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:30093微秒,处理put速度: 每秒 6351 次
get处理时间:26478微秒,处理get速度: 每秒 6351 次

居然达到 每秒 6351 次
7 楼 hqman 2007-07-27  
3台 在加入一台 本地机器 64m 性能为何变差 ???
6 楼 hqman 2007-07-27  
2台  1台 2g  一台 64m
测试完成! 启动线程数:1, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:1010微秒,处理put速度: 每秒 1005 次
get处理时间:995微秒,处理get速度: 每秒 1005 次



测试完成! 启动线程数:1, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:1014微秒,处理put速度: 每秒 1031 次
get处理时间:969微秒,处理get速度: 每秒 1031 次


测试完成! 启动线程数:1, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:995微秒,处理put速度: 每秒 999 次
get处理时间:1001微秒,处理get速度: 每秒 999 次



测试完成! 启动线程数:10, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:30951微秒,处理put速度: 每秒 2881 次
get处理时间:30531微秒,处理get速度: 每秒 2881 次

测试完成! 启动线程数:9, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:25449微秒,处理put速度: 每秒 3119 次
get处理时间:26399微秒,处理get速度: 每秒 3119 次


3台 在加入一台 本地机器 64m
测试完成! 启动线程数:9, 每线程执行测试数量: 1000, 测试数据大小(byte):1024
put处理时间:61636微秒,处理put速度: 每秒 1466 次
get处理时间:43753微秒,处理get速度: 每秒 1466 次
5 楼 iunknown 2007-05-18  
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 就代表从整个程序的角度来计算的结果。而上面我提到的计算方法,计算的是每个线程的角度来计算的结果。
4 楼 eddie 2007-05-17  
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 次
3 楼 iunknown 2007-05-17  
引用

#
#                     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
2 楼 eddie 2007-05-08  
rtdb 写道
我认为你这个测试,数据处理速度应当是受限于网络,
线程数量则是受限于客户机,
没有测试到SERVER的性能。
我们的局域网就这速度,没办法。客户端应该没啥限制的,我的客户机是个IBM笔记本,配置还可以,1.5G内存,双核CPU。
1 楼 rtdb 2007-05-07  
我认为你这个测试,数据处理速度应当是受限于网络,
线程数量则是受限于客户机,
没有测试到SERVER的性能。

相关推荐

    memcache redis tair 性能测试报告

    - Memcached运行在10.19.90.74上,版本1.4.15。 - Redis运行在10.19.90.77上,版本2.6.14。 - Tair的Config_server和Data_server分别在10.19.90.75和10.19.90.76上运行,版本日期为2013-10-24。 【测试结果分析】 ...

    memcached测试的工具类

    - **压力测试**: 连续大量地设置和获取数据,观察Memcached的响应时间和稳定性,检查是否存在性能瓶颈。 - **内存占用监测**: 监控Memcached内存使用情况,确保不会超出预设的内存限制。 3. **命中率测试**: - ...

    Memcached windows 下安装与测试

    **Memcached Windows 下安装与测试详解** ...记住,Memcached主要用于短期存储热数据,降低数据库的读取压力,优化Web应用性能。在实际应用中,根据需求调整配置,如内存分配、过期策略等,以达到最佳效果。

    memcached 64位 window

    **标题与描述解析** 标题"memcached 64位 window"指的是在Windows操作系统上运行的64位版本的Memcached缓存系统。Memcached是一种分布式内存对象...正确配置和使用Memcached,能显著改善用户体验,降低服务器压力。

    memcached服务器端memcached.exe 下载

    描述中提到的“绿色版memcached”,是指这是一个便携式的版本,不需在系统中留下任何配置痕迹,适合临时或测试环境使用。它附带了`php_memcached.dll`文件,这表明该版本特别考虑了与PHP的集成。`php_memcached.dll`...

    memcached整合hibernate资源合集

    5. **测试与优化**:完成上述步骤后,通过单元测试或集成测试确保缓存功能正常工作。根据应用需求和性能监控结果,可能需要调整缓存的过期时间、大小限制以及缓存策略。 在这个资源合集中,你可能会找到示例代码、...

    memcached工具类源码

    - **测试类**:提供各个方法的测试用例,验证功能的正确性。 4. **源码实现细节** - **连接池管理**:为了提高性能,可能会实现连接池,复用已建立的连接,减少频繁创建和销毁连接的开销。 - **序列化与反序列化...

    分布式缓存Memcached实例

    在提供的压缩包中,可能包含了一些关于如何使用或测试Memcached的资源,如`MemcachedTest`可能是用于测试Memcached的脚本或工具,而`网盘资源搜索-【51pansou.com】.txt`和`51pansou-海量网盘资源任意搜索.url`可能...

    memcachedredis性能测试.docx

    Memcached广泛应用于高并发的Web应用,如社交网络、新闻站点等,它可以极大地缓解数据库的压力,提高响应速度。同时,由于其轻量级和简单的设计,使得它易于集成到现有的应用架构中。 7. **对比Redis** Redis是另...

    Memcached缓存技术资料源码

    3. **命令行工具`: `memcached-client`或`telnet`可以直接与Memcached服务通信,进行测试和调试。 **五、源码分析** Memcached的源码主要由C语言编写,包括了服务器端和客户端的实现。源码阅读可以帮助理解其内部...

    memcached-amd64.rar

    **memcached工具类** 在IT领域,`memcached`是一个高性能、分布式...对于需要提升网站性能,减少数据库压力的开发者来说,这是一个非常实用的资源。只需按照上述步骤,你就可以快速集成和利用`memcached`的缓存功能。

    SSM整合memcached缓存

    这不仅能够提高应用的响应速度,还能有效减轻数据库的压力,特别是在处理高并发请求时。同时,由于Memcached的分布式特性,它还可以在多台服务器之间共享缓存,进一步提高系统的扩展性和稳定性。在实际项目中,可以...

    memcached分布式缓存数据库部署.doc

    总的来说,memcached以其高效的内存管理和简单易用的接口,成为解决Web应用数据库压力的有效手段。通过合理的部署和使用,能显著提升应用的性能和用户体验。然而,需要注意的是,memcached并不适用于所有场景,例如...

    memcached_win64_win7 php-安装

    3. **测试连接**:在PHP代码中编写简单的测试脚本,尝试连接到本地的memcached服务,确认扩展已正确安装并可以使用。 4. **使用PHP操作memcached**:学习并掌握基本的memcached PHP API,如`$memcached = new ...

    memcached+tomcat7共享session所需要的jar包

    通过这种方式,我们不仅可以实现跨服务器的Session共享,还可以利用Memcached的分布式特性,进一步提高Session读写的速度,降低单个服务器的压力。需要注意的是,由于Session数据存储在Memcached中,因此需要关注...

    spring memcached 所需jar

    Memcached是一款流行的分布式内存缓存系统,它被用来提升应用性能,通过存储数据到内存中来减少数据库的访问压力。当我们将Memcached与Spring集成时,我们可以利用Spring的IoC(Inversion of Control)和AOP(Aspect...

    memcached1.4.12的32,64版本以及php7的32,64扩展

    5. 最后,通过编写PHP代码测试连接和操作Memcached服务器,验证安装是否成功。 **最佳实践** 在实际使用中,为保证性能和稳定性,需要注意以下几点: 1. 调整Memcached的内存分配,以适应服务器资源和应用需求。 ...

    memcached_1.4.13(win64&32)_client2.12

    在实际应用中,memcached通常用于缓解数据库的压力,例如,将经常访问的数据存储在内存中,减少对数据库的读取次数。这样可以显著提升网站的响应速度,尤其是在高并发访问的场景下。此外,由于memcached是分布式的,...

    session共享 memcached-session-manager 1.9.6 jar

    Memcached是一款广泛应用的高性能分布式内存对象缓存系统,它能够有效地缓解数据库的压力,提高系统的响应速度。`memcached-session-manager`是Java的一个库,用于在基于Tomcat的Web应用中实现基于Memcached的...

Global site tag (gtag.js) - Google Analytics