爲了對Ignite作一個基本瞭解,作了一個性能測試,測試方法也比較簡單主要是針對client模式,由於這種方法和使用redis的方式特別像。測試方法很簡單主要是下面幾點:java
服務器:linux
[09:36:56] ver. 1.7.0#20160801-sha1:383273e3 [09:36:56] OS: Linux 2.6.32-279.el6.x86_64 amd64 [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 [09:36:56] Configured plugins: [09:36:56] ^-- None [09:36:56] [09:36:56] Security status [authentication=off, tls/ssl=off]
CPU:4核
內存8GB
網卡100M
虛擬機redis
客戶機:數據庫
[13:05:32] ver. 1.7.0#20160801-sha1:383273e3 [13:05:32] OS: Windows 7 6.1 amd64 [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 [13:05:32] Initial heap size is 128MB (should be no less than 512MB, use -Xms512m -Xmx512m). [13:05:34] Configured plugins: [13:05:34] ^-- None [13:05:34] [13:05:35] Security status [authentication=off, tls/ssl=off] [13:05:51] Performance suggestions for grid (fix if possible) [13:05:51] To disable, set -DIGNITE_PERFORMANCE_SUGGESTIONS_DISABLED=true [13:05:51] ^-- Decrease number of backups (set 'backups' to 0)
CPU:4核,i5-4210u
內存8GB
筆記本win7 64位
網卡:100Mapache
測試代碼服務器
package org.j2server.j2cache.cache.iginte; import java.util.Arrays; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; import org.apache.ignite.Ignition; import org.apache.ignite.cache.CacheMode; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; public class IgniteTest { //測試的數據行數 private static final Integer test_rows = 50000; private static final Integer thread_cnt = 10; private static final String cacheName = "Ignite Cache"; private static Ignite ignite; private static boolean client_mode = false; static { getIgnite(); } public static void main(String[] args) { MultiThread(); } private static Ignite getIgnite() { if (ignite == null) { TcpDiscoverySpi spi = new TcpDiscoverySpi(); TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder(); ipFinder.setAddresses(Arrays.asList("192.168.49.204")); spi.setIpFinder(ipFinder); CacheConfiguration cacheConfiguration = new CacheConfiguration<String, DataClass>(); cacheConfiguration.setCacheMode(CacheMode.PARTITIONED); cacheConfiguration.setBackups(1); IgniteConfiguration cfg = new IgniteConfiguration(); cfg.setClientMode(client_mode); cfg.setDiscoverySpi(spi); cfg.setCacheConfiguration(cacheConfiguration); ignite = Ignition.start(cfg); } System.out.println("是否客戶端模式:" + client_mode); return ignite; } private static void MultiThread() { System.out.println("=================================================================="); System.out.println("開始測試多線程寫入[線程數:"+thread_cnt+"]"); Long startTime = System.currentTimeMillis(); Thread[] threads = new Thread[thread_cnt]; Ignite ignite = getIgnite(); IgniteCache<String, DataClass> cache = ignite.getOrCreateCache(cacheName); for (int i = 0; i < threads.length; i++) { threads[i] = new Thread(new TestThread(true, cache)); } for (int i = 0; i< threads.length; i++) { threads[i].start(); } for(Thread thread : threads){ try { thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } Long endTime=System.currentTimeMillis(); //獲取結束時間 float interval = endTime-startTime == 0 ? 1 : endTime-startTime; float tpms = (float)test_rows/interval; System.out.println("程序運行時間: "+ interval+"ms"); System.out.println("每毫秒寫入:"+tpms+"條。"); System.out.println("每秒寫入:"+tpms*1000+"條。"); System.out.println("=================================================================="); System.out.println("開始測試多線程讀取[線程數:"+thread_cnt+"]"); startTime = System.currentTimeMillis(); Thread[] readthreads = new Thread[thread_cnt]; for (int i = 0; i < readthreads.length; i++) { readthreads[i] = new Thread(new TestThread(false, cache)); } for (int i = 0; i< readthreads.length; i++) { readthreads[i].start(); } for(Thread thread : readthreads){ try { thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } endTime=System.currentTimeMillis(); //獲取結束時間 interval = endTime-startTime == 0 ? 1 : endTime-startTime; tpms = (float)test_rows/interval; System.out.println("程序運行時間: "+ interval+"ms"); System.out.println("每毫秒讀取:"+tpms+"條。"); System.out.println("每秒讀取:"+tpms*1000+"條。"); } static class TestThread implements Runnable { private boolean readMode = true; private IgniteCache<String, DataClass> cache; public TestThread(boolean readMode, IgniteCache<String, DataClass> cache){ this.readMode = readMode; this.cache = cache; } @Override public void run() { for (int i = 0; i < test_rows/thread_cnt; i++) { if (this.readMode) { cache.get(Integer.toString(i)); } else { DataClass dc = new DataClass(); dc.setName(Integer.toString(i)); dc.setValue(i); dc.setStrValue("asdfadsfasfda"); cache.put(Integer.toString(i), dc); } } } } } import java.io.Serializable; public class DataClass implements Serializable{ private String name; private long value; private String strValue; public String getName() { return name; } public void setName(String name) { this.name = name; } public long getValue() { return value; } public void setValue(long value) { this.value = value; } public String getStrValue() { return strValue; } public void setStrValue(String strValue) { this.strValue = strValue; } }
最終測試的結果仍是有點意思,隨着線程的增加讀寫性能大幅提高,可是到了200的時候就開始降低。下面是測試數據:多線程
[12:53:40] Topology snapshot [ver=20, servers=1, clients=1, CPUs=8, heap=2.8GB] ================================================================== 開始測試多線程寫入[線程數:1] 程序運行時間: 49066.0ms 每毫秒寫入:1.0190356條。 每秒寫入:1019.0356條。 ================================================================== 開始測試多線程讀取[線程數:1] 程序運行時間: 51739.0ms 每毫秒讀取:0.966389條。 每秒讀取:966.389條。 [12:56:22] Topology snapshot [ver=22, servers=1, clients=1, CPUs=8, heap=2.8GB] ================================================================== 開始測試多線程寫入[線程數:10] 程序運行時間: 6215.0ms 每毫秒寫入:8.045053條。 每秒寫入:8045.0527條。 ================================================================== 開始測試多線程讀取[線程數:10] 程序運行時間: 6526.0ms 每毫秒讀取:7.661661條。 每秒讀取:7661.661條。 [12:57:04] Topology snapshot [ver=24, servers=1, clients=1, CPUs=8, heap=2.8GB] ================================================================== 開始測試多線程寫入[線程數:20] 程序運行時間: 4353.0ms 每毫秒寫入:11.486331條。 每秒寫入:11486.331條。 ================================================================== 開始測試多線程讀取[線程數:20] 程序運行時間: 3768.0ms 每毫秒讀取:13.269639條。 每秒讀取:13269.639條。 [12:57:34] Topology snapshot [ver=26, servers=1, clients=1, CPUs=8, heap=2.8GB] ================================================================== 開始測試多線程寫入[線程數:50] 程序運行時間: 2657.0ms 每毫秒寫入:18.818216條。 每秒寫入:18818.217條。 ================================================================== 開始測試多線程讀取[線程數:50] 程序運行時間: 2138.0ms 每毫秒讀取:23.386343條。 每秒讀取:23386.344條。 [12:58:00] Topology snapshot [ver=28, servers=1, clients=1, CPUs=8, heap=2.8GB] ================================================================== 開始測試多線程寫入[線程數:100] 程序運行時間: 2095.0ms 每毫秒寫入:23.866348條。 每秒寫入:23866.348條。 ================================================================== 開始測試多線程讀取[線程數:100] 程序運行時間: 1764.0ms 每毫秒讀取:28.344671條。 每秒讀取:28344.672條。 [12:59:19] Topology snapshot [ver=30, servers=1, clients=1, CPUs=8, heap=2.8GB] ================================================================== 開始測試多線程寫入[線程數:200] 程序運行時間: 2333.0ms 每毫秒寫入:21.431633條。 每秒寫入:21431.633條。 ================================================================== 開始測試多線程讀取[線程數:200] 程序運行時間: 2049.0ms 每毫秒讀取:24.402147條。 每秒讀取:24402.146條。
用圖形看看比較直觀
less
只不過我發現若是不使用client_mode,也就是都是server模式時寫入性能仍是很強的,可是讀取有點搓。tcp
[14:15:02] Topology snapshot [ver=22, servers=2, clients=0, CPUs=8, heap=2.8GB] 是否客戶端模式:false ================================================================== 開始測試多線程寫入[線程數:1] 是否客戶端模式:false 程序運行時間: 828.0ms 每毫秒寫入:60.386475條。 每秒寫入:60386.477條。 ================================================================== 開始測試多線程讀取[線程數:1] 程序運行時間: 28819.0ms 每毫秒讀取:1.7349665條。 每秒讀取:1734.9666條。 [14:08:55] Topology snapshot [ver=10, servers=2, clients=0, CPUs=8, heap=2.8GB] 是否客戶端模式:false ================================================================== 開始測試多線程寫入[線程數:10] 是否客戶端模式:false 程序運行時間: 813.0ms 每毫秒寫入:61.500614條。 每秒寫入:61500.613條。 ================================================================== 開始測試多線程讀取[線程數:10] 程序運行時間: 5965.0ms 每毫秒讀取:8.38223條。 每秒讀取:8382.2295條。 [14:09:48] Topology snapshot [ver=12, servers=2, clients=0, CPUs=8, heap=2.8GB] 是否客戶端模式:false ================================================================== 開始測試多線程寫入[線程數:20] 是否客戶端模式:false 程序運行時間: 812.0ms 每毫秒寫入:61.576355條。 每秒寫入:61576.355條。 ================================================================== 開始測試多線程讀取[線程數:20] 程序運行時間: 5157.0ms 每毫秒讀取:9.6955595條。 每秒讀取:9695.56條。 [14:10:25] Topology snapshot [ver=14, servers=2, clients=0, CPUs=8, heap=2.8GB] 是否客戶端模式:false ================================================================== 開始測試多線程寫入[線程數:50] 是否客戶端模式:false 程序運行時間: 686.0ms 每毫秒寫入:72.8863條。 每秒寫入:72886.3條。 ================================================================== 開始測試多線程讀取[線程數:50] 程序運行時間: 4321.0ms 每毫秒讀取:11.571396條。 每秒讀取:11571.3955條。 [14:11:01] Topology snapshot [ver=16, servers=2, clients=0, CPUs=8, heap=2.8GB] 是否客戶端模式:false ================================================================== 開始測試多線程寫入[線程數:100] 是否客戶端模式:false 程序運行時間: 830.0ms 每毫秒寫入:60.240963條。 每秒寫入:60240.965條。 ================================================================== 開始測試多線程讀取[線程數:100] 程序運行時間: 3963.0ms 每毫秒讀取:12.616705條。 每秒讀取:12616.705條。 [14:13:58] Topology snapshot [ver=20, servers=2, clients=0, CPUs=8, heap=2.8GB] 是否客戶端模式:false ================================================================== 開始測試多線程寫入[線程數:200] 是否客戶端模式:false 程序運行時間: 1014.0ms 每毫秒寫入:49.309666條。 每秒寫入:49309.664條。 ================================================================== 開始測試多線程讀取[線程數:200] 程序運行時間: 3179.0ms 每毫秒讀取:15.728216條。 每秒讀取:15728.216條。
用圖形看看比較直觀
ide
從這個數據能夠看出來,在這種都是服務端的模式下,寫入性能基本穩定,在達到200線程時出現衰減;而讀取則基本是線性的,到100線程差很少也就到頂了。
本來是想和redis做一個對比測試的,先是作了redis的測試。redis客戶端用的jedis2.8.1,同時服務端用的是redis3.2.2,其餘的環境和上面的同樣。
結果測試數據發現redis和ignite使用客戶端模式時居然很相近。因此我懷疑是由於我對redis不瞭解redis沒做優化致使的?可是Ignite我也是直接啓動的,一點優化也沒做,仍是說測試的代碼寫法不對呢?
下面是redis的測試代碼
import redis.clients.jedis.Jedis; public class redis { private static final String ip = "192.168.49.200"; private static final String auth = "your pwd"; private static final Integer port = 6379; //測試的數據行數 private static final Integer test_rows = 50000; //線程數 private static final Integer thread_cnt = 200; public static void main(String[] args) { MultiThread(); } private static void MultiThread() { System.out.println("=================================================================="); System.out.println("開始測試多線程寫入[線程數:"+thread_cnt+"]"); Long startTime = System.currentTimeMillis(); Thread[] threads = new Thread[thread_cnt]; for (int i = 0; i < threads.length; i++) { threads[i] = new Thread(new TestThread(true)); } for (int i = 0; i< threads.length; i++) { threads[i].start(); } for(Thread thread : threads){ try { thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } Long endTime=System.currentTimeMillis(); //獲取結束時間 float interval = endTime-startTime == 0 ? 1 : endTime-startTime; float tpms = (float)test_rows/interval; System.out.println("程序運行時間: "+ interval+"ms"); System.out.println("每毫秒寫入:"+tpms+"條。"); System.out.println("每秒寫入:"+tpms*1000+"條。"); System.out.println("=================================================================="); System.out.println("開始測試多線程寫入[線程數:"+thread_cnt+"]"); startTime = System.currentTimeMillis(); Thread[] readthreads = new Thread[thread_cnt]; for (int i = 0; i < readthreads.length; i++) { readthreads[i] = new Thread(new TestThread(false)); } for (int i = 0; i< readthreads.length; i++) { readthreads[i].start(); } for(Thread thread : readthreads){ try { thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } endTime=System.currentTimeMillis(); //獲取結束時間 interval = endTime-startTime == 0 ? 1 : endTime-startTime; tpms = (float)test_rows/interval; System.out.println("程序運行時間: "+ interval+"ms"); System.out.println("每毫秒讀取:"+tpms+"條。"); System.out.println("每秒讀取:"+tpms*1000+"條。"); } static class TestThread implements Runnable { private boolean readMode = true; public TestThread(boolean readMode){ this.readMode = readMode; } @Override public void run() { Jedis j = new Jedis(ip,port); j.auth(auth); for (int i = 0; i < test_rows/thread_cnt; i++) { if (this.readMode) { j.get("foo"+i); } else { j.set("foo"+i, "bar"+i); } } j.disconnect(); } } }
對比結果視圖
本來我想着redis估計得秒了ignite,畢竟redis是這麼多系統正在使用的內存數據庫。ignite自己含有這麼多功能按理性能確定是比不上纔對,並且ignite組成集羣后是須要進行數據分塊存取和備份的,而測試環境中redis則是單實例狀況,這讓我沒太想明白啊。。還望有高手指點。。
看網上許多人測試的數據redis少點的4萬+,聽說能夠到10萬+。但我本身的測試環境差了點反正最多也沒過3萬,這到底會是什麼緣由呢?
無論如何這是一次簡單的測試與嘗試,結果與預期有點誤差,繼續學習深刻了解吧。