云数据库压测
MySQL性能压测或者基准测试看起来很简单,使用sysbench,tpcc工具跑跑拿到数据就好,其实压测是一个技术活儿,尤其是涉及到性能对比的测试,因为不同场景/不同厂商的产品的参数设置不同,测试的结果也不一样。如果不阐明具体的参数配置差异,直接给出压测结果可能给其他人带来误导。
本文针对三款主流的云数据库做性能压测,主要测试数据库在不同压力场景下的QPS,TPS性能表现,不涉及其他可用性以及功能性介绍。本文的压测结果也不作为任何潜在云客户的购买建议,也不作为购买参考依据。
二 压测
2.1 实例信息
阿里云RDS实例配置信息
腾讯云RDS实例配置信息
AWS RDS实例配置信息
其实阿里云RDS提供三种数据库模式
这里为了和腾讯云RDS在默认参数上接近一致,测试用例选择 高可用 高性能类型的模板。核心差异点在于 sync_binlog
和 innodb_flush_log_at_trx_commit
参数的配置不一样,也就是DBA常说的 双1模式,具体后面会介绍。
2.2 压测模型
工具版本 sysbench 0.5
分别设置并发度为24 48 72 96 120 144 168 192 256 512 1024
选取三个比较经典的sysbench压测场景,其中读写混合模式适合通用的 OLTP 业务模型,比如有大量读写需求的业务;只读模式则适用于读多写少业务场景,该模式测试基于主键查询的情况下,各个数据库的性能表现;无索引更新模式是纯写入,测试根据主键update没有索引字段的表,数据库TPS指标越高则更能体现出数据库实例的IO处理能力越好。
读写混合模式
sysbench命令如下:
sysbench --test=/opt/sysbench/share/sysbench/oltp.lua --oltp-tables-count=10 --oltp-table-size=5000000 --mysql-db=sysbench --mysql-user=sysbench --mysql-password=xxxx --mysql-host=xxxx --mysql-port=3306 --max-time=300 --max-requests=0 --num-threads=$i run
只读模式
sysbench命令如下:
sysbench --test=/opt/sysbench/share/sysbench/select.lua --oltp-tables-count=10 --oltp-table-size=5000000 --mysql-db=sysbench --mysql-user=sysbench --mysql-password=xxxx --mysql-host=xxxx --mysql-port=3306 --max-time=300 --max-requests=0 --num-threads=$i run
无索引更新
sysbench 命令如下:
sysbench --test=/opt/sysbench/share/sysbench/
update_non_index
.lua --oltp-tables-count=10 --oltp-table-size=5000000 --mysql-db=sysbench --mysql-user=sysbench --mysql-password=xxxx --mysql-host=xxxx --mysql-port=3306 --max-time=300 --max-requests=0 --num-threads=$i --oltp-test-mode=complex run
从压测结果来说 混合读写场景下阿里云RDS性能高于腾讯云RDS和AWS RDS,其中QPS 高约50-100%,TPS 高约60%-90%。AWS RDS 比腾讯云RDS性能略高约20-30%。
只读模型压力下,阿里云RDS的性能是腾讯云RDS,AWS RDS的2倍左右。
阿里云RDS性能高于腾讯云RDS和AWS RDS大约 30%-200%,而且阿里云RDS随着并发度的提升,性能基本平稳,腾讯云CDB 的则随着并发度提高而出现性能下降(这点和没有开启thread_pool有关)。
MySQL软件代码设计,宿主机cpu,磁盘配置,raid卡,MySQL相关参数配置,网络时延等都是影响性能吞吐量的因素。作为云资源除了MySQL参数配置之外其他的对使用者而言都是黑盒,使用者无法控制,所以本文对比两种云产品的涉及IO性能相关的核心参数。
阿里云RDS的参数和腾讯云CDB的参数和AWS RDS参数对比:
innodb_buffer_pool_size
阿里云 24G vs 腾讯云 22G vs AWS 24G
内存(因为考虑到连接要占用内存,myisam表等因素,数云厂商实际分配内存都比实际申请的小)binlog size大小
阿里云 1.46G vs 腾讯云 1G vs AWS 128M
注意AWS binlog 默认128M 对于频繁写入的情形,会有明显的性能抖动。实际测试的时候AWS的性能抖动也特别明显。如果有用AWS 的朋友,推荐调整一下binlog大小。
redo log buffer
阿里云 8M vs 腾讯云 64M vs AWS 8M
对与写入比较大的业务场景,还是建议改大relog buffer size。8M对与大部分业务使用是ok的。
innodb_io_capacity
阿里云 20000 vs 腾讯云 20000 vs AWS 200
AWS的配置明显偏小,当然和各个公司对IOPS限制策略也有关系。
innodb_read_io_threads /innodb_write_io_threads
阿里云 4 vs 腾讯云 12 vs AWS 4
performance_schema
阿里云 OFF vs 腾讯云 OFF vs AWS OFF
主从复制同步方式
阿里云 异步模式 vs 腾讯云 异步模式 vs AWS 单实例
AWS 没有主备同一可用区的配置项。异步模式下binglog 拉取对主库IO 压力有一定的影响。
线程池
阿里云 开启 vs 腾讯云 未开启 vs AWS 未开启
总体而言 遇到高并发的场景,MySQL开启线程池时会性能表现更稳定。
sync_binlog
阿里云 1000 vs 腾讯云 0 vs AWS 1000
innodb_flush_log_at_trx_commit
阿里云 2 vs 腾讯云 2 vs AWS 2
关于
innodb_flush_log_at_trx_commit
和sync_binlog
参数要特别用图说明一下innodb_flush_log_at_trx_commit
如果innodb_flush_log_at_trx_commit设置为0,log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行.该模式下,在事务提交的时候,不会主动触发写入磁盘的操作。
如果innodb_flush_log_at_trx_commit设置为1,每次事务提交时MySQL都会把log buffer的数据写入log file,并且flush(刷到磁盘)中去.
如果innodb_flush_log_at_trx_commit设置为2,每次事务提交时MySQL都会把log buffer的数据写入log file.但是flush(刷到磁盘)操作并不会同时进行。该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。当sync_binlog=0时,MySQL不会同步到磁盘中去而是依赖操作系统来刷新binary log。
当sync_binlog=N(N>0),MySQL 在每写N次二进制日志binary log时,会使用fdatasync()函数将它的写二进制日志binary log同步到磁盘中去。选择高性能版本的数据潜在风险是"牺牲"一定的数据安全性。不一定真的会丢失数据,只是说有风险,当然客户可以通过工单或者控制台配置来修改影响数据落盘策略的参数。
另外还有就是各个云厂商对 MySQL 内核开发改进,这点影响不容忽视。有兴趣的朋友可以去查看各自云厂商对数据库改进的介绍。
遇到的问题
压测 AWS RDS 的时候,使用sysbench 压测10个表初始化512 ,1024 个并发时会间歇性失败,调整了connect_timeout 值 有所改善。测试50个表和250个表的时候表现正常。
阿里云RDS 和腾讯云RDS 则没有遇到高并发时初始化失败的问题。
五 总结
从当前的压测结果来看,在读写混合,只读以及无索引更新模式下,阿里云RDS的性能优于腾讯云RDS和AWS RDS,而且随着并发度提升阿里云RDS性能表现比较平稳。
结合此次测试给云用户的几点建议:
推荐大家在使用RDS的时候,打开线程池,提高binlog 文件大小,推荐设置为1G 或者更高,避免binlog频繁切换导致性能抖动,以满足业务对高并发写入的场景需求。
选取合适的数据库落盘参数参数值,关注
sync_binlog
,innodb_flush_log_at_trx_commit
的值。使用sysbench对云数据库进行自测时,建议选择更高的版本,比如sysbench 1.0,提供更丰富的场景,创建多个表(大于20个),避免AWS RDS 测试时遇到初始化失败的问题。