做者介紹:吳雙橋 騰訊雲數據庫工程師html
本文首發騰雲閣 TokuDB性能測試報告mysql
近年來,TokuDB做爲MySQL的大數據(Big Data)存儲引擎受到人們的廣泛關注。其架構的核心基於一種新的叫作分形樹(Fractal Trees)的索引數據結構,該結構是緩存無關的,即便索引數據大小超過內存性能也不會降低,也即沒有內存生命週期和碎片的問題。ios
特別引人注意的是,TokuDB擁有很高的壓縮比(官方稱最大可達25倍),能夠在很大的數據上建立大量的索引,並保持性能不降低。同時,TokuDB支持ACID和MVCC,還有在線修改表結構(Live Schema Modification)以及增長的複製性能等特性,使其在某些特定的應用領域(如日誌存儲與分析)有着獨特的優點。算法
在TokuDB的應用場景中,一般是數據庫插入操做的量遠遠大於讀取的量,於是本此測試主要針對TokuDB的插入性能以及壓縮比,以InnoDB做爲參考基準。sql
測試使用的機器爲高配機型,內存大於100G,CPU型號爲Intel(R) Xeon(R) CPU E5系列,數據盤使用的是SSD硬盤。數據庫
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](https://www.qcloud.com/product/cdb?fromSource=gwzcw.5716.5716.5716) | 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引擎已經就緒,並被設置爲了默認的存儲引擎。安全
如今開源可用的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_flush_log_at_trx_commit
和sync_binlog
。 innodb_flush_log_at_trx_commit
參數指定了InnoDB在事務提交後的日誌寫入頻率。具體來講:
innodb_flush_log_at_trx_commit
取值爲 0 時,log buffer 會 每秒寫入到日誌文件並刷寫(flush)到硬盤。但每次事務提交不會有任何影響,也就是 log buffer 的刷寫操做和事務提交操做沒有關係。在這種狀況下,MySQL性能最好,但若是 mysqld 進程崩潰,一般會致使最後 1s 的日誌丟失。innodb_flush_log_at_trx_commit
會在1和2之間選擇。通常來講,對數據一致性和完整性要求比較高的應用場景,會將其值設置爲1。sync_binlog
參數指定了 MySQL 的二進制日誌同步到硬盤的頻率。若是 MySQL autocommit開啓,那麼每一個語句都寫一次binlog,不然每次事務寫一次。
一般狀況下,innodb_flush_log_at_trx_commit
和sync_binlog
配合起來使用,本次性能測試覆蓋了同步刷新日誌和異步刷新日誌兩種策略。
TokuDB中與InnoDB相似的指標爲TokuDB_commit_sync
和TokuDB_fsync_log_period
。與innodb_flush_log_at_trx_commit
的含義相似,TokuDB_commit_sync
指定當事務提交的時候,是否要刷新日誌到硬盤上。
TokuDB_commit_sync
指定。TokuDB_fsync_log_period
指定多久將日誌文件刷新到硬盤,TukuDB的log buffer總大小爲 32 MB且不可更改。默認爲 0 秒,此時若是TokuDB_commit_sync
設置爲開啓,那麼這個值默認爲 1 分鐘。
TokuDB_commit_sync
和TokuDB_fsync_log_period
一般也是配合起來使用,本次性能測試覆蓋了兩種典型的組合策略。
大多數選擇使用TokuDB的場景,都很是重視它的存儲壓縮比,於是在實際應用場景中總會配套使用某種壓縮算法。當前TokuDB支持的壓縮算法有,quicklz, zlib, lzma, snappy,固然還有不壓縮uncompressed。關於壓縮算法的討論,能夠參考官方博客的一篇分析文章。
本次測試會結合真實的數據來從壓縮比、耗時兩個方面來檢驗上面幾個不一樣的壓縮算法。TokuDB能夠經過在配置文件中設置TokuDB_row_format
來指定不一樣的壓縮算法,它們的取值分別是:TokuDB_QUICKLZ
, TokuDB_ZLIB
, TokuDB_LZMA
和TokuDB_SNAPPY
。值得注意的是,zlib算法是TokuDB官方最新版本的默認算法,也是現今支持TokuDB的雲服務商的默認推薦算法。
sysbench針對MySQL壓測的參數有不少,這裏選取的是與實際應用場景最爲相關的兩個參數:表數量以及線程數量。表數量對應的是數據庫實際在同時寫入的表的數量,線程數對應的到MySQL數據庫上的鏈接。其餘的參數,如表的大小,是不是事務等可能影響總體的插入性能,但影響並不顯著,這裏只選取最主要的兩個參數進行分析。
本測試的採用的方式爲經典的控制變量法。這裏的變量有:採用的存儲引擎類型,是否同步刷新日誌,採用的壓縮算法,以及另外兩個與sysbench相關的參數:壓測的線程數量和壓測的表數量。其中,壓縮算法的選擇只是在四種算法中選擇一種,因此並不與其餘變量交叉測試。這樣以存儲引擎和同步刷新日誌來劃分測試,能夠將整個測試數據分爲四個大類:
在每一個大類下,對壓測線程數量和壓測表數量進行交叉測試。壓測表數量取值可能爲[1, 2, 4, 8, 12, 16],線程數的可能取值爲[1, 2, 4, 8, 16, 24, 32, 48, 64, 80],於是每一個大類下進行6 * 10 = 60 次壓測,每次壓測寫入2,000,000 條數據,對每次壓測進行插入性能統計。
將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 |
用更直觀的圖表來展現:
能夠看到:
將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
的狀況有所不一樣:
將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 |
用圖表來展現:
能夠看到:
線程數/插入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 |
用圖表來展現:
對比以前的圖標,能夠看到:
TokuDB Sync
和TokuDB Async
二者的圖形形狀幾乎同樣壓縮算法測試使用的實際的運行數據作測試,原來用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 |
從表中能夠觀察到:
結合在測試過程當中持續觀察CPU的使用狀況,lzma算法在運行過程當中CPU使用率在600%~700%左右,而zlib算法CPU使用率在80%~180%之間擺動。於是,在實際生產環境中,若是沒有特殊的考慮,建議使用zlib壓縮算法。
本次測試以InnoDB爲參考,主要測試TokuDB的寫入性能以及存儲壓縮比。經過不一樣場景下的對比測試,能夠得出幾個觀點:
值得一提的是,InnoDB性能表現優異部分緣由可歸功於InnoDB的成熟度,可靈活的配置許多參數以適應特定的應用場景,而TokuDB暴露出的優化參數不多,不能根據硬件配置調整一些重要參數。綜上,雖然TokuDB在現階段還沒成熟,但已經表現出強大的性能以及突出的特性,應該做爲某些特定應用場景的首選。
隨時隨地閱讀雲計算技術乾貨
微博 @騰訊雲
知乎 騰訊雲技術社區
掃碼關注微信公衆號