前言
自从使用 docker 以来,就经常听说 MySQL 数据库最好别运行在容器中,性能会损失很多。一些之前没使用过容器的同事,对数据库运行在容器中也是忌讳莫深,甚至只要数据库跑在容器中出现性能问题时,首先就把问题推到容器上。
那么到底会损失多少,性能损失会很多吗?
为此我装了两个 MySQL,版本都是 8.0.34。一个用官网二进制包安装,另一个用 docker hub 的 MySQL 镜像安装。两个 MySQL 都运行在同一台机器,但不同时运行,先后运行测试。测试工具用的 sysbench,运行在另一台机器。
提前声明:测试流程比较简单,只是用 sysbench 测了混合读写场景,测试次数也较少,不具有权威性。感兴趣的话,可以自行完善测试流程。
如果对后文没什么兴趣,这里也可以直接说结论:
单表百万级以下时,非容器和容器的性能差异并不多。单表千万级时,容器 MySQL 大概会损耗 10% ~ 20%的性能。
应用
|
版本
|
备注
|
Debian
|
12.0
|
操作系统。4C16G
|
docker
|
20.10.17
|
容器运行时
|
MySQL(非 docker)
|
8.0.34
|
基于官方的二进制安装包
|
MySQL(docker)
|
8.0.34
|
使用 docker hub 的镜像
|
sysbench
|
1.0.20
|
压测工具
|
MySQL 配置
MySQL 安装后创建测试用的 sysbench 用户和 sysbench 数据库,调整 innodb_buffer_pool_size 为 2GB。
docker 容器的网络配置为 bridge,挂载数据目录。
sysbench 命令
•
准备数据
sysbench --db-driver=mysql --mysql-host=192.168.3.21 --mysql-port=3306 --mysql-user=sysbench --mysql-password=123456 --mysql-db=sysbench --table_size=10000000 --tables=20 --threads=4 oltp_read_write prepare
•
执行测试
sysbench --db-driver=mysql --mysql-host=192.168.3.21 --mysql-port=3306 --mysql-user=sysbench --mysql-password=123456 --mysql-db=sysbench --time=300 --threads=8 --report-interval=10 oltp_read_write run
•
清理测试数据
sysbench --db-driver=mysql --mysql-host=192.168.3.21 --mysql-port=3306 --mysql-user=sysbench --mysql-password=123456 --mysql-db=sysbench --table_size=10000000 --tables=20 --threads=4 oltp_read_write cleanup
测试结果
单表 1000w 数据,20 张表,测试 4 次。
MySQL 运行环境
|
测试序列
|
总 SQL 执行数
|
每秒 SQL 数
|
每秒事务数
|
延迟时间(平均)
|
延迟时间(95%)
|
非容器
|
1
|
3798093
|
12658.84
|
632.78
|
12.64
|
20.00
|
非容器
|
2
|
3914578
|
13047.91
|
652.28
|
12.26
|
17.01
|
非容器
|
3
|
4059867
|
13531.79
|
676.46
|
11.82
|
15.55
|
非容器
|
4
|
3772390
|
12574.00
|
628.58
|
12.72
|
19.65
|
容器
|
1
|
3230678
|
10768.41
|
538.28
|
14.86
|
26.20
|
容器
|
2
|
3538573
|
11794.68
|
589.62
|
13.57
|
19.29
|
容器
|
3
|
3567943
|
11892.56
|
594.50
|
13.45
|
17.63
|
容器
|
4
|
3616204
|
12053.53
|
602.58
|
13.27
|
17.32
|