TokuDB性能測試報告

作者:吳雙橋 騰訊雲數據庫工程師        

出處:騰雲閣文章

----------------------------------------------------


一 、背景介紹

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

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

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

二、測試環境搭建

測試使用的機器爲高配機型,內存大於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             | 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引擎已經就緒,並被設置爲了默認的存儲引擎。

三、測試工具與變量

1、測試工具選擇

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

2、測試變量

插入性能相關的變量

除去根據機器硬件特性配置的常規優化參數,對於存儲引擎插入性能影響最大的是:是否將事務和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數據庫上的連接。其他的參數,如表的大小,是否是事務等可能影響整體的插入性能,但影響並不顯著,這裏只選取最主要的兩個參數進行分析。

3、測試方法

本測試的採用的方式爲經典的控制變量法。這裏的變量有:採用的存儲引擎類型,是否同步刷新日誌,採用的壓縮算法,以及另外兩個與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 條數據,對每次壓測進行插入性能統計。

四、測試結果分析

1、InnoDB & 同步刷新日誌

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

表數/插入TPS/線程數12481216
15645.545678.405711.155687.445660.765708.54
210995.4210921.0611023.2511017.8811038.0610902.12
418732.1418724.2018882.6518935.6218890.4617997.52
833291.3533379.3733372.1933842.1530576.5834048.53
1654560.3656346.2057358.3357454.1157571.7257989.96
2466230.4470813.8773871.3168764.2268019.2767538.82
3266855.5480153.0684885.8284387.9676404.0484920.13
4856788.9685778.2293914.4597055.9684041.3196790.49
6455640.9683342.8895736.4292667.2596560.5183598.00
8058408.1875858.1860683.9960491.2660177.2464290.13

用更直觀的圖表來展示:

可以看到:

  1. 在線程數比較少的時候(不高於24個,即總CPU數目的一半),數據表的個數對整體的性能影響很小;當線程數較多時才顯示出區別:相同線程數下,增加表數目可提升數據庫整體吞吐量

  2. InnoDB整體性能在48線程時達到頂峯,也即達到CPU的總數目,說明InnoDB能充分利用硬件多CPU的特性

  3. 在線程數或者表數量很小的時候,增加線程數或者表數量可以線性地提升性能,在實際環境中值得注意;而在線程數量超過物理CPU數量時,整體插入性能會下降

2、InnoDB & 異步刷新日誌

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

表數/插入TPS/線程數12481216
17751.837776.787741.867739.297770.417662.18
215199.9814952.9415252.0415184.5415186.7615176.68
429075.8329194.6229228.0929204.6329625.6029406.31
853578.1051007.4253116.4454029.6053291.4152173.69
1661002.6571383.4574656.3675597.6676305.2476412.77
2452758.5470906.0478472.4981999.9980430.5282896.78
3251740.3868061.2579936.1282063.7984966.8683667.26
4850961.6265962.7979952.4585511.9786223.3886718.83
6453378.7665758.2974224.2676779.6375368.3076614.14
8055056.8866799.1173969.1162867.6062039.6863572.61

用更直觀的圖表來展示:

可以看到與InnoDB Sync的情況有所不同:

  1. 異步的情況,隨着線程數的增加,插入性能提升較快,在16個線程的時候已經接近峯值

  2. 插入TPS的峯值比同步情況的峯值低,這個與以往SATA/SAS磁盤環境下的MySQL優化經驗不匹配;通過iostat查看SSD盤的使用率很低,只有百分之幾,因而SSD硬盤條件下的InnoDB的優化策略需要持續改進

3、TokuDB & 同步刷新日誌

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

表數/插入TPS/線程數12481216
16506.166533.516514.366505.526581.286588.60
212335.7212323.0712494.7412572.3712600.9412623.45
422726.2423001.4723331.9623854.4724267.2024060.65
834935.5338952.8640093.3741687.6142472.6044021.98
1630777.2542145.6350293.4755585.2458956.6559804.16
2428102.2638306.2744420.4447960.7750440.5952436.36
3226227.4935677.1039627.2240717.3242562.4544657.12
4823335.3330574.9834961.2234289.7934819.2535367.41
6428923.6936267.5035228.7035306.8530393.7629644.79
8028323.7433808.3934203.4735249.8827757.4532269.39

用圖表來展示:

可以看到:

  1. 出乎意料的是,TokuDB在線程數16的時候插入TPS達到峯值,也就是說TokuDB並沒有完全利用起多物理CPU的優勢

  2. 對比InnoDB線程數從1~16的情況可以看到,TokuDB在相同條件下比InnoDB的性能還要高;而在線程數增多的時候,TokuDB的插入TPS在逐漸減小,而InnoDB在線程數超過物理CPU個數的時,插入TPS纔開始下降,說明TokuDB還有很大的優化空間

4、TokuDB & 異步刷新日誌

線程數/插入TPS/表數12481216
16478.746514.036571.316555.926462.556588.75
212388.2412433.7512417.5312457.8312629.2112597.90
422915.6122265.0824002.6324248.5722596.1824323.07
835078.0839179.4639583.8239505.7942549.1943493.89
1630017.0642012.4346019.3758790.7660294.1161057.96
2427675.7037873.9445151.5445075.4849145.7352417.81
3226078.9035496.1939891.1638888.1343570.0344882.92
4823340.2032392.8935164.6633858.1634209.2735350.72
6429522.8036475.7636969.6832381.5332160.1832589.76
8027976.8633483.4034994.0134977.6230259.9632680.34

用圖表來展示:

對比之前的圖標,可以看到:

  1. 與InnoDB不同的是,是否開啓log的同步對TokuDB的插入性能影響不大,TokuDB SyncTokuDB Async兩者的圖形形狀幾乎一樣

  2. 與同步的情況類似,TokuDB在線程數16的時候插入TPS就達到峯值,有很大的優化空間

5、壓縮算法選擇

壓縮算法測試使用的實際的運行數據做測試,原來用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設置爲不同的壓縮算法,得到其導入後的實際存儲空間以及導入時間,測試結果如下:

壓縮算法/項目存儲大小導入時間
snappy12GB47min40s
quicklz7.1GB47min21s
zlib5.7GB48min9s
lzma4.7GB47min10s

從表中可以觀察到:

  1. 幾種壓縮算法耗時差不多,相差很小

  2. 不同的壓縮算法的壓縮比差異較大,snappy壓縮比較小,約爲6.6倍;壓縮比最大的lzma爲16.8倍

  3. zlib作爲官方選擇的默認壓縮算法,在壓縮比和CPU消耗上有較好的平衡,壓縮比爲13.8倍

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

五、討論與結論

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

  1. InnoDB現階段插入性能有優勢,性能大約高出30%左右

  2. TokuDB雖然沒有充分利用硬件的能力,但是已經表現出強大的足夠高的性能,考慮到TokuDB的成熟度,後面它還有較大的提升空間,可以持續關注其後續進展

  3. TokuDB選擇日誌同步或者異步刷新對性能影響不大,建議默認選擇同步日誌保護數據

  4. TokuDB在數據壓縮存儲上有絕對的優勢,十幾倍的壓縮比對於冷備數據存儲有着極大的吸引力

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




------------------------------------------

獲取更多雲計算技術乾貨,可請前往 騰訊雲技術社區

我也會持續同步更新~

微信公衆號:騰訊雲技術社區( QcloudCommunity)


wKiom1jGFirgiVFNAAAvZ3cJzxs400.jpg


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章