TokuDB性能測試報告

TokuDB做爲MySQL的大數據(Big Data)存儲引擎受到人們的廣泛關注。TokuDB擁有很高的壓縮比(官方稱最大可達25倍),能夠在很大的數據上建立大量的索引,並保持性能不降低。咱們來實測一下其真實性能如何?
做者:吳雙橋 騰訊雲數據庫工程師        
出處:騰雲閣文章
----------------------------------------------------
html

 

一 、背景介紹

近年來,TokuDB做爲MySQL的大數據(Big Data)存儲引擎受到人們的廣泛關注。其架構的核心基於一種新的叫作分形樹(Fractal Trees)的索引數據結構,該結構是緩存無關的,即便索引數據大小超過內存性能也不會降低,也即沒有內存生命週期和碎片的問題。mysql

特別引人注意的是,TokuDB擁有很高的壓縮比(官方稱最大可達25倍),能夠在很大的數據上建立大量的索引,並保持性能不降低。同時,TokuDB支持ACID和MVCC,還有在線修改表結構(Live Schema Modification)以及增長的複製性能等特性,使其在某些特定的應用領域(如日誌存儲與分析)有着獨特的優點。ios

在TokuDB的應用場景中,一般是數據庫插入操做的量遠遠大於讀取的量,於是本此測試主要針對TokuDB的插入性能以及壓縮比,以InnoDB做爲參考基準。算法

2、測試環境搭建

測試使用的機器爲高配機型,內存大於100G,CPU型號爲Intel(R) Xeon(R) CPU E5系列,數據盤使用的是SSD硬盤。sql

MySQL TokuDB版本使用的是 5.6.28-76.1,按照Percona網站上的安裝方法使用插件的方式進行安裝,見官網教程。使用MySQL命令查看:數據庫

+--------------------+---------+--------------+------+------------+
| Engine             | Support | Transactions | XA   | Savepoints |
+--------------------+---------+--------------+------+------------+
| InnoDB             | YES     | YES          | YES  | YES        | 
| CSV                | YES     | NO           | NO   | NO         | 
| MyISAM             | YES     | NO           | NO   | NO         | 
| BLACKHOLE          | YES     | NO           | NO   | NO         | 
| MEMORY             | YES     | NO           | NO   | NO         | 
| TokuDB             | DEFAULT | YES          | YES  | YES        | 
| MRG_MYISAM         | YES     | NO           | NO   | NO         | 
| ARCHIVE            | YES     | NO           | NO   | NO         | 
| FEDERATED          | NO      | NULL         | NULL | NULL       | 
| PERFORMANCE_SCHEMA | YES     | NO           | NO   | NO         | 
+--------------------+---------+--------------+------+------------+

能夠看到TokuDB引擎已經就緒,並被設置爲了默認的存儲引擎。緩存

3、測試工具與變量

一、測試工具選擇

如今開源可用的MySQL基準測試工具備不少,如mysqlslap,MySQL Benchmark Suite,Super Smack,Database Test Suite,TPCC和sysbench等。綜合工具的功能、易用性還有流行程度,最終選定操做簡單但功能強大的sysbench做爲測試工具。在sysbench 0.5版本中,已經開始支持Lua腳本,使用修改起來很是靈活。另外,測試壓縮比直接使用的mysqldump工具。安全

二、測試變量

插入性能相關的變量

除去根據機器硬件特性配置的常規優化參數,對於存儲引擎插入性能影響最大的是:是否將事務和binlog同步刷新到硬盤。微信

須要特別說明的是,還有一個比較重要的指標,便是否開啓了DIRECT IO功能,因爲在測試環境InnoDB開啓了DIRECT IO,並能提升總體的性能,而TokuDB在測試機型上沒法開啓DIRECT IO功能,因此在這點上InnoDB有相對的優點。數據結構

InnoDB 相關

對於InnoDB來講,控制這個功能的參數爲innodb_flush_log_at_trx_commitsync_binlog
innodb_flush_log_at_trx_commit參數指定了InnoDB在事務提交後的日誌寫入頻率。具體來講:

  1. innodb_flush_log_at_trx_commit取值爲 0 時,log buffer 會 每秒寫入到日誌文件並刷寫(flush)到硬盤。但每次事務提交不會有任何影響,也就是 log buffer 的刷寫操做和事務提交操做沒有關係。在這種狀況下,MySQL性能最好,但若是 mysqld 進程崩潰,一般會致使最後 1s 的日誌丟失。
  2. 當取值爲 1 時,每次事務提交時,log buffer 會被寫入到日誌文件並刷寫到硬盤。這也是默認值。這是最安全的配置,但因爲每次事務都須要進行硬盤I/O,因此也最慢。
  3. 當取值爲 2 時,每次事務提交會寫入日誌文件,但並不會當即刷寫到硬盤,日誌文件會每秒刷寫一次到硬盤。這時若是 mysqld 進程崩潰,因爲日誌已經寫入到系統緩存,因此並不會丟失數據;在操做系統崩潰的狀況下,一般會致使最後 1s 的日誌丟失。
    在實際的生產系統中,innodb_flush_log_at_trx_commit會在1和2之間選擇。通常來講,對數據一致性和完整性要求比較高的應用場景,會將其值設置爲1。

sync_binlog參數指定了 MySQL 的二進制日誌同步到硬盤的頻率。若是MySQL autocommit開啓,那麼每一個語句都寫一次binlog,不然每次事務寫一次。

  1. 默認值爲 0,不主動同步binlog的寫入,而依賴於操做系統自己不按期把文件內容flush到硬盤。
  2. 設置爲 1 時,在每一個語句或者事務後會同步一次binlog,即便發生意外崩潰時也最多丟失一個事務的日誌,於是速度較慢。

一般狀況下,innodb_flush_log_at_trx_commitsync_binlog配合起來使用,本次性能測試覆蓋了同步刷新日誌和異步刷新日誌兩種策略。

TokuDB 相關

TokuDB中與InnoDB相似的指標爲tokudb_commit_synctokudb_fsync_log_period。與innodb_flush_log_at_trx_commit的含義相似,tokudb_commit_sync指定當事務提交的時候,是否要刷新日誌到硬盤上。

  1. 默認開啓,值爲1。也就是每次事務提交時,log buffer 會被寫入到日誌文件並刷寫到硬盤。
  2. 若是設置爲 0,每次事務提交會寫入日誌文件,但並不會當即刷寫到硬盤,日誌文件會每隔一段時間刷寫一次到硬盤。這個時間間隔由tokudb_commit_sync指定。

tokudb_fsync_log_period指定多久將日誌文件刷新到硬盤,TukuDB的log buffer總大小爲 32 MB且不可更改。默認爲 0 秒,此時若是tokudb_commit_sync設置爲開啓,那麼這個值默認爲 1 分鐘。

tokudb_commit_synctokudb_fsync_log_period一般也是配合起來使用,本次性能測試覆蓋了兩種典型的組合策略。

壓縮比相關的變量

大多數選擇使用TokuDB的場景,都很是重視它的存儲壓縮比,於是在實際應用場景中總會配套使用某種壓縮算法。當前TokuDB支持的壓縮算法有,quicklz, zlib, lzma, snappy,固然還有不壓縮uncompressed。關於壓縮算法的討論,能夠參考官方博客的一篇分析文章

本次測試會結合真實的數據來從壓縮比、耗時兩個方面來檢驗上面幾個不一樣的壓縮算法。TokuDB能夠經過在配置文件中設置tokudb_row_format來指定不一樣的壓縮算法,它們的取值分別是:TOKUDB_QUICKLZTOKUDB_ZLIBTOKUDB_LZMATOKUDB_SNAPPY。值得注意的是,zlib算法是TokuDB官方最新版本的默認算法,也是現今支持TokuDB的雲服務商的默認推薦算法。

sysbench壓縮工具相關的變量

sysbench針對mysql壓測的參數有不少,這裏選取的是與實際應用場景最爲相關的兩個參數:表數量以及線程數量。表數量對應的是數據庫實際在同時寫入的表的數量,線程數對應的到MySQL數據庫上的鏈接。其餘的參數,如表的大小,是不是事務等可能影響總體的插入性能,但影響並不顯著,這裏只選取最主要的兩個參數進行分析。

三、測試方法

本測試的採用的方式爲經典的控制變量法。這裏的變量有:採用的存儲引擎類型,是否同步刷新日誌,採用的壓縮算法,以及另外兩個與sysbench相關的參數:壓測的線程數量和壓測的表數量。其中,壓縮算法的選擇只是在四種算法中選擇一種,因此並不與其餘變量交叉測試。這樣以存儲引擎和同步刷新日誌來劃分測試,能夠將整個測試數據分爲四個大類:

  1. InnoDB & 同步刷新日誌
  2. InnoDB & 異步刷新日誌
  3. TokuDB & 同步刷新日誌
  4. TokuDB & 異步刷新日誌

在每一個大類下,對壓測線程數量和壓測表數量進行交叉測試。壓測表數量取值可能爲[1, 2, 4, 8, 12, 16],線程數的可能取值爲[1, 2, 4, 8, 16, 24, 32, 48, 64, 80],於是每一個大類下進行6 * 10 = 60 次壓測,每次壓測寫入2,000,000 條數據,對每次壓測進行插入性能統計。

4、測試結果分析

一、InnoDB & 同步刷新日誌

innodb_flush_log_at_trx_commit設置爲1,sync_binlog設置爲1,也便是保證數據最安全:同步刷新log到硬盤,而且針對每一個事務同步一次binlog。測試的狀況見下表:

表數/插入TPS/線程數 1 2 4 8 12 16
1 5645.54 5678.40 5711.15 5687.44 5660.76 5708.54
2 10995.42 10921.06 11023.25 11017.88 11038.06 10902.12
4 18732.14 18724.20 18882.65 18935.62 18890.46 17997.52
8 33291.35 33379.37 33372.19 33842.15 30576.58 34048.53
16 54560.36 56346.20 57358.33 57454.11 57571.72 57989.96
24 66230.44 70813.87 73871.31 68764.22 68019.27 67538.82
32 66855.54 80153.06 84885.82 84387.96 76404.04 84920.13
48 56788.96 85778.22 93914.45 97055.96 84041.31 96790.49
64 55640.96 83342.88 95736.42 92667.25 96560.51 83598.00
80 58408.18 75858.18 60683.99 60491.26 60177.24 64290.13

用更直觀的圖表來展現:

能夠看到:

  1. 在線程數比較少的時候(不高於24個,即總CPU數目的一半),數據表的個數對總體的性能影響很小;當線程數較多時才顯示出區別:相同線程數下,增長表數目可提高數據庫總體吞吐量
  2. InnoDB總體性能在48線程時達到頂峯,也即達到CPU的總數目,說明InnoDB能充分利用硬件多CPU的特性
  3. 在線程數或者表數量很小的時候,增長線程數或者表數量能夠線性地提高性能,在實際環境中值得注意;而在線程數量超過物理CPU數量時,總體插入性能會降低

二、InnoDB & 異步刷新日誌

innodb_flush_log_at_trx_commit設置爲2,sync_binlog設置爲 0,日誌文件會每秒刷寫一次到硬盤,而且不主動同步binlog的寫入,而依賴於操做系統自己不按期把文件內容flush到硬盤。測試的狀況見下表:

表數/插入TPS/線程數 1 2 4 8 12 16
1 7751.83 7776.78 7741.86 7739.29 7770.41 7662.18
2 15199.98 14952.94 15252.04 15184.54 15186.76 15176.68
4 29075.83 29194.62 29228.09 29204.63 29625.60 29406.31
8 53578.10 51007.42 53116.44 54029.60 53291.41 52173.69
16 61002.65 71383.45 74656.36 75597.66 76305.24 76412.77
24 52758.54 70906.04 78472.49 81999.99 80430.52 82896.78
32 51740.38 68061.25 79936.12 82063.79 84966.86 83667.26
48 50961.62 65962.79 79952.45 85511.97 86223.38 86718.83
64 53378.76 65758.29 74224.26 76779.63 75368.30 76614.14
80 55056.88 66799.11 73969.11 62867.60 62039.68 63572.61

用更直觀的圖表來展現:

能夠看到與InnoDB Sync的狀況有所不一樣:

  1. 異步的狀況,隨着線程數的增長,插入性能提高較快,在16個線程的時候已經接近峯值
  2. 插入TPS的峯值比同步狀況的峯值低,這個與以往SATA/SAS磁盤環境下的MySQL優化經驗不匹配;經過iostat查看SSD盤的使用率很低,只有百分之幾,於是SSD硬盤條件下的InnoDB的優化策略須要持續改進

三、TokuDB & 同步刷新日誌

tokudb_commit_sync設置爲1,tokudb_fsync_log_period設置爲0,也就是每次事務提交時,log buffer 會被寫入到日誌文件並刷寫到硬盤。

表數/插入TPS/線程數 1 2 4 8 12 16
1 6506.16 6533.51 6514.36 6505.52 6581.28 6588.60
2 12335.72 12323.07 12494.74 12572.37 12600.94 12623.45
4 22726.24 23001.47 23331.96 23854.47 24267.20 24060.65
8 34935.53 38952.86 40093.37 41687.61 42472.60 44021.98
16 30777.25 42145.63 50293.47 55585.24 58956.65 59804.16
24 28102.26 38306.27 44420.44 47960.77 50440.59 52436.36
32 26227.49 35677.10 39627.22 40717.32 42562.45 44657.12
48 23335.33 30574.98 34961.22 34289.79 34819.25 35367.41
64 28923.69 36267.50 35228.70 35306.85 30393.76 29644.79
80 28323.74 33808.39 34203.47 35249.88 27757.45 32269.39

用圖表來展現:

能夠看到:

  1. 出乎意料的是,TokuDB在線程數16的時候插入TPS達到峯值,也就是說TokuDB並無徹底利用起多物理CPU的優點
  2. 對比InnoDB線程數從1~16的狀況能夠看到,TokuDB在相同條件下比InnoDB的性能還要高;而在線程數增多的時候,TokuDB的插入TPS在逐漸減少,而InnoDB在線程數超過物理CPU個數的時,插入TPS纔開始降低,說明TokuDB還有很大的優化空間

四、TokuDB & 異步刷新日誌

線程數/插入TPS/表數 1 2 4 8 12 16
1 6478.74 6514.03 6571.31 6555.92 6462.55 6588.75
2 12388.24 12433.75 12417.53 12457.83 12629.21 12597.90
4 22915.61 22265.08 24002.63 24248.57 22596.18 24323.07
8 35078.08 39179.46 39583.82 39505.79 42549.19 43493.89
16 30017.06 42012.43 46019.37 58790.76 60294.11 61057.96
24 27675.70 37873.94 45151.54 45075.48 49145.73 52417.81
32 26078.90 35496.19 39891.16 38888.13 43570.03 44882.92
48 23340.20 32392.89 35164.66 33858.16 34209.27 35350.72
64 29522.80 36475.76 36969.68 32381.53 32160.18 32589.76
80 27976.86 33483.40 34994.01 34977.62 30259.96 32680.34

用圖表來展現:

對比以前的圖標,能夠看到:

  1. 與InnoDB不一樣的是,是否開啓log的同步對TokuDB的插入性能影響不大,TokuDB SyncTokuDB Async二者的圖形形狀幾乎同樣
  2. 與同步的狀況相似,TokuDB在線程數16的時候插入TPS就達到峯值,有很大的優化空間

五、壓縮算法選擇

壓縮算法測試使用的實際的運行數據作測試,原來用InnoDB存儲的日誌數據爲92GB,用mysqldump工具導出後爲79GB。測試表是典型的日誌存儲表,其結構以下:

+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| a     | int(11)      | NO   | PRI | NULL    | auto_increment | 
| b     | bigint(20)   | NO   | MUL | 0       |                | 
| c     | varchar(30)  | NO   |     |         |                | 
| d     | varchar(20)  | NO   |     |         |                | 
| e     | varchar(30)  | NO   |     |         |                | 
| f     | text         | NO   |     | NULL    |                | 
| g     | varchar(300) | NO   |     |         |                | 
| h     | int(11)      | NO   |     | 0       |                | 
| i     | int(11)      | NO   |     | 0       |                | 
| j     | int(11)      | NO   |     | 0       |                | 
| k     | int(11)      | NO   |     | 0       |                | 
+-------+--------------+------+-----+---------+----------------+

依次將TokuDB的tokudb_row_format設置爲不一樣的壓縮算法,獲得其導入後的實際存儲空間以及導入時間,測試結果以下:

壓縮算法/項目 存儲大小 導入時間
snappy 12GB 47min40s
quicklz 7.1GB 47min21s
zlib 5.7GB 48min9s
lzma 4.7GB 47min10s

從表中能夠觀察到:

  1. 幾種壓縮算法耗時差很少,相差很小
  2. 不一樣的壓縮算法的壓縮比差別較大,snappy壓縮比較小,約爲6.6倍;壓縮比最大的lzma爲16.8倍
  3. zlib做爲官方選擇的默認壓縮算法,在壓縮比和CPU消耗上有較好的平衡,壓縮比爲13.8倍

結合在測試過程當中持續觀察CPU的使用狀況,lzma算法在運行過程當中CPU使用率在600%~700%左右,而zlib算法CPU使用率在80%~180%之間擺動。於是,在實際生產環境中,若是沒有特殊的考慮,建議使用zlib壓縮算法。

5、討論與結論

本次測試以InnoDB爲參考,主要測試TokuDB的寫入性能以及存儲壓縮比。經過不一樣場景下的對比測試,能夠得出幾個觀點:

  1. InnoDB現階段插入性能有優點,性能大約高出30%左右
  2. TokuDB雖然沒有充分利用硬件的能力,可是已經表現出強大的足夠高的性能,考慮到TokuDB的成熟度,後面它還有較大的提高空間,能夠持續關注其後續進展
  3. TokuDB選擇日誌同步或者異步刷新對性能影響不大,建議默認選擇同步日誌保護數據
  4. TokuDB在數據壓縮存儲上有絕對的優點,十幾倍的壓縮比對於冷備數據存儲有着極大的吸引力

值得一提的是,InnoDB性能表現優異部分緣由可歸功於InnoDB的成熟度,可靈活的配置許多參數以適應特定的應用場景,而TokuDB暴露出的優化參數不多,不能根據硬件配置調整一些重要參數。綜上,雖然TokuDB在現階段還沒成熟,但已經表現出強大的性能以及突出的特性,應該做爲某些特定應用場景的首選。

 

 

------------------------------
獲取更多雲計算技術乾貨,可請前往騰訊雲技術社區
微信公衆號:騰訊雲技術社區( QcloudCommunity)

 

相關文章
相關標籤/搜索