隨着數據量越來越大,越來越頻繁的遇到需要進行結構拆分的情況,每一次拆分都耗時很久,並且需要多方配合,非常的不想搞這個事情。於是在@zolker的提醒下想到了13年開源tokuDB,來解決我們迫在眉睫的容量問題。
坊間流傳tokuDB有如下幾個看着令人垂涎欲滴的特點,正好符合我們實際環境的需求,故針對每個特點進行了針對性測試:
1、高壓縮比,官方宣稱可以達到1:12。
2、高insert性能,官方稱至少比innodb高9倍。
3、可以在線添加索引和字段,速度快。
(前提:由於是為了解決線上的實際問題,故本次驗證並不會按照嚴格的測試規范進行,所得數據也不是tokuDB的極限數據,只是在實際業務上的表現)
高壓縮比:
原有數據庫容量1126G,使用tokudb之后,壓縮到76G,壓縮比達到驚人的14倍。
高insert性能:
簡單比較追同步的性能,同時在innodb和tokudb上阻塞同步3分鍾,然后觀察追同步的性能(不代表最大性能,因為會受限於mysql單線程追同步的瓶頸。io不會被充分利用到)
基本環境為SAS服務器,12*300G 15000轉SAS盤,BP size相同。
可以明顯看到在不改變基本配置,不增加多線程復制的情況下,tokudb的追同步性能高於innodb,大概在1.9倍。
在線添加字段和索引:
測試目標表為425MB,所在服務器均為10塊盤做RAID5的SSD服務器。
從下圖可以看出
- 添加索引,innodb快,tokudb慢
- 刪除索引,innodb快,tokudb超快
- 增加字段,innodb慢,tokudb超快
- 刪除字段,innodb慢,tokudb超快
TokuDB在在線DDL操作的時候相對InnoDB有較大的優勢。在索引方面,刪除索引基本瞬間完成。在字段方案,添加/刪除字段基本都是瞬間完成。
具體我們可以看下面的操作記錄。
CREATE TABLE `timeline_1009` ( `uid` bigint(16) unsigned NOT NULL, `vflag` tinyint(4) unsigned NOT NULL DEFAULT '0', `status_id` bigint(16) unsigned NOT NULL, `source` int(6) unsigned NOT NULL DEFAULT '0', `fflag` int(6) unsigned NOT NULL DEFAULT '0', `mflag` tinyint(4) NOT NULL DEFAULT '0', PRIMARY KEY (`uid`) ) ENGINE=TokuDB DEFAULT CHARSET=utf8 ROW_FORMAT=TOKUDB_LZMA;
InnoDB操作記錄:
>create index idx_flag on timeline_1009 (mflag); Query OK, 0 rows affected (36.48 sec) >drop index idx_flag on timeline_1009; Query OK, 0 rows affected (0.29 sec) >alter table timeline_1009 add column test_flag tinyint; Query OK, 4549087 rows affected (28.64 sec) >alter table timeline_1009 drop column test_flag; Query OK, 4549087 rows affected (27.29 sec)
TokuDB操作記錄:
>create index idx_flag on timeline_1009(mflag); Query OK, 0 rows affected (56.56 sec) >drop index idx_flag on timeline_1009; Query OK, 0 rows affected (0.05 sec) >alter table timeline_1009 add column test_flag tinyint; Query OK, 0 rows affected (0.01 sec) >alter table timeline_1009 drop column test_flag; Query OK, 0 rows affected (0.00 sec)
innodb添加字段的時候會建立一個temp table,修改表結構后,會刪除原表,並將臨時表rename回原名字,所以就相當於對表進行了一次optimization,清理各種碎片,這也就是為什么add column的時候會有百萬級別的rows affected。但是可以很明顯的看到tokudb的rows affected為0,推測是tokudb在添加字段的時候,並不會采用innodb的方法。從官網的文檔中獲得的信息是,TokuDB會將添加字段的工作放在后台執行,而其快速的原因是將B-tree改為了Fractal-tree,其將隨機IO替換為了順序IO。領用Fractal-tree的特性,將HCAD命令廣播到所有行上,而不是想InnoDB那樣,需要open table並消耗很多的內存資源。
以上都是TokuDB的特點,接下來我們看看其對CPU、IOPS和RT的影響。以上3點是影響服務器負載和對外提供服務質量的關鍵數據。
測試背景,相同的slave,只不過引擎不通,在同一個時間點抓取數據,理論上認為承擔的服務量相等。
CPU消耗:
理論上經過大壓縮比的數據庫一定會比較消耗cpu的usr態,果然從下圖中我們可以看出,tokudb比innodb對usr態的cpu消耗要多,平均在2倍左右。
IOPS消耗:
根據官方文檔的說明,相同QPS的情況下,tokudb應該比innodb消耗更少的iops。我們從下面兩個圖可以看出,讀的IOPS並沒有太大的差別,但是寫的IOPS innodb比tokudb平均多消耗了5.5倍。
RT響應時間:
在響應時間上,由於整體數據庫的size變小了,測試目標庫innodb版本743G,tokudb版本61G。相對於BP=30G來說,明顯tokudb更占優勢。但是由於tokkudb的數據是經過高壓縮的,在響應時間上應該還會多一部分解壓的時間消耗,所以最終結果不好確認。
從測試結果看,tokudb的響應時間明顯高於innodb的,其平均值大概高2.2倍。看來如果上了tokudb,響應時間是需要付出的代價。
總結:
TokuDB的優點:1、高壓縮比 2、高insert性能 3、增刪字段秒級。
TokuDB的缺點:1、cpu usr態消耗高 2、響應時間變長。
總體來說,TokuDB的特性非常的吸引人,能解決我們很棘手的問題。但是,看上去很美的東西,一定會有坑存在,排雷將是我們下一步的重點工作,這也是決定TokuDB到底能不能真正在線上使用的關鍵。