關於MySQL的基準測試

什麼是基準測試

當咱們對數據庫進行優化後,只有進行測量系統性能才能知道優化是否有效,這種測量的方式就是基準測試。基準測試的定義以下:html

基準測試是一種測量和評估軟件性能指標的活動用於創建某個時刻的性能基準,以便當系統發生軟/硬件變化時,從新進行基準測試以評估變化對性能的影響前端

咱們能夠這樣認爲:mysql

基準測試是針對系統設置的一種壓力測試,能夠用來觀察系統在不一樣壓力下的行爲。評估系統的容量,觀察系統如何處理不一樣的數據。git

可是基於測試不等同於壓力測試:github

  • 基於測試:直接、簡單、易於比較,用於評估服務器的處理能力。基準測試可能不關心業務邏輯,所使用的查詢和業務的真實性能夠和業務環節沒有關係
  • 壓力測試:對真實的業務數據進行測試,得到真實系統所能承受的壓力。壓力測試須要針對不一樣的主題,所使用的數據和查詢也是真實用到的

對MySQL進行基準測試的目的:web

  • 一、創建MySQL服務器的性能基準線,肯定當前MySQL服務器的運行狀況
  • 二、模擬比當前系統更高的負載,以找出系統的擴展瓶頸。增長數據庫的併發,觀察QPS、TPS的變化,以肯定併發量與性能最優的關係
  • 三、測試不一樣的硬件、軟件和操做系統配置
  • 四、證實新的硬件設備是否配置正確

如何進行基準測試

一般來講,基準測試有兩種方式:sql

  • 一、對整個系統進行基準測試:從系統的入口進行測試(網站Web前端,手機APP前端)
    • 優勢:可以測試整個系統的性能,包括web服務器緩存、數據庫等;能反映出系統中各個組件接口之間的性能問題,體現真實性能情況
    • 缺點:測試用例設計複雜,消耗時間長
  • 二、單獨對MySQL進行基準測試:僅測試系統中的MySQL服務
    • 優勢:測試用例設計簡單,所需耗時少
    • 缺點:沒法全面瞭解整個系統的性能基線

MySQL基準測試的常見指標:數據庫

  • 單位時間內所處理的事務數(TPS)
  • 單位時間內所處理的查詢數(QPS)
  • 併發數量:同時處理的查詢請求數量
  • 單個測試任務的響應時間
    • 包含:平均響應時間、最小響應時間、最大響應時間及各時間所佔百分比

基準測試中容易忽略的問題:緩存

  • 使用生產環境數據進行測試時,只使用了部分數據,可能會致使測試結果不許確
    • 推薦:使用數據庫的全量備份數據來進行測試
  • 在多用戶場景中,只作了單用戶的測試
    • 推薦:使用多線程併發測試
  • 在單服務器上測試分佈式應用
    • 推薦:應使用相同的架構進行測試
  • 反覆執行同一查詢,問題在於一樣的SQL語句容易緩存命中,沒法反應真實查詢性能。而在實際的環境中查詢方式多是不盡相同的

基準測試的步驟:bash

  • 一、選擇是對整個系統仍是某一個組件進行測試,還須要肯定使用什麼樣的數據進行測試
  • 二、準備測試數據的收集腳本,一般須要儘量多的收集當前系統的信息,例如CPU使用率、IO、網絡流量、狀態與計數器信息等
  • 三、編寫腳本分析第二步所收集的基準測試信息,最後得出測試結果

收集腳本和分析腳本示例

基準測試數據的收集腳本:

#!/bin/bash
# 腳本的運行間隔
INTERVAL=5
# 建立數據文件的存儲目錄
STORE_DIR=/home/mysql/benchmarks
mkdir -p $STORE_DIR
# 將收集的數據存儲到哪一個目錄下,以及文件前綴
PREFIX=$STORE_DIR/$INTERVAL-sec-status
# 設置腳本的運行標識
RUNFILE=$STORE_DIR/running
touch $RUNFILE && echo "1" > $RUNFILE
# mysql的用戶名和密碼
USER=root
PWD=123456
# mysql命令所在的路徑
MYSQL="/usr/local/mysql/bin/mysql -u$USER -p$PWD"
# 記錄當前mysql的全局變量
$MYSQL -e "show global variables" >> mysql-variables

# 運行標識文件存在就會一直循環
while test -e $RUNFILE; do
    # 定義腳本運行時的當前時間
    file=$(date +%F_%I)
    # 實現間隔運行該循環
    sleep=$(date +%s.%N | awk '{print 5 - ($1 % 5)}')
    sleep $sleep

    ts="$(date +"TS %s.%N %F %T")"
    # 獲取系統負載信息
    loadavg="$(uptime)"
    # 記錄系統負載信息
    echo "$ts $loadavg" >> $PREFIX-${file}-status
    # 記錄當前mysql的全局變量信息
    $MYSQL -e "show global status" >> $PREFIX-${file}-status &
    echo "$ts $loadavg" >> $PREFIX-${file}-innodbstatus
    # 記錄當前 innodb 的狀態信息
    $MYSQL -e "show engine innodb status" >> $PREFIX-${file}-innodbstatus &
    echo "$ts $loadavg" >> $PREFIX-${file}-processlist
    # 記錄當前mysql所有鏈接信息列表
    $MYSQL -e "show full processlist\G" >> $PREFIX-${file}-processlist &
    echo $ts
done

echo Exiting because $RUNFILE does not exists

測試數據分析腳本:

#!/bin/bash
awk '
   BEGIN {
     printf "#ts date time load QPS";
     fmt=" %.2f";
   }
   /^TS/ {
   ts = substr($2,1,index($2,".")-1);
   load = NF -2;
   diff = ts - prev_ts;
   printf "\n%s %s %s %s",ts,$3,$4,substr($load,1,length($load)-1);
   prev_ts=ts;
   }
   /Queries/{
   printf fmt,($2-Queries)/diff;
   Queries=$2
   }
   ' "$@"

### 使用示例 ###
# sh ./analyze.sh ${測試數據文件路徑}
# 如:sh ./analyze.sh /home/mysql/benchmarks/5-sec-status-2020-01-11_04-status

Mysql基準測試工具之mysqlslap

通常來講,咱們都不會本身去編寫基準測試的腳本,由於都有現成的工具。例如,mysql 5.1以上版本都自帶了mysqlslap這個基準測試工具。因爲是自帶的也無需進行單獨的安裝,該工具位於mysql的bin目錄下。

功能簡介:

  • 模擬服務器負載,並輸出相關統計信息
  • 能夠指定測試的查詢語句,也可使用該工具自動生成的測試語句

經常使用參數說明:

參數 說明
--concurrency 併發數量,即模擬的客戶端數量,能夠指定多個,使用逗號分隔
--iterations 指定測試的運行次數
--auto-generate-sql 使用系統自動生成的SQL腳原本進行測試
--auto-generate-sql-add-autoincrement 在自動生成的表中增長自增ID
--auto-generate-sql-load-type 指定測試中使用的查詢類型(取值:read, write, update, mixed),默認mixed
--auto-generate-sql-write-number 指定初始化數據時所生成的數據量
--engine 要測試表的存儲引擎,容許指定多個,使用逗號分隔
--no-drop 指定不清理測試數據
--number-of-queries 指定每個鏈接執行的查詢次數
--debug-info 指定輸出額外的內存及CPU統計信息
--number-char-cols 指定測試表中包含的int類型的數量
--number-int-cols 指定測試表中包含的varchar類型的數量
--create-schema 指定用於執行測試的數據庫的名稱
--query 用於指定自定義的SQL腳本
--only-print 指定該參數時,不會運行測試腳本,而是把生成的腳本打印出來

使用示例:

[root@localhost ~]# mysqlslap -uroot -p123456 --concurrency=1,50,100,200 --iterations=3 --number-int-cols=5 --number-char-cols=5 --auto-generate-sql --auto-generate-sql-add-autoincrement --engine=myisam,innodb --number-of-queries=10 --create-schema=test

運行該測試後,截取的部分輸出片斷以下:

Benchmark
    # 運行的是myisam引擎的測試
    Running for engine myisam
    # 運行全部查詢的平均秒數
    Average number of seconds to run all queries: 0.020 seconds
    # 運行全部查詢的最小秒數
    Minimum number of seconds to run all queries: 0.018 seconds
    # 運行全部查詢的最大秒數
    Maximum number of seconds to run all queries: 0.022 seconds
    # 運行查詢的客戶端數
    Number of clients running queries: 1
    # 每一個客戶端的平均查詢數 
    Average number of queries per client: 10

Benchmark
    Running for engine innodb
    Average number of seconds to run all queries: 0.049 seconds
    Minimum number of seconds to run all queries: 0.042 seconds
    Maximum number of seconds to run all queries: 0.059 seconds
    Number of clients running queries: 1
    Average number of queries per client: 10

Mysql基準測試工具之sysbench

除了 mysqlslap 這個mysql自帶的基準測試工具以外,還有一個經常使用的工具就是 sysbench。sysbench的功能比mysqlslap更多一些,能測試的點也更全面一些。sysbench除了能夠測試MySQL外,還能測試系統的CPU、IO、內存等方面。

安裝sysbench

sysbench的GitHub倉庫地址及源碼安裝文檔以下:

通常系統中不會自帶sysbench工具,須要咱們自行安裝,我這裏採用源碼編譯安裝的方式進行安裝。首先到以下地址複製源碼包的下載連接:

而後到Linux上使用wget命令進行下載:

[root@txy-server ~]# cd /usr/local/src
[root@txy-server /usr/local/src]# wget https://github.com/akopytov/sysbench/archive/1.0.19.tar.gz

安裝編譯sysbench時所依賴的一些庫:

[root@txy-server /usr/local/src]# yum -y install make automake libtool pkgconfig libaio-devel mariadb-devel openssl-devel

接着將下載好的源碼包進行解壓縮,並進入到解壓後的目錄:

[root@txy-server /usr/local/src]# tar -zxvf 1.0.19.tar.gz
[root@txy-server /usr/local/src]# cd sysbench-1.0.19/

最後參考如下步驟完成編譯安裝:

[root@txy-server /usr/local/src/sysbench-1.0.19]# ./autogen.sh
[root@txy-server /usr/local/src/sysbench-1.0.19]# ./configure --with-mysql-includes=/usr/local/mysql/include --with-mysql-libs=/usr/local/mysql/lib
[root@txy-server /usr/local/src/sysbench-1.0.19]# make && make install

等待完成編譯安裝後,測試是否安裝成功。我這裏報了個找不到庫文件的錯誤:

[root@txy-server /usr/local/src/sysbench-1.0.19]# sysbench --version
sysbench: error while loading shared libraries: libmysqlclient.so.21: cannot open shared object file: No such file or directory

解決方式是創建一個該文件的軟鏈接到/usr/lib64/目錄下:

[root@txy-server /usr/local/src/sysbench-1.0.19]# ln -s /usr/local/mysql/lib/libmysqlclient.so.21  /usr/lib64/

再次測試,執行成功:

[root@txy-server /usr/local/src/sysbench-1.0.19]# sysbench --version
sysbench 1.0.19

sysbench的使用

sysbench的命令格式以下:

sysbench [options]... [testname] [command]

一、options,是指定測試參數,如下是使用sysbench測試MySQL時經常使用的參數:

  • --mysql-db:用於指定基準測試的數據庫名稱,該數據庫必須是已存在的
  • --mysql_storage_engine:指定測試的MySQL存儲引擎
  • --tables:執行測試的表的數量
  • --table_size:指定每一個表中的數據量
  • --threads:指定測試的併發線程數量
  • --max-time:指定最大測試時間,單位爲秒
  • --report-interval:指定間隔多長時間就輸出一次統計信息,單位爲秒
  • --mysql-socket:指定mysql的.sock文件路徑,用於鏈接mysql
  • --mysql-user:指定用於測試時鏈接mysql的用戶
  • --mysql-password:指定mysql用戶的密碼
  • 關於其餘參數詳見官方文檔

二、testname,是指定內置的測試類型或測試腳本。內置的測試類型有以下取值:

  • fileio:測試文件系統I/O性能
  • cpu:測試cpu性能
  • memory:測試內存性能
  • threads:測試線程性能
  • mutex:測試互斥鎖性能
  • 執行sysbench [testname] help,能夠查看各個測試類型所支持的參數

除內置測試類型之外的測試,就須要指定測試腳本。sysbench的測試腳本須要使用lua語言編寫,能夠根據實際需求編寫自已的測試腳本,也可使用sysbench自帶的測試腳本。sysbench自帶的lua腳本以下:

[root@txy-server ~]# ls /usr/local/share/sysbench
bulk_insert.lua  # 用於測試大量的insert操做性能
oltp_common.lua  # 公共文件,給其餘腳本引用的,不可直接使用
oltp_delete.lua  # 用於測試oltp下的delete操做性能
oltp_insert.lua  # 用於測試oltp下的insert操做性能
oltp_point_select.lua   # 用於測試oltp下的定點查詢性能,例如根據主鍵查詢
oltp_read_only.lua   # 用於測試oltp下的只讀性能
oltp_read_write.lua  # 用於測試oltp下的讀寫性能
oltp_update_index.lua  # 用於測試更新索引字段的性能
oltp_update_non_index.lua  # 用於測試更新無索引字段操做的性能
oltp_write_only.lua  # 用於測試oltp下的寫操做性能
select_random_points.lua  # 用於測試隨機定點查詢的性能
select_random_ranges.lua  # 用於測試隨機範圍讀取的性能
...
  • Tips:不一樣版本的sysbench存放測試腳本的路徑可能不太同樣,須要自行確認

三、command,則是指定一些測試操做,例如運行測試、清除數據或準備數據等:

  • prepare:用於測試開始前準備測試數據
  • run:用於測試數據準備完成後,執行測試
  • cleanup:用於測試執行完成後清理測試數據

sysbench基準測試示例

一、測試CPU性能

如下命令可讓cpu找出10000之內的素數,並統計計算所需耗時,以此得知cpu的性能。須要注意的是,這種方式測試的是單核心性能,而非多核性能:

[root@txy-server ~]# sysbench --cpu-max-prime=10000 cpu run

測試結果以下:

# CPU速度
CPU speed:
    # 每秒事件數
    events per second:  1039.79

General statistics:
    # 計算出全部素數的總耗時
    total time:                          10.0005s  
    # 總的事件數
    total number of events:              10400

Latency (ms):
         # 計算出一個素數的最低耗時
         min:                                    0.94
         # 平均計算出一個素數的耗時
         avg:                                    0.96
         # 計算出一個素數的最長耗時
         max:                                    9.43
         # 95%狀況是1.01毫秒計算出一個素數
         95th percentile:                        1.01
         # 合計耗時
         sum:                                 9994.05

# 線程公平性
Threads fairness:
    events (avg/stddev):           10400.0000/0.00
    execution time (avg/stddev):   9.9941/0.00

二、測試系統I/O性能

測試I/O性能須要先準備測試數據,測試數據的大小須要大於物理內存。命令以下:

# 該命令會生成127個測試文件,這些文件合計4G大小
[root@txy-server ~]# sysbench --file-total-size=4G fileio prepare
...
Creating file test_file.125
Creating file test_file.126
Creating file test_file.127
4294967296 bytes written in 39.00 seconds (105.04 MiB/sec).
[root@txy-server ~]#

數據準備好後,執行測試:

[root@txy-server ~]# sysbench --threads=8 --file-total-size=4G --file-test-mode=rndrw --report-interval=1 fileio run

參數說明:

  • --threads=8:設置併發線程數爲8
  • --file-test-mode=rndrw:指定文件測試模式爲隨機讀寫,即測試磁盤I/O的隨機讀寫性能
  • --report-interval=1:指定每秒輸出一次統計信息

測試結果以下:

File operations:
    reads/s:                      2089.75
    writes/s:                     1392.67
    fsyncs/s:                     4553.64

Throughput:
    # 每秒讀取
    read, MiB/s:                  32.65
    # 
    written, MiB/s:               21.76

General statistics:
    total time:                          10.0778s
    total number of events:              79973

Latency (ms):
         min:                                    0.00
         avg:                                    1.00
         max:                                   58.42
         95th percentile:                        3.13
         sum:                                79895.62

Threads fairness:
    events (avg/stddev):           9996.6250/43.23
    execution time (avg/stddev):   9.9870/0.01

最後執行cleanup操做,清除測試數據:

[root@txy-server ~]# sysbench --file-total-size=4G fileio cleanup

三、測試MySQL性能

因爲sysbench內置的測試類型沒有MySQL,因此在使用sysbench測試MySQL時,testname須要指定爲測試腳本的路徑。sysbench自帶了一些MySQL的測試腳本,因此無特殊需求的狀況下,咱們也無需本身去編寫測試腳本。接下來,進行一個簡單的演示,看看如何使用測試腳原本測試MySQL的性能。

首先也是須要準備數據,命令以下:

[root@txy-server ~]# sysbench --mysql_storage_engine=innodb --table_size=10000 --mysql-db=test --tables=10 --mysql-socket=/tmp/mysql.sock --mysql-user=root --mysql-password=123456 /usr/local/share/sysbench/oltp_read_write.lua prepare
  • Tips:該腳本用於測試OLTP下的讀寫性能。另外,筆者這裏爲了方便就直接使用root帳戶,在實際測試中,務必建立一個用於測試的帳戶

執行測試:

[root@txy-server ~]# sysbench --mysql_storage_engine=innodb --table_size=10000 --mysql-db=test --tables=10 --mysql-socket=/tmp/mysql.sock --mysql-user=root --mysql-password=123456 /usr/local/share/sysbench/oltp_read_write.lua run

測試結果以下:

SQL statistics:
    queries performed:
        # 讀取操做的總數
        read:                            10444
        # 寫操做的總數
        write:                           2984
        # 其餘操做的總數,例如commit等
        other:                           1492
        # 總共執行的操做數量
        total:                           14920
    # 每秒執行的事務數,即TPS,這裏爲每秒74.48次
    transactions:                        746    (74.48 per sec.)
    # 每秒查詢的數量,即QPS,這裏爲每秒1489.53次
    queries:                             14920  (1489.53 per sec.)
    # 忽略的錯誤次數
    ignored errors:                      0      (0.00 per sec.)
    # 重連次數
    reconnects:                          0      (0.00 per sec.)

General statistics:
    total time:                          10.0150s
    total number of events:              746

Latency (ms):
         min:                                    8.86
         avg:                                   13.42
         max:                                   99.97
         95th percentile:                       20.00
         sum:                                10009.79

Threads fairness:
    events (avg/stddev):           746.0000/0.00
    execution time (avg/stddev):   10.0098/0.00

一樣,最後須要清理測試數據:

[root@txy-server ~]# sysbench --mysql_storage_engine=innodb --table_size=10000 --mysql-db=test --tables=10 --mysql-socket=/tmp/mysql.sock --mysql-user=root --mysql-password=123456 /usr/local/share/sysbench/oltp_read_write.lua cleanup

若是想要知道測試腳本具體支持哪些參數,其查看方式和內置測試類型是同樣的,只不過把測試類型的名稱換成了腳本而已:

[root@txy-server ~]# sysbench /usr/local/share/sysbench/oltp_read_write.lua help
相關文章
相關標籤/搜索