MySQL學習 - 基準測試

1. Introduction 

1.1 爲何須要有基準測試

  • 快速有效,瞭解系統在給定工做負荷下表現的方法
  • 確認系統,是否按照預期工做
  • 重現錯誤,輔助解決這些問題
  • 模擬更高負載,提早預測性能瓶頸,規劃業務增加

1.2 基準測試 & 真實測試

  • 基準測試 + 真實測試 : 只使用基準測試,case簡單很難反映出真實狀況。只使用真實測試,狀況複雜多變很難總結出確切結論


2. 設計基準測試的策略

2.1 我應該測試什麼 -> 全局基準測試 & MySQL基準測試

  • 何時使用全局基準測試
    • 想要測試一整個應用,連同  Web服務器+網絡+數據庫 的總體表現
    • 數據庫並不必定會是性能瓶頸,聯合全局+數據測試驗證這個結論
  • 何時只針對MySQL展開基準測試
    • 想要比較不一樣表,不一樣查詢語句間的性能差別
    • 針對應用中某個具體問題的測試

2.2 選擇測試指標

你必須得抱有必定目的:  "這個CPU相比與上一種是否是快一點?"   "這個索引好用嗎?"
根據測試指標,分析,解答你一開始的疑惑mysql

  • 吞吐量: 單位時間事務處理數量, 通常用TPS做爲單位
  • 響應時間: 完成某個指定請求消耗的時間,取95%,最好將結果繪圖方便理解
  • 併發性: 任意時間,同時發生的併發請求,你能夠在Sysbench中指定,好比我要求如今併發64請求,而後測試這種環境下的響應速度等指標
  • 原則: 設計出你想了解的更多指標,指定可接受範圍

2.3 數據集從那兒來

  • 最好的數據就是來自用戶真實使用的數據,你能夠選擇記錄一下高峯時段下一小時的請求記錄,爲了徹底重現服務的狀態,使用多線程安排這些請求
  • 若是沒有,或者真實記錄很是少,你須要模擬用戶的行爲,可是做假也要作的像一點,好比不要均勻分佈請求,請求門類有熱點非熱點的區別

2.4 記錄下運行時的系統狀態

  • 記錄下系統測試時的狀態. 常見的系統指標包含 CPU使用率,磁盤IO,網絡流量統計等數據記錄狀態的過程能夠由Shell腳本完成並保存,最好是先記錄最原始的數據稍後在清洗等。
  • 抵消影響因素.  
    • 保證系統狀態一致: 理論上最好保持系統狀態一致,你甚至須要爲此單獨重啓預熱系統
    • 內存&數據碎片度: 爲了保證內存的碎片度一致,可能須要每次快速格式化硬盤並分區
  • 其餘
    • 修改基準測試參數: 爲了達到最優效果,你可能會面臨參數調整的需求,一次修改儘量少的參數,使用二分法,從而得到最優參數
    • MySQL的默認參數:  MySQL的默認配置原則是儘可能消耗少資源,爲了得到性能的最大化,你須要逐步挑選出最適合你業務的參數
    • 若是出現了奇怪的數據,不要輕易丟棄: 嘗試分析/復現一下奇怪數據,會有一些新的發現,這多是你代碼上或者測試設計的有問題。沒有搞清楚前不要公佈測試結果

2.5 嘗試分析測試結果

  • 嘗試使用gnuplot繪圖或者R繪圖的方式,結合記錄下的數據繪圖,髒數據不要丟嘗試分析


3. 基準測試工具

3.1 全局測試工具

  • ab : 基於單個URL展開的壓力測試
  • http_load: 多個URL中隨機挑選的壓力測試
  • JMeter: 更加複雜,甚至能夠設置預熱時間,繪圖等

3.2 MySQL測試工具

  • sysbench: 多線程壓測工具,它能夠根據影響數據庫服務器性能的各類因素,對系統性能評估,這些因素包含:文件IO,操做系統調度器,內存分配等


4. 使用Sysbench測試計算機性能

4.1 sysbench  <全局參數>   --test=<測試類型>   <測試參數>  <行動>

  • 全局參數
    • num-threads      指定線程數量
    • max-request      測試全過程最多發出多少請求
    • max-time             超時設定
    • report-interval   每隔多久打印一次測試概況
    • mysql-host/port/socket/user/password/db
  • 測試類型
    • fileio / cpu / memory / threads / mutex / oltp / 指定腳本
  • 行動
    • preprare   準備測試所需數據
    • run              開始行動
    • cleanup    清理測試數據


4.2  fileio 型測試

sysbench    --test=fileio        <測試類型 - fileio測試>
            --file-num=10        <生成10個測試使用的文件>
            --file-total-size=5G <全部文件的一共5G>
            prepare              <fileio測試 - 行動:準備文件>


sysbench    --max-time=180            <超時時間180秒>
            --max-requests=100000000  <最多10000000請求>
            --num-threads=16          <測試使用16線程>
            --init-rng=on             <使用隨機數生成器>
            --test=fileio             <測試類型 - fileio測試>

            --file-total-size=5G      <全部文件的一共5G>
            --file-test-mode=rndrw    <測試類型 - 隨機寫>
            --file-num=10             <生成10個測試使用的文件>
            run                       <行動類型 - 運行測試>

sysbench    --test=fileio             <測試類型 - fileio測試>
            --file-num=10             <生成10個測試使用的文件>
            --file-total-size=5G      <全部文件的一共5G>
            cleanup                   <行動類型 - 清除測試數據>
複製代碼


4.3 CPU性能測試

sysbench --test=cpu --cpu-max-prime=20000 run <計算2萬之內最大素數>複製代碼

假設如今針對兩臺電腦直接展開這樣的測試是不公平的,由於這裏線程數量被設置成1, 爲了能表現出CPU的最大威力,咱們應該以下設置線程數量git

sysbench    --test=cpu 
            --num-threads=`grep "processor" /proc/cpuinfo | wc -l` <使用所有核心>
            --cpu-max-prime=20000 
            run複製代碼


4.4 內存連續讀寫性能測試

sysbench    --test=memory           <測試內存>
            --memory-block-size=8K  <測試內存塊大小爲8k>
            --memory-total-size=1G  <總共數據傳輸大小1G>
            --num-threads=16        <線程數量16>
            run複製代碼


5. 使用Sysbench 測試數據庫性能

5.1 測試實例

sysbench 
            --mysql-host=127.0.0.1     <指定數據庫相關參數>
            --mysql-port=3166 
            --mysql-user=root 
            --mysql-password=123456    
            --test=oltp                <測試類型爲數據庫相關測試>
            --oltp_tables_count=1      <生成一張表>
            --oltp-table-size=1000000  <表裏有這些數據>
            --rand-init=on             
            prepare                    <行動: 準備對應數據>

sysbench 
            --mysql-host=127.0.0.1 
               --mysql-port=3166 
               --mysql-user=root 
               --mysql-password=123456 
               --test=tests/db/oltp.lua 
               --oltp_tables_count=1 
               --oltp-table-size=1000000 
               --num-threads=128 
               --oltp-read-only=off 
               --report-interval=10 
               --rand-type=uniform 
               --max-time=60 
               --max-requests=10000000
               run# 使用128線程測試60秒,每隔10秒發送一次測試狀況報告複製代碼


5.2  Lua腳本分析 

完整腳本github

local stmt_defs = {

   point_selects = {
      "SELECT c FROM sbtest%u WHERE id=?",
      t.INT},

   simple_ranges = {
      "SELECT c FROM sbtest%u WHERE id BETWEEN ? AND ?",
      t.INT, t.INT},

   sum_ranges = {
      "SELECT SUM(k) FROM sbtest%u WHERE id BETWEEN ? AND ?",
       t.INT, t.INT},

   order_ranges = {
      "SELECT c FROM sbtest%u WHERE id BETWEEN ? AND ? ORDER BY c",
       t.INT, t.INT},

   distinct_ranges = {
      "SELECT DISTINCT c FROM sbtest%u WHERE id BETWEEN ? AND ? ORDER BY c",
      t.INT, t.INT},

   index_updates = {
      "UPDATE sbtest%u SET k=k+1 WHERE id=?",
      t.INT},

   non_index_updates = {
      "UPDATE sbtest%u SET c=? WHERE id=?",
      {t.CHAR, 120}, t.INT},

   deletes = {
      "DELETE FROM sbtest%u WHERE id=?",
      t.INT},

   inserts = {
      "INSERT INTO sbtest%u (id, k, c, pad) VALUES (?, ?, ?, ?)",
      t.INT, t.INT, {t.CHAR, 120}, {t.CHAR, 60}},
}複製代碼

上面是真的開始執行的時候,sysbench會去執行的命令sql

CREATE TABLE sbtest%d(
  id %s,
  k INTEGER DEFAULT '0' NOT NULL,
  c VARCHAR(500) DEFAULT '' NOT NULL,
  pad CHAR(60) DEFAULT '' NOT NULL,
  %s (id)
) %s %s]]

複製代碼
CREATE TABLE sbtest%d(
  id %s,
  gmt_create datetime not null,
  gmt_modified datetime not null,
  k INTEGER DEFAULT '0' NOT NULL,
  c VARCHAR(500) DEFAULT '' NOT NULL,
  pad CHAR(60) DEFAULT '' NOT NULL,
  is_used INTEGER DEFAULT '0' NOT NULL,
  %s (id)
) %s %s]]複製代碼

這個則是在prepare階段會去作的事,建立一張這樣的表,你也能夠修改爲你這樣,而後對應的修改 run的時候所要操做的指令,而後 prepare - run - cleanup 就能夠了數據庫

相關文章
相關標籤/搜索