本文中,我们将通过基准测试来给大家展示MyRocks引擎的性能。
Percona Server MySQL 5.7新引入的一个数据库引擎。关于他性能可能还是还待探索,所以今天我们就一起来看看你看它在相对高端服务器和SSD存储下的性能表现。
我们想要要检查它对于给定的数据库不同大小的可用内存情况表现。它与之前Percona官方发布的InnoDB基准测试相同的条件下,我们使用sysbench-tpcc基准测试,用InnoDB作为基准,然后用其对MyRocks和InnoDB两种引擎进行对比测试。
作为基准测试,我将使用100个TPC-C仓库,以及一组10个表格(从行递增调整瓶颈)。这应该提供大约90GB的数据大小(加载到InnoDB时),大致相当于1000个数据仓库的数据量。
为了改变内存大小,我们将InnoDB的innodb_buffer_pool_size从5GB更改为100GB,MyRocks的 rocksdb_block_cache_size也做同样修改。
对于MyRocks,我们将使用LZ4作为存盘的默认压缩。 MyRocks存储引擎中的数据大小为21GB。需要注意的是是,在MyRocks中未压缩的数据存储上限70GB。
这两种引擎,均未使用FOREIGN KEYS,因为MyRocks目前还不支持。
MyRocks不支持Percona Server中实现的REPEATABLE-READ模式中的"SELECT .. FOR UPDATE"语句。但是,在此基准测试中使用了"SELECT .. FOR UPDATE"。必须使用READ-COMMITTED模式。
还要提及的最重要的设置是启用二进制日志,原因如下:
1、任何重要的生产系统都都会启用二进制日志
2、如果禁用的二进制日志,MyRocks会受到的非最优事务协调器的影响
我们对二进制日志使用了以下设置:
binlog_format ='ROW'
binlog_row_image = minimal
sync_binlog = 10000(我没有使用0,因为这会在二进制日志转存到硬盘时候时候导致严重的卡顿)
虽然我并不是MyRocks调优的完整专家,但我使用了此页面的调优建议:github上 /facebook/mysql-5.6/wiki/my.cnf-tuning。同时Facebook-MyRocks工程团队还为我们提供了关于MyRocks最佳设置配置。
结果展示
内存性能
让我们回顾一下不同内存大小的结果。
这第一张图显示吞吐量抖动。这有助于了解吞吐量结果的分布情况。吞吐量每1秒测量一次,图表上显示运行2000秒后的所有测量结果(每次运行的总长度为3600秒)。所以我们展示了每次运行的最后1600秒(去除准备热身阶段):
为了更好地量化结果,让我们对比看boxplot图。理解箱型图的最快方法是看中间线。它代表测量的中位数。
内存吞吐变化
在我们跳到结果总结之前,让我们来看看InnoDB和MyRocks的吞吐量变化。我们100GB内存分配的结果将放大到的1秒分辨率图表:
我们可以看到,MyRocks在定期1秒性能下降中变化很大。目前,我们还不知道导致吞吐量变化的原因。
因此,让我们来看看不同内存设置下每个引擎的平均吞吐量(结果以tps为单位,而且越多越好):
这是MyRocks与InnoDB行为不同的地方。 InnoDB从额外的内存中受益良多,直到增加到工作数据集的大小。之后,内存增加被限制。
于此对比,有趣的是MyRocks并没有从额外的内存中获益。
基本上,MyRocks按预期执行写优化引擎。有关更多详细信息,请参阅我的文章"三种基本数据结构如何影响存储和检索"。
总之,当工作数据集适合(或几乎适合)可用内存时,InnoDB的性能会更好(与其本身相比),而MyRocks可以在小内存上运行(并且胜过InnoDB)。
IO和CPU使用率
值得关注的是每个引擎的资源利用率。我们对每次运行都进行了vmstat测量,以便分析IO和CPU使用情况。
写性能
首先,让我们回顾一下每秒写入的数量(以KB/秒为单位)。注意,这些写操作也包括二进制日志写入,而不仅仅是存储引擎写入。
我们还计算了各存储引擎每次执行的写入次数:
上面的图显示了InnoDB和MyRocks之间的本质区别。 MyRocks是一个写优化的引擎,每个事务使用的写入量不变。
相比较InnoDB,写入的数量很大程度上取决于内存大小。我们拥有的内存越少,它需要执行的写入就越多。
读性能
下表显示了以每秒KB为单位的读取。
我们可以将其转换为每个事务的读取次数:
这张图显示了MyRocks的读取放大。分配更多内存有助于减少IO读取,但不如InnoDB那么明显。
CPU使用率
让我们在看看两个存储引擎的CPU使用情况。先是InnoDB:
该图表显示,对于5GB内存大小,InnoDB大部分时间用于IO等待(绿色区域),并且CPU使用率(蓝色区域)随着更多内存的增加而增加。
做为对比MyRocks的情况:
其详细表格数据如下:
我们可以看到无论分配了多少内存,MyRocks都使用了很多CPU(用户+系统态)。这导致MyRocks性能受限于CPU性能而非可用内存的限制。
MyRocks目录大小
随着MyRocks写入所有更改并压缩成SST文件,可以看到基准测试期间数据目录大小如何变化,以便我们估算存储需求。下面是数据目录大小的图表:
我们可以看到,数据目录从开始时的20GB变为基准期间的31GB。观察数据增长直到压缩,然后缩小呈现周期性的规律变化。
结论
总之,我可以说MyRocks性能随着数据集大小与内存的比例增加而增加,在5GB内存分配的情况下,性能比InnoDB高出近5倍。吞吐量变化是值得关注的问题,但我们希望这一点在未来得到改善。
MyRocks不需要大量内存,并且在使用大部分CPU资源时显示稳定地写入IO。
我们认为这特性可能会使MyRocks成为云数据库实例的绝佳选择,而内存和IO都消费都会比较合算。 MyRocks部署可以让云部署更便宜。
我们将跟进更多基于云计算的基准测试。
附件
原始结果,脚本和测试配置
我的目标是提供完全可重复的基准测试。为此,我们在GitHub分享相关信息包括我们使用的所有脚本和设置:
Github链接:Percona-Lab-results/201803-sysbench-tpcc-myrocks
MyRocks设置
rocksdb_max_open_files=-1
rocksdb_max_background_jobs=8
rocksdb_max_total_wal_size=4G
rocksdb_block_size=16384
rocksdb_table_cache_numshardbits=6
# rate limiter
rocksdb_bytes_per_sync=16777216
rocksdb_wal_bytes_per_sync=4194304
rocksdb_compaction_sequential_deletes_count_sd=1
rocksdb_compaction_sequential_deletes=199999
rocksdb_compaction_sequential_deletes_window=200000
rocksdb_default_cf_options="write_buffer_size=256m;target_file_size_base=32m;max_bytes_for_level_base=512m;max_write_buffer_number=4;level0_file_num_compaction_trigger=4;level0_slowdown_writes_trigger=20;level0_stop_writes_trigger=30;max_write_buffer_number=4;block_based_table_factory={cache_index_and_filter_blocks=1;filter_policy=bloomfilter:10:false;whole_key_filtering=0};level_compaction_dynamic_level_bytes=true;optimize_filters_for_hits=true;memtable_prefix_bloom_size_ratio=0.05;prefix_extractor=capped:12;compaction_pri=kMinOverlappingRatio;compression=kLZ4Compression;bottommost_compression=kLZ4Compression;compression_opts=-14:4:0"
rocksdb_max_subcompactions=4
rocksdb_compaction_readahead_size=16m
rocksdb_use_direct_reads=ON
rocksdb_use_direct_io_for_flush_and_compaction=ON
InnoDB设置
# files
innodb_file_per_table
innodb_log_file_size=15G
innodb_log_files_in_group=2
innodb_open_files=4000
# buffers
innodb_buffer_pool_size= 200G
innodb_buffer_pool_instances=8
innodb_log_buffer_size=64M
# tune
innodb_doublewrite= 1
innodb_support_xa=0
innodb_thread_concurrency=0
innodb_flush_log_at_trx_commit= 1
innodb_flush_method=O_DIRECT_NO_FSYNC
innodb_max_dirty_pages_pct=90
innodb_max_dirty_pages_pct_lwm=10
innodb_lru_scan_depth=1024
innodb_page_cleaners=4
join_buffer_size=256K
sort_buffer_size=256K
innodb_use_native_aio=1
innodb_stats_persistent = 1
#innodb_spin_wait_delay=96
# perf special
innodb_adaptive_flushing = 1
innodb_flush_neighbors = 0
innodb_read_io_threads = 4
innodb_write_io_threads = 2
innodb_io_capacity=2000
innodb_io_capacity_max=4000
innodb_purge_threads=4
硬件和系统配置列表
超微服务器:
CPU:
Intel(R) Xeon(R) CPU E5-2683 v3 @ 2.00GHz
2 sockets / 28 cores / 56 threads
内存: 256GB of RAM
硬盘: 三星 SM863 1.9TB Enterprise SSD
文件系统: ext4
数据库:Percona-Server-5.7.21-20
操作系统: Ubuntu 16.04.4, linux内核 4.13.0-36-generic
本文虫虫译自percona官方博客,作者是percona联合创始人Vadim Tkachenko和CTO。(原文链接见percona最新blog,此处略)。