InfluxDB讀寫性能測試

来源:http://www.cnblogs.com/MikeZhang/archive/2017/02/12/InfluxDBTest20170212.html
-Advertisement-
Play Games

今天進行了InfluxDB和MySQL的對比測試,這裡記錄下結果,也方便我以後查閱。 操作系統: CentOS6.5_x64InfluxDB版本 : v1.1.0MySQL版本:v5.1.73CPU : Intel(R) Core(TM) i5-2320 CPU @ 3.00GHz記憶體 :12G硬碟 ...


今天進行了InfluxDB和MySQL的對比測試,這裡記錄下結果,也方便我以後查閱。

操作系統: CentOS6.5_x64
InfluxDB版本 : v1.1.0
MySQL版本:v5.1.73
CPU : Intel(R) Core(TM) i5-2320 CPU @ 3.00GHz
記憶體 :12G
硬碟 :SSD 

一、MySQL讀寫測試

測試準備

初始化SQL語句:

CREATE DATABASE testMysql;
CREATE TABLE `monitorStatus` (
    `system_name` VARCHAR(20) NOT NULL,
    `site_name` VARCHAR(50) NOT NULL,
    `equipment_name` VARCHAR(50) NOT NULL,
    `current_value` DOUBLE NOT NULL,
    `timestamp` BIGINT(20) NULL DEFAULT NULL,
    INDEX `system_name` (`system_name`),
    INDEX `site_name` (`site_name`),
    INDEX `equipment_name` (`equipment_name`),
    INDEX `timestamp` (`timestamp`)
)
ENGINE=InnoDB;

單寫測試代碼(insertTest1.c):

#include <stdlib.h>  
#include <stdio.h>  
#include <time.h>
#include "mysql/mysql.h"

#define N 100

int main()
{
    MYSQL *conn_ptr;  
    int res;  
    int t,i,j;
    int64_t tstamp = 1486872962;        
    srand(time(NULL));
    t=0;
    conn_ptr = mysql_init(NULL);  
    if (!conn_ptr)
    {  
        printf("mysql_init failed\n");  
        return EXIT_FAILURE;  
    }  
    conn_ptr = mysql_real_connect(conn_ptr,"localhost","root","","testMysql",0,NULL,0);  
    if (conn_ptr)
    {  
        for(i=1;i<= 10000;i++)
        {
            mysql_query(conn_ptr,"begin");
            for(j=0;j<N;j++,t++)
            {
                char query[1024]={0};

                sprintf(query,"insert into monitorStatus values ('sys_%d','s_%d','e_%d','0.%02d','%lld');",
                    //j%10,(t+i)%10,(t+j)%10,(t+i+j)%100,tstamp);
                    j%10,(t+i)%10,(t+j)%10,rand()%100,tstamp);
                //printf("query : %s\n",query);
                res = mysql_query(conn_ptr,query);

                if (!res)
                {   
                    //printf("Inserted %lu rows\n",(unsigned long)mysql_affected_rows(conn_ptr));   
                }
                else
                {   
                    fprintf(stderr, "Insert error %d: %sn",mysql_errno(conn_ptr),mysql_error(conn_ptr));  
                }
                if(j%10 == 0) tstamp+=1;
            }
            mysql_query(conn_ptr,"commit");
            //printf("i=%d\n",i);
        }
    }
    else
    {  
        printf("Connection failed\n");  
    }  
    mysql_close(conn_ptr);  
    return EXIT_SUCCESS;  
}
View Code

可根據情況調整測試代碼中的N參數。

單讀測試代碼(queryTest1.c):

#include <stdio.h>  
#include <stdlib.h>  
#include "mysql/mysql.h"

int main()
{  
    MYSQL *conn_ptr;  
    MYSQL_RES *res_ptr;  
    MYSQL_ROW sqlrow;  
    MYSQL_FIELD *fd;  
    int res, i, j;  

    conn_ptr = mysql_init(NULL);  
    if (!conn_ptr)
    {  
        return EXIT_FAILURE;  
    }  
    conn_ptr = mysql_real_connect(conn_ptr,"localhost","root","","testMysql", 0, NULL, 0);  
    if (conn_ptr)
    {  
        res = mysql_query(conn_ptr,"select * from `monitorStatus` where system_name='sys_8' and site_name='s_9' and equipment_name='e_6' order by timestamp desc limit 10000;");

        if (res)
        {         
            printf("SELECT error:%s\n",mysql_error(conn_ptr));     
        }
        else
        {        
            res_ptr = mysql_store_result(conn_ptr);             
            if(res_ptr)
            {               
                printf("%lu Rows\n",(unsigned long)mysql_num_rows(res_ptr));   
                j = mysql_num_fields(res_ptr);          
                while((sqlrow = mysql_fetch_row(res_ptr)))  
                {  
                    continue;
                    for(i = 0; i < j; i++)         
                        printf("%s\t", sqlrow[i]);                
                    printf("\n");          
                }              
                if (mysql_errno(conn_ptr))
                {                      
                    fprintf(stderr,"Retrive error:s\n",mysql_error(conn_ptr));               
                }        
            }        
            mysql_free_result(res_ptr);        
        }  
    }
    else
    {  
        printf("Connection failed\n");  
    }  
    mysql_close(conn_ptr);  
    return EXIT_SUCCESS;  
}  
View Code

Makefile文件:

all:
    gcc -g insertTest1.c -o insertTest1 -L/usr/lib64/mysql/ -lmysqlclient
    gcc -g queryTest1.c -o queryTest1 -L/usr/lib64/mysql/ -lmysqlclient

clean:
    rm -rf insertTest1
    rm -rf queryTest1    

測試數據記錄

磁碟空間占用查詢:

使用du方式(新資料庫,僅為測試):

du -sh /var/lib/mysql

查詢特定表:

use information_schema;
select concat(round(sum(DATA_LENGTH/1024/1024), 2), 'MB') as data from TABLES where table_schema='testMysql' and table_name='monitorStatus';

測試結果:

  • 100萬條數據

    [root@localhost mysqlTest]# time ./insertTest1
    
    real    1m20.645s
    user    0m8.238s
    sys    0m5.931s
    
    [root@localhost mysqlTest]# time ./queryTest1
    10000 Rows
    
    real    0m0.269s
    user    0m0.006s
    sys    0m0.002s

     

    原始數據 : 28.6M
    du方式 : 279MB
    sql查詢方式: 57.59MB
    寫入速度: 12398 / s
    讀取速度: 37174 / s

  • 1000萬條數據
    root@localhost mysqlTest]# time ./insertTest1
    
    real    7m15.003s
    user    0m48.187s
    sys    0m33.885s
    
    
    [root@localhost mysqlTest]# time ./queryTest1
    10000 Rows
    
    real    0m6.592s
    user    0m0.005s
    sys    0m0.002s

     

    原始數據 : 286M
    du方式 : 2.4G
    sql查詢方式: 572MB
    寫入速度: 22988 / s
    讀取速度: 1516 / s

  • 3000萬條數據
    [root@localhost mysqlTest]# time ./insertTest1
    
    real    20m38.235s
    user    2m21.459s
    sys    1m40.329s
    [root@localhost mysqlTest]# time ./queryTest1
    10000 Rows
    
    real    0m4.421s
    user    0m0.004s
    sys    0m0.004s

     

    原始數據 : 858M
    du方式 : 7.1G
    sql查詢方式: 1714MB
    寫入速度: 24228 / s
    讀取速度: 2261 / s

二、InfluxDB讀寫測試

測試準備

需要將InfluxDB的源碼放入 go/src/github.com/influxdata 目錄

單寫測試代碼(write1.go):

package main

import (
    "log"
    "time"
    "fmt"
    "math/rand"
    "github.com/influxdata/influxdb/client/v2"
)

const (
    MyDB = "testInfluxdb"
    username = "root"
    password = ""
)

func queryDB(clnt client.Client, cmd string) (res []client.Result, err error) {
    q := client.Query{
        Command:  cmd,
        Database: MyDB,
    }
    if response, err := clnt.Query(q); err == nil {
        if response.Error() != nil {
            return res, response.Error()
        }
        res = response.Results
    } else {
        return res, err
    }
    return res, nil
}

func writePoints(clnt client.Client,num int) {
    sampleSize := 1 * 10000
    rand.Seed(42)
    t := num
    bp, _ := client.NewBatchPoints(client.BatchPointsConfig{
        Database:  MyDB,
        Precision: "us",
    })

    for i := 0; i < sampleSize; i++ {
        t += 1
        tags := map[string]string{
            "system_name": fmt.Sprintf("sys_%d",i%10),
            "site_name":fmt.Sprintf("s_%d", (t+i) % 10),
            "equipment_name":fmt.Sprintf("e_%d",t % 10),
        }
        fields := map[string]interface{}{
            "value" : fmt.Sprintf("%d",rand.Int()),
        }
        pt, err := client.NewPoint("monitorStatus", tags, fields,time.Now())
        if err != nil {
            log.Fatalln("Error: ", err)
        }
        bp.AddPoint(pt)
    }

    err := clnt.Write(bp)
    if err != nil {
        log.Fatal(err)
    }

    //fmt.Printf("%d task done\n",num)
}

func main() {
    // Make client
    c, err := client.NewHTTPClient(client.HTTPConfig{
        Addr: "http://localhost:8086",
        Username: username,
        Password: password,
    })

    if err != nil {
        log.Fatalln("Error: ", err)
    }
    _, err = queryDB(c, fmt.Sprintf("CREATE DATABASE %s", MyDB))
    if err != nil {
        log.Fatal(err)
    }

    i := 1
    for i <= 10000 {
        defer writePoints(c,i)
        //fmt.Printf("i=%d\n",i)
        i += 1
    }
    //fmt.Printf("task done : i=%d \n",i)

}
View Code

單讀測試代碼(query1.go):

package main

import (
    "log"
    //"time"
    "fmt"
    //"math/rand"
    "github.com/influxdata/influxdb/client/v2"
)

const (
    MyDB = "testInfluxdb"
    username = "root"
    password = ""
)

func queryDB(clnt client.Client, cmd string) (res []client.Result, err error) {
    q := client.Query{
        Command:  cmd,
        Database: MyDB,
    }
    if response, err := clnt.Query(q); err == nil {
        if response.Error() != nil {
            return res, response.Error()
        }
        res = response.Results
    } else {
        return res, err
    }
    return res, nil
}

func main() {
    // Make client
    c, err := client.NewHTTPClient(client.HTTPConfig{
        Addr: "http://localhost:8086",
        Username: username,
        Password: password,
    })

    if err != nil {
        log.Fatalln("Error: ", err)
    }
    q := fmt.Sprintf("select * from monitorStatus where system_name='sys_5' and site_name='s_1' and equipment_name='e_6' order by time desc limit 10000 ;")
    res, err2 := queryDB(c, q)
    if err2 != nil {
        log.Fatal(err)
    }
    count := len(res[0].Series[0].Values)
    log.Printf("Found a total of %v records\n", count)

}
View Code

測試結果記錄

查看整體磁碟空間占用:

du -sh /var/lib/influxdb/

查看最終磁碟空間占用:

du -sh /var/lib/influxdb/data/testInfluxdb 
  • 100萬條數據
    [root@localhost goTest2]# time ./write1
    real    0m14.594s
    user    0m11.475s
    sys    0m0.251s
    
    [root@localhost goTest2]# time ./query1
    2017/02/12 20:00:24 Found a total of 10000 records
    
    real    0m0.222s
    user    0m0.052s
    sys    0m0.009s

     

    原始數據 : 28.6M
    整體磁碟占用:27M
    最終磁碟占用:21M
    寫入速度: 68521 / s
    讀取速度: 45045 / s

  • 1000萬條數據

    [root@localhost goTest2]# time ./write1
    
    real    2m22.520s
    user    1m51.704s
    sys    0m2.532s
    
    [root@localhost goTest2]# time ./query1
    2017/02/12 20:05:16 Found a total of 10000 records
    
    real    0m0.221s
    user    0m0.050s
    sys    0m0.003s

    原始數據 : 286M
    整體磁碟占用:214M
    最終磁碟占用:189M 寫入速度: 70165 / s
    讀取速度: 45249 / s

  • 3000萬條數據
    [root@localhost goTest2]# time ./write1
    
    real    7m19.121s
    user    5m49.738s
    sys    0m8.189s
    [root@localhost goTest2]# ls
    query1  query1.go  write1  write1.go
    [root@localhost goTest2]# time ./query1
    2017/02/12 20:49:40 Found a total of 10000 records
    
    real    0m0.233s
    user    0m0.050s
    sys    0m0.012s

    原始數據 : 858M
    整體磁碟占用:623M
    最終磁碟占用:602M
    寫入速度: 68318 / s
    讀取速度: 42918 / s

三、測試結果分析

整體磁碟占用情況對比:

最終磁碟占用情況對比:

寫入速度對比:

讀取速度對比:

結論:

相比MySQL來說,InfluxDB在磁碟占用和數據讀取方面很占優勢,而且隨著數據規模的擴大,查詢速度沒有明顯的下降。
針對時序數據來說,InfluxDB有明顯的優勢。

好,就這些了,希望對你有幫助。

本文github地址:

https://github.com/mike-zhang/mikeBlogEssays/blob/master/2017/20170212_InfluxDB和MySQL的讀寫對比測試.md

歡迎補充 


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

-Advertisement-
Play Games
更多相關文章
  • 1.問題 今天重新安裝了ubuntu,PHP,MySQL,Apache,到測試CMS項目時發生一個錯誤: 驗證碼無法顯示出來。 2.解決: 2.1 使用 phpinfo檢查: 在項目根目錄創建一個test.php,並寫上上邊的代碼,測試檢查phpinfo.查找有沒有gd項,也就是有沒有開啟gd庫。 ...
  • 1. 環境搭建 ADT(Bundle) + JDK (安裝方式自行百度) ADT(Bundle) 集成了 Eclipse + ADT + android sdk jdk bin 裡面含 各種命令; lib 裡面含各種庫; 2. 程式員寫打程式怎麼執行? java 源程式 編譯 > 位元組碼文件 >在虛 ...
  • 重載:同一個類中,方法名相同,方法參數不同(參數個數、參數類型),返回類型無關,所以返回類型不能作為重載的區別依據。 重寫:子父類中,子類的方法名、參數位置、參數個數、返回類型和父類一致,方法體不同 重寫方法的規則如下: 1. 參數列表:必須與被重寫方法的參數列表完全匹配。 2. 返回類型:必須與超 ...
  • 例如: 判斷html節點的class是否有no-js。 1.jquery的實現方式 jquery源碼的實現方式: 源碼裡面用到了nodeType,nodeType是HTML DOM 的nodeType 屬性,nodeType 屬性返回以數字值返回指定節點的節點類型。常用的一般有三種: 例如,獲得 b ...
  • Filterizr 是一款功能強大的篩選過濾插件,它提供了多重篩選過濾方式,配合了css3的動畫效果。 線上實例 預設 回調函數 使用方法 <div class="sucaihuo"> <div class="filtr-item" data-category="1, 5"> <img src="i ...
  • 一、IIFE解釋 全拼Imdiately Invoked Function Expression,立即執行的函數表達式。 像如下的代碼所示,就是一個匿名立即執行函數: 二、括弧的意義 2.1 包住 的括弧的意義 這個括弧的目的,是為了把 轉化為表達式。像一些庫的源碼,喜歡用如下方式代替: 或者這種方 ...
  • 在Mvc模式大行其道的今天,後端通過各種Mvc框架實現視圖與數據模型的隔離,而前端這方面也發展迅速。vue實現了Dom與viewModel雙向綁定,使其視圖的更新影響模型,模型的更新影響視圖,你會不會覺得這就是Mvc庫呢,實則不然,因為他還差一個重要的C(也就是控制器)。以下是鄙人對Mvc的個人理解 ...
  • 什麼是Ajax Ajax(Asynchronous JavaScript and XML):翻譯成中文就是非同步的JavaScript和XML。 從功能上來看是一種在無需重新載入整個網頁的情況下能夠更新部分網頁的技術。 傳統的網頁 想要更新內容或者提交表單就要重新載入或刷新頁面。 使用ajax技術的網 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...