MariaDB 10.1 和 MySQL 5.7.4-labs-tplc 性能测量更新
引言
本文是我的原博客 https://blog.mariadb.org/performance-evaluation-of-mariadb-10-1-and-mysql-5-7-4-labs-tplc 的后续。首先,我要感谢收到的所有评论。根据评论,有人担心看到的性能差异是否由于不同的配置设置所致。此外,我之前不知道 MySQL 中有一个配置变量可以实现类似于 MariaDB 的多线程刷新机制。为了弄清不同的配置变量或不同的默认设置是否是性能差异的原因,我进行了几轮新的测试。
测试 1
更改 buffer pool 实例的数量或 innodb thread concurrency 的值似乎对至少 LinkBench 基准测试的性能结果没有显著影响。但是,更改刷新线程的数量会产生影响。下面我将展示 MariaDB 和 MySQL 使用页面压缩的结果。最低那条线是之前已在 https://blog.mariadb.org/performance-evaluation-of-mariadb-10-1-and-mysql-5-7-4-labs-tplc/ 中展示的原始结果。
更改参数产生了影响,并且 LinkBench 基准测试的性能结果有所改善。然而,改进对两个服务器来说是相似的。显然,在这种配置下,MariaDB 在此基准测试中仍然优于 MySQL。下面是本次测试中使用的全套配置变量。
[mysqld] basedir=/usr/local/mysql user=root socket=/tmp/mysql.sock server_id=1 local_infile=1 pid-file=/tmp/server1.pid port=3306 max_connections = 3000 back_log = 1500 open_files_limit = 1500 table_open_cache = 520 table_open_cache_instances = 32 key_buffer_size = 16M query_cache_type = 0 join_buffer_size = 32K sort_buffer_size = 32K skip-grant-tables innodb_buffer_pool_size=50G innodb_use_native_aio=1 innodb_data_file_path=ibdata1:50M:autoextend innodb_file_per_table=1 innodb_open_files=100 innodb_flush_log_at_trx_commit=1 innodb_lock_wait_timeout = 120 innodb_doublewrite=0 innodb_buffer_pool_instances=16 innodb_mtflush_threads=16 innodb_compression_level=6 innodb_compression_algorithm=2 max-prepared-stmt-count=400000 innodb_fast_shutdown=0 innodb_log_buffer_size=256M innodb_log_files_in_group=3 innodb_log_file_size=8G innodb_thread_concurrency=32 innodb_flush_method = O_DIRECT innodb_write_io_threads=16 innodb_read_io_threads=16 innodb_max_dirty_pages_pct=90 skip-name-resolve innodb_adaptive_flushing=1 innodb_file_format=barracuda innodb_fast_shutdown=0 #used on MariaDB innodb_mtflush_threads=16 innodb_use_mtflush=1 #used on MySQL #innodb_page_cleaners=16 #innodb_compression_punch_hole=1 # IO innodb_checksum_algorithm=crc32 innodb_flush_neighbors=0 innodb_lru_scan_depth=2500 innodb_io_capacity=25000 innodb_io_capacity_max=35000 #xtradb ignore-builtin-innodb plugin-load=innodb=ha_innodb.so plugin-dir=/mnt/fiob/10.0-FusionIO/storage/innobase #innodb_log_block_size=4096 [mysql] local-infile=1 [client]
测试 2
在我还在测试不同配置设置时,一篇关于类似性能测量的优秀博客发表在 http://dimitrik.free.fr/blog/archives/2014/08/mysql-performance-analyzing-linkbench-workload-on-mysql-57-and-mariadb-101.html。这篇博客又使用了不同的配置(自然硬件也不同)。结果非常有趣,我决定尝试重复一遍。
我从使用未压缩表获得的结果开始,我的系统使用的是 Intel Xeon CPU e5-2690 2.90GHz,2 个插槽,8 个核心,使用超线程,即总共 32 个核心。我使用 CentOs 6.4 和 Linux 3.4.12。存储是 Fusion-io ioDrive2 Duo,驱动版本 3.3.3 build 716,固件 v7.2.5,格式化为 NVMFS。
与 DimitriK 博客中获得的结果存在明显差异。首先,两个服务器的结果都好得多。我使用的系统核心数量较少,但频率更高。此外,该系统使用了较新版本的 NVMFS。在我的结果中,我使用了 24 小时的测量时间和 150G 数据库。DimitriK 在他的博文中使用了 30 分钟。此外,我使用了几乎相同的配置,只有一个例外。我使用了与 innodb_page_cleaners 完全相同数量的 innodb_mtflush_threads。在我的结果中,MariaDB 的性能仍然优于 MySQL。但是,让我们也看看页面压缩的结果。
显然,这些新参数比之前使用的参数更好。我感谢 DimitriK 指出了这些。
MariaDB 和 MySQL 之间的差异更大,并且 MariaDB 的性能仍优于 MySQL。底线是我无法重复该博客中的结果。这个版本的 MariaDB 确实不包含 InnoDB 索引锁争用的修复,但这在这种环境下似乎不是问题。查看 performance schema 的数值,可以发现这一点。
仅供记录,这里是使用的配置变量。
[mysqld] basedir=/usr/local/mysql socket=/tmp/mysql.sock user=root port=3306 max_connections=4000 skip_grant_tables #myisam key_buffer_size = 4000M ft_max_word_len = 16 low_priority_updates = 2 #general table_open_cache = 8000 table_open_cache_instances=16 back_log=1500 query_cache_type = 0 #files innodb_file_per_table=1 innodb_file_format=Barracuda innodb_log_file_size=1024M innodb_log_files_in_group=12 innodb_open_files=4000 #buffers innodb_buffer_pool_size = 75000M innodb_buffer_pool_instances=32 innodb_log_buffer_size=64M #tune innodb_checksums=1 innodb_checksum_algorithm=crc32 innodb_doublewrite=0 innodb_support_xa=0 innodb_thread_concurrency=0 innodb_flush_log_at_trx_commit=1 innodb_flush_method=O_DIRECT innodb_max_dirty_pages_pct=90 innodb_max_dirty_pages_pct_lwm=10 innodb_lru_scan_depth=4000 #for MYSQL #innodb_page_cleaners=4 join_buffer_size=32K sort_buffer_size=32K innodb_use_native_aio=1 innodb_stats_persistent = 1 innodb_spin_wait_delay=6 #perf special innodb_adaptive_flushing=1 innodb_flush_neighbors=0 innodb_read_io_threads=16 innodb_write_io_threads=16 innodb_io_capacity=15000 innodb_purge_threads=4 innodb_max_purge_lag_delay=30000000 innodb_max_purge_lag=1000000 innodb_adaptive_hash_index=0 #monitoring innodb_monitor_enable = '%' performance_schema=ON performance_schema_instrument='%sync%=on' #mariadb innodb_compression_algorithm=2 innodb_use_mtflush=1 innodb_mtflush_threads=4 innodb_use_fallocate=1 innodb_use_atomic_writes=1 ignore-builtin-innodb plugin-load=ha_innodb.so plugin-dir=/mnt/fioa/MariaDB-10.1/storage/innobase
结论
我的观察
- 配置变量的值会显著影响性能,因此根据基准测试和硬件来调优变量以获得最佳性能非常重要。
- 我的原始博客中的性能测量结果是正确的,即使不是最优的。
- 我未能重复 DimitriK 博客中呈现的显著性能差异。一些可能的原因:
- 我们使用不同的发行版和硬件
- 博客使用了较短的 30 分钟测量时间(我不认为这是问题)
- 博客仅使用了未压缩的表(根据我的结果,这不是问题)
- 博客在 MariaDB 上使用了 XtraDB(作为默认值),这可能会产生一些影响,但不是全部
- 我使用了默认编译 (cmake . ; make )
- 由于 DimitriK 指出的索引锁争用,MariaDB 的性能不是最优的。这将在更高版本的 MariaDB 10.1 中修复。
是否有计划使用更经济的 IO(例如 8 块 10K SAS RAID 阵列)发布相同服务器版本在 Linkbench 上的基准测试结果?
SAS 通常并不更经济。按字节计算,SAS 更便宜。按 IOPs 计算,闪存更便宜。您的预算、数据库大小和 IOPs 需求是多少?
对于第一次测试。
为什么将 table_open_cache 从默认值 2000 减小到 520?为什么将 innodb_open_files 从其默认值(与 table_open_cache 相同)减小到 100?本次测试期间使用的 .ibd 文件总数是多少?
为什么将 open_files_limit 从其初始编译默认值 5000 减小到 1500,同时覆盖其根据 max_connections 设置为 3000 和 table_open_cache 设置为 520 的自动配置?这种设置组合应该会在 MySQL 服务器错误日志中产生一个“Changed limits”警告,告诉您您将 open_files_limits 设置得太低,服务器不得不降低 max_connections 和 table_open_cache 以适应您指定的文件句柄限制。该警告说了什么,或者它是否被其他设置抑制了?
除非您通过给出 open_files_limit 的值来覆盖它,否则用于 open_files_limit 的计算值是以下值中较高的一个:
1. 10 + max_connections + (table_open_cache * 2) = 4050
2. max_connections * 5 = 15000
3. 5000,编译内置的默认值。
因此,根据您的设置,open_files_limit 的预期计算值将是 15,000,但您将服务器限制为不超过 1,500,迫使其降低其他设置以适应该限制。
如果您没有将 table_open_cache 设置为其通常默认值以下,规则 1 将给出 7010,并且规则 2 的 15000 仍然会起主导作用。
您对这些设置的组合令人费解,因为您要求了一些设置,然后又使用了另一个设置来阻止服务器使用您设置的值。
像往常一样,对于表和表定义缓存,测试结束时 Opened_tables 和 Opened_table_definitions 的值是多少,以检查这些值是否至少足够,而不是导致大量冗余的表打开和关闭?
James Day,MySQL 高级首席支持工程师,Oracle
不确定这些在此案例中是否重要,因为 LinkBench 使用 3 个表。但他没有告诉我们 LinkBench 使用的客户端线程数或表是否使用了分区。所以也许这会很重要。
有 18 个 .ibd 文件,并且使用了分区。LinkBench 使用 64 个客户端。运行后 Opened_files 是 98,Opened_table_definitions 是 0。看来我在 open_table_cache 上打错了,应该是 15200,但这并不重要。我测试过了,对性能没有影响。
你好 Jan,
感谢分享结果!——结果和我的仍然完全不同,但我认为再耐心一些我们就能找到原因了..
首先我要问你的问题是:你在图表中显示的 TPS 数值是 MySQL/MariaDB 本身报告的还是 Linkbench 报告的?.. — 如果是 LinkBench 报告的,那能否展示数据库服务器本身报告的 Commit/sec 图表?..
然后:你提到在 PFS 报告的等待列表中未看到索引锁位于顶部.. — 你能否展示 MySQL 和 MariaDB 在“未压缩”测试中哪些等待项位于顶部?..
关于差异:不,我的测试中没有使用 XtraDB(据我所知,XtraDB 没有 MariaDB 配置选项,对吧? 😉 — 也不认为测试时长在此起作用,因为在你的测试中,TPS 水平随着时间推移下降得非常快,所以即使在 30 分钟内这种趋势也应该可见;也不认为硬件起很大作用..
好吧,为了澄清你的结果,你能不能在同一个 Fusion-io 设备上使用 EXT4 文件系统运行一个测试?(不使用任何压缩、原子操作、双写缓冲等)——这将显示进一步研究的基础结果.. 另外,别忘了监控 PFS 报告的互斥锁等待——这也将有助于澄清情况..
我的服务器上更详细的结果很快就会发布,敬请关注 😉
顺致敬意,
-Dimitri
是的,我使用了基准测试生成的数据。
你能分享你生成 commit 和索引争用结果的 select 语句吗,这样我至少可以使用相同的查询来获取结果,反正 index_lock 也会在那里显示出来。
在 10.0 和 10.1 中,XtraDB 是默认使用的,除非你使用 –ignore-builtin-innodb, –plugin-load=ha_innodb.so 并定义 plugin-dir。XtraDB 具有那些额外的 MariaDB 选项,因为我在那里实现了它们。
当然,我也可以使用 EXT4,让我看看。
但我认为我们真的应该投入精力思考如何更好地利用 FusionIO 硬件的潜力。根据 FusionIO 的说法,该卡在写入时可以达到约 1.2GB/s,而 MySQL 或 MariaDB 即使在加载阶段也远未达到此速度。
因此,可以测试一些方面来查看性能潜力。数据库中有很多因素会限制性能。序列化的 fsync,难以保持大的 I/O 队列深度(特别是在读取时),锁争用等等。
进行更多多实例测试并观察性能如何变化可能会很有趣(例如将 1 个 linkbench 分割成 2 个,使用 1/2 的 BP、客户端等)。
看看在 DRAM 延迟下进行日志写入意味着什么也会很有趣(使用 ramdisk 进行测试)。
此外,Mysql 长期以来一直使用缓冲日志写入。日志写入的 O_DIRECT 选项并不是真正有用,因为写入本身是通过一个_非常_繁忙的互斥锁完成的,这意味着访问后端存储的开销太大了。在这里考虑使用更细粒度的锁可能更有意义,这样就不必进行
获取互斥锁
缓冲写入
释放互斥锁
fsync()
系统调用开销是明显可见的。
顺致敬意,
Torben
有点有趣。Jan 在这里报告 LinkBench 记录的 QPS 随时间变化。Dimitri 报告他的优秀性能监控工具链所消耗的 MySQL/InnoDB 指标。所以结果很难比较,但这有时能阻止我们在哪个更快的问题上浪费太多时间。
我使用了基准测试生成的数据。报告 InnoDB 指标与你在应用程序中实际看到的不同,因为从 InnoDB 引擎向应用程序返回 commit 消息需要大于零的时间。