Ignite性能测试以及对redis的对比

 

测试方法

为了对Ignite做一个基本了解,做了一个性能测试,测试方法也比较简单主要是针对client模式,因为这种方法和使用redis的方式特别像。测试方法很简单主要是下面几点:

  • 不作参数优化,默认配置进行测试
  • 在一台linux服务器上部署Ignite服务端,然后自己的笔记本作客户端
  • 按1,10,20,50,100,200线程进行测试

测试环境说明

服务器:

  1. [09:36:56] ver. 1.7.0#20160801-sha1:383273e3
  2. [09:36:56] OS: Linux 2.6.32-279.el6.x86_64 amd64
  3. [09:36:56] VM information: Java(TM) SE Runtime Environment 1.7.0_07-b10 Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 23.3-b01
  4. [09:36:56] Configured plugins:
  5. [09:36:56] ^-- None
  6. [09:36:56]
  7. [09:36:56] Security status [authentication=off, tls/ssl=off]

CPU:4核
内存8GB
网卡100M
虚拟机

客户机:

  1. [13:05:32] ver. 1.7.0#20160801-sha1:383273e3
  2. [13:05:32] OS: Windows 7 6.1 amd64
  3. [13:05:32] VM information: Java(TM) SE Runtime Environment 1.8.0_40-b26 Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.40-b25
  4. [13:05:32] Initial heap size is 128MB (should be no less than 512MB, use -Xms512m -Xmx512m).
  5. [13:05:34] Configured plugins:
  6. [13:05:34] ^-- None
  7. [13:05:34]
  8. [13:05:35] Security status [authentication=off, tls/ssl=off]
  9. [13:05:51] Performance suggestions for grid (fix if possible)
  10. [13:05:51] To disable, set -DIGNITE_PERFORMANCE_SUGGESTIONS_DISABLED=true
  11. [13:05:51] ^-- Decrease number of backups (set 'backups' to 0)

CPU:4核,i5-4210u
内存8GB
笔记本win7 64位
网卡:100M

测试代码

  1. package org.j2server.j2cache.cache.iginte;
  2. import java.util.Arrays;
  3. import org.apache.ignite.Ignite;
  4. import org.apache.ignite.IgniteCache;
  5. import org.apache.ignite.Ignition;
  6. import org.apache.ignite.cache.CacheMode;
  7. import org.apache.ignite.configuration.CacheConfiguration;
  8. import org.apache.ignite.configuration.IgniteConfiguration;
  9. import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
  10. import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
  11. public class IgniteTest {
  12. //测试的数据行数
  13. private static final Integer test_rows = 50000;
  14. private static final Integer thread_cnt = 10;
  15. private static final String cacheName = "Ignite Cache";
  16. private static Ignite ignite;
  17. private static boolean client_mode = false;
  18. static {
  19. getIgnite();
  20. }
  21. public static void main(String[] args) {
  22. MultiThread();
  23. }
  24. private static Ignite getIgnite() {
  25. if (ignite == null) {
  26. TcpDiscoverySpi spi = new TcpDiscoverySpi();
  27. TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder();
  28. ipFinder.setAddresses(Arrays.asList("192.168.49.204"));
  29. spi.setIpFinder(ipFinder);
  30. CacheConfiguration cacheConfiguration = new CacheConfiguration<String, DataClass>();
  31. cacheConfiguration.setCacheMode(CacheMode.PARTITIONED);
  32. cacheConfiguration.setBackups(1);
  33. IgniteConfiguration cfg = new IgniteConfiguration();
  34. cfg.setClientMode(client_mode);
  35. cfg.setDiscoverySpi(spi);
  36. cfg.setCacheConfiguration(cacheConfiguration);
  37. ignite = Ignition.start(cfg);
  38. }
  39. System.out.println("是否客户端模式:" + client_mode);
  40. return ignite;
  41. }
  42. private static void MultiThread() {
  43. System.out.println("==================================================================");
  44. System.out.println("开始测试多线程写入[线程数:"+thread_cnt+"]");
  45. Long startTime = System.currentTimeMillis();
  46. Thread[] threads = new Thread[thread_cnt];
  47. Ignite ignite = getIgnite();
  48. IgniteCache<String, DataClass> cache = ignite.getOrCreateCache(cacheName);
  49. for (int i = 0; i < threads.length; i++) {
  50. threads[i] = new Thread(new TestThread(true, cache));
  51. }
  52. for (int i = 0; i< threads.length; i++) {
  53. threads[i].start();
  54. }
  55. for(Thread thread : threads){
  56. try {
  57. thread.join();
  58. } catch (InterruptedException e) {
  59. e.printStackTrace();
  60. }
  61. }
  62. Long endTime=System.currentTimeMillis(); //获取结束时间
  63. float interval = endTime-startTime == 0 ? 1 : endTime-startTime;
  64. float tpms = (float)test_rows/interval;
  65. System.out.println("程序运行时间: "+ interval+"ms");
  66. System.out.println("每毫秒写入:"+tpms+"条。");
  67. System.out.println("每秒写入:"+tpms*1000+"条。");
  68. System.out.println("==================================================================");
  69. System.out.println("开始测试多线程读取[线程数:"+thread_cnt+"]");
  70. startTime = System.currentTimeMillis();
  71. Thread[] readthreads = new Thread[thread_cnt];
  72. for (int i = 0; i < readthreads.length; i++) {
  73. readthreads[i] = new Thread(new TestThread(false, cache));
  74. }
  75. for (int i = 0; i< readthreads.length; i++) {
  76. readthreads[i].start();
  77. }
  78. for(Thread thread : readthreads){
  79. try {
  80. thread.join();
  81. } catch (InterruptedException e) {
  82. e.printStackTrace();
  83. }
  84. }
  85. endTime=System.currentTimeMillis(); //获取结束时间
  86. interval = endTime-startTime == 0 ? 1 : endTime-startTime;
  87. tpms = (float)test_rows/interval;
  88. System.out.println("程序运行时间: "+ interval+"ms");
  89. System.out.println("每毫秒读取:"+tpms+"条。");
  90. System.out.println("每秒读取:"+tpms*1000+"条。");
  91. }
  92. static class TestThread implements Runnable {
  93. private boolean readMode = true;
  94. private IgniteCache<String, DataClass> cache;
  95. public TestThread(boolean readMode, IgniteCache<String, DataClass> cache){
  96. this.readMode = readMode;
  97. this.cache = cache;
  98. }
  99. @Override
  100. public void run() {
  101. for (int i = 0; i < test_rows/thread_cnt; i++) {
  102. if (this.readMode) {
  103. cache.get(Integer.toString(i));
  104. } else {
  105. DataClass dc = new DataClass();
  106. dc.setName(Integer.toString(i));
  107. dc.setValue(i);
  108. dc.setStrValue("asdfadsfasfda");
  109. cache.put(Integer.toString(i), dc);
  110. }
  111. }
  112. }
  113. }
  114. }
  115. import java.io.Serializable;
  116. public class DataClass implements Serializable{
  117. private String name;
  118. private long value;
  119. private String strValue;
  120. public String getName() {
  121. return name;
  122. }
  123. public void setName(String name) {
  124. this.name = name;
  125. }
  126. public long getValue() {
  127. return value;
  128. }
  129. public void setValue(long value) {
  130. this.value = value;
  131. }
  132. public String getStrValue() {
  133. return strValue;
  134. }
  135. public void setStrValue(String strValue) {
  136. this.strValue = strValue;
  137. }
  138. }

测试数据

最终测试的结果还是有点意思,随着线程的增长读写性能大幅提升,但是到了200的时候就开始下降。下面是测试数据:


  1. [12:53:40] Topology snapshot [ver=20, servers=1, clients=1, CPUs=8, heap=2.8GB]
  2. ==================================================================
  3. 开始测试多线程写入[线程数:1]
  4. 程序运行时间: 49066.0ms
  5. 每毫秒写入:1.0190356条。
  6. 每秒写入:1019.0356条。
  7. ==================================================================
  8. 开始测试多线程读取[线程数:1]
  9. 程序运行时间: 51739.0ms
  10. 每毫秒读取:0.966389条。
  11. 每秒读取:966.389条。
  12. [12:56:22] Topology snapshot [ver=22, servers=1, clients=1, CPUs=8, heap=2.8GB]
  13. ==================================================================
  14. 开始测试多线程写入[线程数:10]
  15. 程序运行时间: 6215.0ms
  16. 每毫秒写入:8.045053条。
  17. 每秒写入:8045.0527条。
  18. ==================================================================
  19. 开始测试多线程读取[线程数:10]
  20. 程序运行时间: 6526.0ms
  21. 每毫秒读取:7.661661条。
  22. 每秒读取:7661.661条。
  23. [12:57:04] Topology snapshot [ver=24, servers=1, clients=1, CPUs=8, heap=2.8GB]
  24. ==================================================================
  25. 开始测试多线程写入[线程数:20]
  26. 程序运行时间: 4353.0ms
  27. 每毫秒写入:11.486331条。
  28. 每秒写入:11486.331条。
  29. ==================================================================
  30. 开始测试多线程读取[线程数:20]
  31. 程序运行时间: 3768.0ms
  32. 每毫秒读取:13.269639条。
  33. 每秒读取:13269.639条。
  34. [12:57:34] Topology snapshot [ver=26, servers=1, clients=1, CPUs=8, heap=2.8GB]
  35. ==================================================================
  36. 开始测试多线程写入[线程数:50]
  37. 程序运行时间: 2657.0ms
  38. 每毫秒写入:18.818216条。
  39. 每秒写入:18818.217条。
  40. ==================================================================
  41. 开始测试多线程读取[线程数:50]
  42. 程序运行时间: 2138.0ms
  43. 每毫秒读取:23.386343条。
  44. 每秒读取:23386.344条。
  45. [12:58:00] Topology snapshot [ver=28, servers=1, clients=1, CPUs=8, heap=2.8GB]
  46. ==================================================================
  47. 开始测试多线程写入[线程数:100]
  48. 程序运行时间: 2095.0ms
  49. 每毫秒写入:23.866348条。
  50. 每秒写入:23866.348条。
  51. ==================================================================
  52. 开始测试多线程读取[线程数:100]
  53. 程序运行时间: 1764.0ms
  54. 每毫秒读取:28.344671条。
  55. 每秒读取:28344.672条。
  56. [12:59:19] Topology snapshot [ver=30, servers=1, clients=1, CPUs=8, heap=2.8GB]
  57. ==================================================================
  58. 开始测试多线程写入[线程数:200]
  59. 程序运行时间: 2333.0ms
  60. 每毫秒写入:21.431633条。
  61. 每秒写入:21431.633条。
  62. ==================================================================
  63. 开始测试多线程读取[线程数:200]
  64. 程序运行时间: 2049.0ms
  65. 每毫秒读取:24.402147条。
  66. 每秒读取:24402.146条。

用图形看看比较直观

不使用客户端模式

只不过我发现如果不使用client_mode,也就是都是server模式时写入性能还是很强的,但是读取有点搓。

  1. [14:15:02] Topology snapshot [ver=22, servers=2, clients=0, CPUs=8, heap=2.8GB]
  2. 是否客户端模式:false
  3. ==================================================================
  4. 开始测试多线程写入[线程数:1]
  5. 是否客户端模式:false
  6. 程序运行时间: 828.0ms
  7. 每毫秒写入:60.386475条。
  8. 每秒写入:60386.477条。
  9. ==================================================================
  10. 开始测试多线程读取[线程数:1]
  11. 程序运行时间: 28819.0ms
  12. 每毫秒读取:1.7349665条。
  13. 每秒读取:1734.9666条。
  14. [14:08:55] Topology snapshot [ver=10, servers=2, clients=0, CPUs=8, heap=2.8GB]
  15. 是否客户端模式:false
  16. ==================================================================
  17. 开始测试多线程写入[线程数:10]
  18. 是否客户端模式:false
  19. 程序运行时间: 813.0ms
  20. 每毫秒写入:61.500614条。
  21. 每秒写入:61500.613条。
  22. ==================================================================
  23. 开始测试多线程读取[线程数:10]
  24. 程序运行时间: 5965.0ms
  25. 每毫秒读取:8.38223条。
  26. 每秒读取:8382.2295条。
  27. [14:09:48] Topology snapshot [ver=12, servers=2, clients=0, CPUs=8, heap=2.8GB]
  28. 是否客户端模式:false
  29. ==================================================================
  30. 开始测试多线程写入[线程数:20]
  31. 是否客户端模式:false
  32. 程序运行时间: 812.0ms
  33. 每毫秒写入:61.576355条。
  34. 每秒写入:61576.355条。
  35. ==================================================================
  36. 开始测试多线程读取[线程数:20]
  37. 程序运行时间: 5157.0ms
  38. 每毫秒读取:9.6955595条。
  39. 每秒读取:9695.56条。
  40. [14:10:25] Topology snapshot [ver=14, servers=2, clients=0, CPUs=8, heap=2.8GB]
  41. 是否客户端模式:false
  42. ==================================================================
  43. 开始测试多线程写入[线程数:50]
  44. 是否客户端模式:false
  45. 程序运行时间: 686.0ms
  46. 每毫秒写入:72.8863条。
  47. 每秒写入:72886.3条。
  48. ==================================================================
  49. 开始测试多线程读取[线程数:50]
  50. 程序运行时间: 4321.0ms
  51. 每毫秒读取:11.571396条。
  52. 每秒读取:11571.3955条。
  53. [14:11:01] Topology snapshot [ver=16, servers=2, clients=0, CPUs=8, heap=2.8GB]
  54. 是否客户端模式:false
  55. ==================================================================
  56. 开始测试多线程写入[线程数:100]
  57. 是否客户端模式:false
  58. 程序运行时间: 830.0ms
  59. 每毫秒写入:60.240963条。
  60. 每秒写入:60240.965条。
  61. ==================================================================
  62. 开始测试多线程读取[线程数:100]
  63. 程序运行时间: 3963.0ms
  64. 每毫秒读取:12.616705条。
  65. 每秒读取:12616.705条。
  66. [14:13:58] Topology snapshot [ver=20, servers=2, clients=0, CPUs=8, heap=2.8GB]
  67. 是否客户端模式:false
  68. ==================================================================
  69. 开始测试多线程写入[线程数:200]
  70. 是否客户端模式:false
  71. 程序运行时间: 1014.0ms
  72. 每毫秒写入:49.309666条。
  73. 每秒写入:49309.664条。
  74. ==================================================================
  75. 开始测试多线程读取[线程数:200]
  76. 程序运行时间: 3179.0ms
  77. 每毫秒读取:15.728216条。
  78. 每秒读取:15728.216条。

用图形看看比较直观

从这个数据可以看出来,在这种都是服务端的模式下,写入性能基本稳定,在达到200线程时出现衰减;而读取则基本是线性的,到100线程差不多也就到顶了。

与redis的对比

原本是想和redis作一个对比测试的,先是做了redis的测试。redis客户端用的jedis2.8.1,同时服务端用的是redis3.2.2,其他的环境和上面的一样。

结果测试数据发现redis和ignite使用客户端模式时竟然很相近。所以我怀疑是因为我对redis不了解redis没作优化导致的?但是Ignite我也是直接启动的,一点优化也没作,还是说测试的代码写法不对呢?

下面是redis的测试代码

  1. import redis.clients.jedis.Jedis;
  2. public class redis {
  3. private static final String ip = "192.168.49.200";
  4. private static final String auth = "your pwd";
  5. private static final Integer port = 6379;
  6. //测试的数据行数
  7. private static final Integer test_rows = 50000;
  8. //线程数
  9. private static final Integer thread_cnt = 200;
  10. public static void main(String[] args) {
  11. MultiThread();
  12. }
  13. private static void MultiThread() {
  14. System.out.println("==================================================================");
  15. System.out.println("开始测试多线程写入[线程数:"+thread_cnt+"]");
  16. Long startTime = System.currentTimeMillis();
  17. Thread[] threads = new Thread[thread_cnt];
  18. for (int i = 0; i < threads.length; i++) {
  19. threads[i] = new Thread(new TestThread(true));
  20. }
  21. for (int i = 0; i< threads.length; i++) {
  22. threads[i].start();
  23. }
  24. for(Thread thread : threads){
  25. try {
  26. thread.join();
  27. } catch (InterruptedException e) {
  28. e.printStackTrace();
  29. }
  30. }
  31. Long endTime=System.currentTimeMillis(); //获取结束时间
  32. float interval = endTime-startTime == 0 ? 1 : endTime-startTime;
  33. float tpms = (float)test_rows/interval;
  34. System.out.println("程序运行时间: "+ interval+"ms");
  35. System.out.println("每毫秒写入:"+tpms+"条。");
  36. System.out.println("每秒写入:"+tpms*1000+"条。");
  37. System.out.println("==================================================================");
  38. System.out.println("开始测试多线程写入[线程数:"+thread_cnt+"]");
  39. startTime = System.currentTimeMillis();
  40. Thread[] readthreads = new Thread[thread_cnt];
  41. for (int i = 0; i < readthreads.length; i++) {
  42. readthreads[i] = new Thread(new TestThread(false));
  43. }
  44. for (int i = 0; i< readthreads.length; i++) {
  45. readthreads[i].start();
  46. }
  47. for(Thread thread : readthreads){
  48. try {
  49. thread.join();
  50. } catch (InterruptedException e) {
  51. e.printStackTrace();
  52. }
  53. }
  54. endTime=System.currentTimeMillis(); //获取结束时间
  55. interval = endTime-startTime == 0 ? 1 : endTime-startTime;
  56. tpms = (float)test_rows/interval;
  57. System.out.println("程序运行时间: "+ interval+"ms");
  58. System.out.println("每毫秒读取:"+tpms+"条。");
  59. System.out.println("每秒读取:"+tpms*1000+"条。");
  60. }
  61. static class TestThread implements Runnable {
  62. private boolean readMode = true;
  63. public TestThread(boolean readMode){
  64. this.readMode = readMode;
  65. }
  66. @Override
  67. public void run() {
  68. Jedis j = new Jedis(ip,port);
  69. j.auth(auth);
  70. for (int i = 0; i < test_rows/thread_cnt; i++) {
  71. if (this.readMode) {
  72. j.get("foo"+i);
  73. } else {
  74. j.set("foo"+i, "bar"+i);
  75. }
  76. }
  77. j.disconnect();
  78. }
  79. }
  80. }

对比结果视图

结束

原本我想着redis估计得秒了ignite,毕竟redis是这么多系统正在使用的内存数据库。ignite本身含有这么多功能按理性能肯定是比不上才对,而且ignite组成集群后是需要进行数据分块存取和备份的,而测试环境中redis则是单实例情况,这让我没太想明白啊。。还望有高手指点。。

看网上许多人测试的数据redis少点的4万+,据说可以到10万+。但我自己的测试环境差了点反正最多也没过3万,这到底会是什么原因呢?

不管如何这是一次简单的测试与尝试,结果与预期有点偏差,继续学习深入了解吧。

性能测试以及对redis的更多相关文章

  1. Ignite性能测试以及对redis的对比

    测试方法 为了对Ignite做一个基本了解,做了一个性能测试,测试方法也比较简单主要是针对client模式,因为这种方法和使用redis的方式特别像.测试方法很简单主要是下面几点: 不作参数优化,默认 ...

  2. Redis性能测试Redis-benchmark

    Redis-benchmark是官方自带的Redis性能测试工具 测试Redis在你的系统及你的配置下的读写性能 redis-benchmark可以模拟N个机器,同时发送M个请求 redis-benc ...

  3. 万字长文入门 Redis 命令、事务、锁、订阅、性能测试

    作者:痴者工良 Redis 基本数据类型 Redis 中,常用的数据类型有以下几种: String:字符串类型,二进制安全字符串: Hash:哈希表: List 列表:链表结构,按照插入顺序排序的字符 ...

  4. 基于Twemproxy的Redis集群方案

    概述 由于单台redis服务器的内存管理能力有限,使用过大内存redis服务器的性能急剧下降,且服务器发生故障将直接影响大面积业务.为了获取更好的缓存性能及扩展型,我们将需要搭建redis集群来满足需 ...

  5. redis入门教程

    21) Redis 简介Redis 是一个开源的使用 ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value 数据库.2) 数据类型2.1. Redis 的 KeyRedi ...

  6. 利用Azure Redis Cache构建百万量级缓存读写

    Redis是一个非常流行的基于内存的,低延迟,高吞吐量的key/value数据存储,被广泛用于数据库缓存,session的管理,热数据高速访问,甚至作为数据库方式提高应用程序可扩展性,吞吐量,和实施处 ...

  7. 基于 twemproxy 搭建 redis 集群

    概述 由于单台redis服务器的内存管理能力有限,使用过大内存redis服务器的性能急剧下降,且服务器发生故障将直接影响大面积业务.为了获取更好的缓存性能及扩展型,我们将需要搭建redis集群来满足需 ...

  8. redis 基本原理及安装

    一:什么是redis? Redis 是一个开源的,高性能的,基于键值对的缓存与存储系统.通过提供多种键值数据类型来适应不同场景下的缓存与存储需求. 二:redis数据库有什么优点? Redis数据库中 ...

  9. Redis 主从模式

    系统:Centos6.6x64安装目录:/usr/local/主:192.168.100.103从:192.168.100.104 ,下载安装: 安装依赖: # yum install gcc tcl ...

随机推荐

  1. zynq+linux+ramdisk can调试

    由于采用ramdisk文件系统,自带的ip工具版本太旧无法配置can,需要自行编译ip,具体参见参考文献2 1.vivado配置ps 2.设备树增加can0,一般开发板均已提供此配置 can@e000 ...

  2. UIButton UIBarButtonItem用法

    #pragma mark 快速创建一个item - (UIBarButtonItem *)itemWithNormal:(NSString *)normal highlighted:(NSString ...

  3. 【u251】心灵的抚慰

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 病毒问题解决后,神牛们的心灵久久不能平静.他可以从一个程序联想到一些相似的程序.比如从程序1联想到2, ...

  4. js中数组如何使用

    js中数组如何使用 一.总结 一句话总结:new Array()和[]两种方法都可以创建数组. 二.js中创建数组,并往数组里添加元素 数组的创建 var arrayObj = new Array() ...

  5. 【45.65%】【codeforces 560B】Gerald is into Art

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  6. windll对象

    回过头来,再看一下windll和oledll的差别,这两者之间最大的差别是oledll调用的函数都是固定返回HRESULT类型的值,而windll是不固定的类型的.在Python 3.3版本号之前,都 ...

  7. jquery-2 jQuery原理和核心方法(多看学习视频)

    jquery-2  jQuery原理和核心方法(多看学习视频) 一.总结 一句话总结:jQuery就是普通的js对象,只不过方法比较多而已,属性就length一个. 1.jquery的链式操作的底层原 ...

  8. 数据库迁移框架Flyway介绍

    官方文档 https://flywaydb.org/getstarted/firststeps/api[https://flywaydb.org/getstarted/firststeps/api] ...

  9. Quartz2D常见图形的绘制:线条、多边形、圆

    UI高级 Quartz2D http://ios.itcast.cn  iOS学院 掌握 drawRect:方法的使用 常见图形的绘制:线条.多边形.圆 绘图状态的设置:文字颜色.线宽等 图形上下文状 ...

  10. ITFriend创业败局(序):简要概述我的第一次创业经历

    是时候, 面对过去,继续踏上未来之路了.    是时候,该给自己一个交待了,给ITFriend创业合伙人.ITFriend用户.关注我的朋友和网友们一个答复了.    是时候,全面认真总结过去的经历. ...