Ignite性能測試以及對redis的對比

来源:http://www.cnblogs.com/5207/archive/2016/11/22/6089209.html
-Advertisement-
Play Games

測試方法 為了對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條。

用圖形看看比較直觀
image

不使用客戶端模式

只不過我發現如果不使用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條。

用圖形看看比較直觀
image

從這個數據可以看出來,在這種都是服務端的模式下,寫入性能基本穩定,在達到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();
        }


    }
}

對比結果視圖
image

結束

原本我想著redis估計得秒了ignite,畢竟redis是這麼多系統正在使用的記憶體資料庫。ignite本身含有這麼多功能按理性能肯定是比不上才對,而且ignite組成集群後是需要進行數據分塊存取和備份的,而測試環境中redis則是單實例情況,這讓我沒太想明白啊。。還望有高手指點。。

看網上許多人測試的數據redis少點的4萬+,據說可以到10萬+。但我自己的測試環境差了點反正最多也沒過3萬,這到底會是什麼原因呢?

不管如何這是一次簡單的測試與嘗試,結果與預期有點偏差,繼續學習深入瞭解吧。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • oracle: 一、數據 db數據欄位如下: task_id task_name t.parent_task_id *** *** *** *** *** 000001 t1 *** *** 000002 t11 000001 *** 000005 t12 000001 *** 000003 t11 ...
  • 這是最基礎的用法: LISTAGG(XXX,XXX) WITHIN GROUP( ORDER BY XXX) 例: select listagg(oeid,',') within GROUP (order by oeid) ...
  • Master/Slave主從複製 主從複製MongoDB中比較常用的一種方式,如果要實現主從複製至少應該有兩個MongoDB實例,一個作為主節點負責客戶端請求,另一個作為從節點負責從主節點映射數據,提供數據備份,客戶端讀取等,推薦一主多從模式 MongoDB主從複製的實現方式: 主節點的操作會被記錄... ...
  • 11g新特性:Health Monitor Checks 一、什麼是Health Monitor Checks Health Monitor Checks能夠發現文件損壞,物理、邏輯塊損壞,undo、redo損壞,數據字典損壞等等。 Health Monitor Checks產生結果報告,它包含瞭解 ...
  • Sqoop的使用應該是Oozie裡面最常用的了,因為很多BI數據分析都是基於業務資料庫來做的,因此需要把mysql或者oracle的數據導入到hdfs中再利用mapreduce或者spark進行ETL,生成報表信息。 因此本篇的Sqoop Action其實就是運行一個sqoop的任務而已。 同樣ac ...
  • 1.SELECT DISTINCT 語句 關鍵詞DISTINCT用於返回唯一不同的值。 語法: SELECT DISTINCT 列名稱 FROM 表名稱 2.SELECT INTO語句 SELECT INTO語句從一個表中選取數據,然後把數據插入另一個表中。 SELECT INTO語句常用於創建表的 ...
  • 1. 【事件起因】 今天在做項目的時候,發現提供給客戶端的介面時間很慢,達到了2秒多,我第一時間,抓了介面,看了運行的sql,發現就是 2個sql慢,分別占了1秒多。 一個sql是 鏈接了5個表同時使用了 2個 order by和 1個limit的分頁 sql。 一個sql是上一個sql的count ...
  • 原文地址 1)、id列數字越大越先執行,如果說數字一樣大,那麼就從上往下依次執行,id列為null的就表是這是一個結果集,不需要使用它來進行查詢。 2)、select_type列常見的有: A:simple:表示不需要union操作或者不包含子查詢的簡單select查詢。有連接查詢時,外層的查詢為s ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...