測試方法 為了對Ignite做一個基本瞭解,做了一個性能測試,測試方法也比較簡單主要是針對client模式,因為這種方法和使用redis的方式特別像。測試方法很簡單主要是下麵幾點: 不作參數優化 ,預設配置進行測試 在一臺linux伺服器上部署Ignite服務端,然後自己的筆記本作客戶端 按1,10 ...
測試方法
為了對Ignite做一個基本瞭解,做了一個性能測試,測試方法也比較簡單主要是針對client模式,因為這種方法和使用redis的方式特別像。測試方法很簡單主要是下麵幾點:
- 不作參數優化,預設配置進行測試
- 在一臺linux伺服器上部署Ignite服務端,然後自己的筆記本作客戶端
- 按1,10,20,50,100,200線程進行測試
測試環境說明
伺服器:
[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
虛擬機
客戶機:
[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位
網卡:100M
測試代碼
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條。
用圖形看看比較直觀
不使用客戶端模式
只不過我發現如果不使用client_mode,也就是都是server模式時寫入性能還是很強的,但是讀取有點搓。
[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條。
用圖形看看比較直觀
從這個數據可以看出來,在這種都是服務端的模式下,寫入性能基本穩定,在達到200線程時出現衰減;而讀取則基本是線性的,到100線程差不多也就到頂了。
與redis的對比
原本是想和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萬,這到底會是什麼原因呢?
不管如何這是一次簡單的測試與嘗試,結果與預期有點偏差,繼續學習深入瞭解吧。