TokuDB 性能测试报告

本文对比测试了TokuDB与InnoDB在不同场景下的写入性能及存储压缩比。结果显示,TokuDB虽未充分利用多核优势,但在压缩比方面表现出极大优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者介绍:吴双桥 腾讯云数据库工程师。


一 、背景介绍

近年来, 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 网站上的安装方法使用插件的方式进行安装,见官网教程(https://www.percona.com/doc/percona-server/5.6/tokudb/tokudb_installation.html) 。使用 MySQL 命令查看:

  1. +--------------------+---------+--------------+------+------------+

  2. | Engine             | Support | Transactions | XA   | Savepoints |

  3. +--------------------+---------+--------------+------+------------+

  4. | InnoDB             | YES     | YES          | YES  | YES        |

  5. | CSV                | YES     | NO           | NO   | NO         |

  6. | MyISAM             | YES     | NO           | NO   | NO         |

  7. | BLACKHOLE          | YES     | NO           | NO   | NO         |

  8. | MEMORY             | YES     | NO           | NO   | NO         |

  9. | TokuDB             | DEFAULT | YES          | YES  | YES        |

  10. | MRG_MYISAM         | YES     | NO           | NO   | NO         |

  11. | ARCHIVE            | YES     | NO           | NO   | NO         |

  12. | FEDERATED          | NO      | NULL         | NULL | NULL       |

  13. | PERFORMANCE_SCHEMA | YES     | NO           | NO   | NO         |

  14. +--------------------+---------+--------------+------+------------+

可以看到 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_commit sync_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_commit sync_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。关于压缩算法的讨论,可以参考官方博客的一篇分析文章(https://www.percona.com/blog/2016/03/09/evaluating-database-compression-methods/)。

本次测试会结合真实的数据来从压缩比、耗时两个方面来检验上面几个不同的压缩算法。TokuDB 可以通过在配置文件中设置tokudb_row_format来指定不同的压缩算法,它们的取值分别是:TOKUDB_QUICKLZ, TOKUDB_ZLIB, TOKUDB_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。测试表是典型的日志存储表,其结构如下:

  1. +-------+--------------+------+-----+---------+----------------+

  2. | Field | Type         | Null | Key | Default | Extra          |

  3. +-------+--------------+------+-----+---------+----------------+

  4. | a     | int(11)      | NO   | PRI | NULL    | auto_increment |

  5. | b     | bigint(20)   | NO   | MUL | 0       |                |

  6. | c     | varchar(30)  | NO   |     |         |                |

  7. | d     | varchar(20)  | NO   |     |         |                |

  8. | e     | varchar(30)  | NO   |     |         |                |

  9. | f     | text         | NO   |     | NULL    |                |

  10. | g     | varchar(300) | NO   |     |         |                |

  11. | h     | int(11)      | NO   |     | 0       |                |

  12. | i     | int(11)      | NO   |     | 0       |                |

  13. | j     | int(11)      | NO   |     | 0       |                |

  14. | k     | int(11)      | NO   |     | 0       |                |

  15. +-------+--------------+------+-----+---------+----------------+

依次将 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 在现阶段还没成熟,但已经表现出强大的性能以及突出的特性,应该作为某些特定 应用场景的首选。

点击「阅读原文」可了解更多详细信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值