SysBench 压测实践:CPU、内存、FileIO 与 MySQL OLTP 基准测试指南
前言
SysBench 是一款常用的多线程基准测试工具,适合用来快速评估服务器 CPU、内存、线程调度、文件 IO 以及数据库 OLTP 性能。
它的价值不只是“跑一个分数”,而是帮助我们在以下场景中获得可对比的数据:
- 新服务器上线前做基准测试;
- Linux 内核参数或文件描述符调优前后对比;
- 数据库实例规格、磁盘类型、Buffer Pool、连接数调整前后对比;
- 压测环境、预发环境、生产只读副本之间做横向对比;
- 排查 CPU、IO、内存或数据库瓶颈。
如果你还需要配套的系统参数调优和排查命令,可以参考:
SysBench 是什么
SysBench 官方项目将它定位为基于 LuaJIT 的可脚本化、多线程基准测试工具。它内置了多类测试:
| 测试类型 | 说明 |
|---|---|
cpu |
CPU 计算能力测试,常用素数计算作为负载。 |
memory |
内存读写吞吐测试。 |
threads |
线程调度和上下文切换测试。 |
mutex |
互斥锁性能测试。 |
fileio |
文件 IO 测试,支持顺序读写、随机读写等模式。 |
| Lua OLTP 脚本 | MySQL / PostgreSQL 等数据库 OLTP 压测,例如 oltp_read_write.lua。 |
SysBench 的通用命令格式是:
sysbench [options] testname command
常见 command 包括:
| command | 作用 |
|---|---|
prepare |
准备测试数据,例如创建测试文件或数据库表。 |
run |
执行压测。 |
cleanup |
清理测试数据。 |
help |
查看测试脚本或测试项支持的参数。 |
安装 SysBench
CentOS / RHEL
常见方式是使用 packagecloud 仓库:
curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
sudo yum install -y sysbench
Debian / Ubuntu
sudo apt update
sudo apt install -y sysbench
检查版本
sysbench --version
示例:
sysbench 1.0.20
如果使用的是发行版仓库,版本可能落后于 GitHub 最新版本。压测结果跨版本对比时,要记录 SysBench 版本。
查看内置 Lua 脚本
在很多 Linux 发行版中,SysBench 的 Lua 脚本位于:
ls -lh /usr/share/sysbench/
常见脚本包括:
bulk_insert.lua
oltp_common.lua
oltp_delete.lua
oltp_insert.lua
oltp_point_select.lua
oltp_read_only.lua
oltp_read_write.lua
oltp_update_index.lua
oltp_update_non_index.lua
oltp_write_only.lua
select_random_points.lua
select_random_ranges.lua
数据库压测时,最常用的是:
oltp_read_only.lua:只读 OLTP;oltp_write_only.lua:只写 OLTP;oltp_read_write.lua:读写混合 OLTP;oltp_point_select.lua:主键点查场景;oltp_insert.lua:插入场景。
通用参数说明
下面这些参数几乎所有测试都会用到:
| 参数 | 说明 |
|---|---|
--threads |
并发线程数。 |
--time |
压测持续时间,单位秒。 |
--events |
总事件数,设置为 0 时通常由 --time 控制。 |
--report-interval |
每隔几秒输出一次中间结果。 |
--percentile |
统计延迟百分位,例如 P95。 |
--rand-type |
随机分布类型,数据库压测中常用。 |
--db-driver |
数据库驱动,例如 mysql。 |
建议压测时至少记录:
机器规格、CPU 型号、内存、磁盘类型、文件系统、内核版本、数据库版本、SysBench 版本、线程数、压测时间、测试脚本、数据量、参数配置。
否则压测结果很难复现,也很难和后续结果对比。
标准压测流程
SysBench 最重要的是三段式流程:
# 1. 准备测试数据
sysbench ... prepare
# 2. 执行压测
sysbench ... run
# 3. 清理测试数据
sysbench ... cleanup
并不是所有测试都需要 prepare 和 cleanup。例如 CPU、memory、threads 通常直接 run;fileio 和数据库 OLTP 则需要先 prepare。
CPU 测试
CPU 测试通过计算素数来制造 CPU 负载。
sysbench cpu \
--threads=4 \
--cpu-max-prime=20000 \
--time=60 \
--report-interval=10 \
run
关注指标:
| 指标 | 含义 |
|---|---|
events per second |
每秒完成的事件数,越高越好。 |
total time |
总耗时。 |
latency avg |
平均延迟。 |
latency 95th percentile |
95% 请求的延迟上界。 |
CPU 测试适合比较同类机器的计算能力,但不代表数据库或 Web 服务的真实吞吐,因为实际业务还会受 IO、网络、锁、缓存命中率影响。
内存测试
内存测试关注内存读写吞吐量。
sysbench memory \
--threads=4 \
--memory-block-size=1K \
--memory-total-size=10G \
--time=60 \
--report-interval=10 \
run
常见参数:
| 参数 | 说明 |
|---|---|
--memory-block-size |
每次读写的块大小。 |
--memory-total-size |
总读写量。 |
--memory-oper |
操作类型,read 或 write。 |
--memory-access-mode |
访问模式,seq 或 rnd。 |
关注结果中的吞吐量,例如 MiB/sec。
线程调度测试
线程测试用于观察线程调度和上下文切换能力。
sysbench threads \
--threads=64 \
--thread-yields=1000 \
--thread-locks=8 \
--time=60 \
--report-interval=10 \
run
如果线程数增加后吞吐不升反降,可能说明 CPU 调度、锁竞争或系统负载已经成为瓶颈。
FileIO 测试
FileIO 测试需要先准备文件,再运行测试,最后清理。
准备测试文件
sysbench fileio \
--threads=4 \
--file-total-size=4G \
--file-num=128 \
--file-test-mode=rndrw \
prepare
执行随机读写测试
sysbench fileio \
--threads=4 \
--file-total-size=4G \
--file-num=128 \
--file-test-mode=rndrw \
--time=120 \
--report-interval=10 \
--file-extra-flags=direct \
run
清理测试文件
sysbench fileio \
--file-total-size=4G \
cleanup
常见 --file-test-mode:
| 模式 | 说明 |
|---|---|
seqrd |
顺序读。 |
seqwr |
顺序写。 |
rndrd |
随机读。 |
rndwr |
随机写。 |
rndrw |
随机读写混合。 |
建议:
--file-total-size应大于系统内存的一定比例,否则容易测到缓存而不是磁盘;- 如果希望尽量绕过文件系统缓存,可以使用
--file-extra-flags=direct; - 测试前后结合
iostat -x 1、vmstat 1、dmesg查看系统状态; - 不要在生产业务盘上直接做破坏性压测。
MySQL OLTP 压测
MySQL 压测建议独立准备测试库和测试账号。
创建测试库
CREATE DATABASE sbtest DEFAULT CHARACTER SET utf8mb4;
CREATE USER 'sbtest'@'%' IDENTIFIED BY 'sbtest_password';
GRANT ALL PRIVILEGES ON sbtest.* TO 'sbtest'@'%';
FLUSH PRIVILEGES;
准备数据
sysbench /usr/share/sysbench/oltp_read_write.lua \
--db-driver=mysql \
--mysql-host=127.0.0.1 \
--mysql-port=3306 \
--mysql-user=sbtest \
--mysql-password='sbtest_password' \
--mysql-db=sbtest \
--tables=8 \
--table-size=100000 \
--threads=8 \
prepare
这里会创建 8 张表,每张表 10 万行。
执行读写混合压测
sysbench /usr/share/sysbench/oltp_read_write.lua \
--db-driver=mysql \
--mysql-host=127.0.0.1 \
--mysql-port=3306 \
--mysql-user=sbtest \
--mysql-password='sbtest_password' \
--mysql-db=sbtest \
--tables=8 \
--table-size=100000 \
--threads=16 \
--time=300 \
--report-interval=10 \
--percentile=95 \
run
清理数据
sysbench /usr/share/sysbench/oltp_read_write.lua \
--db-driver=mysql \
--mysql-host=127.0.0.1 \
--mysql-port=3306 \
--mysql-user=sbtest \
--mysql-password='sbtest_password' \
--mysql-db=sbtest \
--tables=8 \
cleanup
OLTP 常用脚本选择
| 脚本 | 场景 |
|---|---|
oltp_read_only.lua |
只读场景,适合测试缓存命中、索引查询和读扩展能力。 |
oltp_write_only.lua |
写入场景,适合观察 redo、binlog、刷盘、锁竞争。 |
oltp_read_write.lua |
读写混合场景,最常用于综合压测。 |
oltp_point_select.lua |
主键点查,适合测试数据库查询延迟。 |
oltp_insert.lua |
插入场景,适合测试写入吞吐。 |
结果指标怎么读
SysBench 输出中常见指标:
| 指标 | 含义 | 关注点 |
|---|---|---|
transactions |
完成的事务数。 | 数据库 OLTP 中常用于计算 TPS。 |
queries |
执行的 SQL 数量。 | 常用于计算 QPS。 |
events per second |
每秒事件数。 | CPU / memory / fileio 等测试常用。 |
latency avg |
平均延迟。 | 容易被极端值影响。 |
latency 95th percentile |
P95 延迟。 | 更能反映大部分请求的体验。 |
read/write MiB/s |
文件读写吞吐。 | FileIO 测试关注。 |
fsyncs/s |
每秒 fsync 次数。 | 和磁盘刷盘能力相关。 |
数据库压测不能只看 TPS。更合理的判断方式是:
- TPS 是否提升;
- P95 / P99 延迟是否可接受;
- CPU 是否打满;
- IO util 是否接近 100%;
- MySQL 是否出现锁等待、慢 SQL、连接耗尽;
- 系统是否有丢包、磁盘错误、OOM、上下文切换过高。
压测注意事项
1. 不要只跑一次
建议至少跑三轮,去掉明显异常值后再取平均或中位数。
2. 区分冷启动和热数据
数据库和文件系统都有缓存。第一次压测可能和后续结果不同,需要明确记录:
- 是否重启过数据库;
- 是否清理过 OS page cache;
- 是否预热过 Buffer Pool;
- 是否开启 direct IO。
3. 压测数据量要足够
MySQL OLTP 压测中,如果数据完全放进 Buffer Pool,测到的更多是内存和 CPU;如果数据远大于内存,则会更多体现磁盘和 IO 调度能力。
4. 不要在生产环境随意压测
FileIO、OLTP 写入和高线程压测可能影响业务。生产环境中更适合做低风险观察或只读压测,真正的极限压测应该在隔离环境完成。
5. 调优必须前后对比
Linux 参数或 MySQL 参数调整后,要保留变更前后的相同压测条件。否则很难判断性能提升来自参数,还是来自缓存、负载波动或测试误差。
常用压测模板
CPU 快速模板
sysbench cpu --threads=$(nproc) --cpu-max-prime=20000 --time=60 --report-interval=10 run
内存快速模板
sysbench memory --threads=$(nproc) --memory-block-size=1K --memory-total-size=10G --time=60 run
FileIO 随机读写模板
sysbench fileio --threads=4 --file-total-size=4G --file-test-mode=rndrw prepare
sysbench fileio --threads=4 --file-total-size=4G --file-test-mode=rndrw --file-extra-flags=direct --time=120 --report-interval=10 run
sysbench fileio --file-total-size=4G cleanup
MySQL 读写混合模板
sysbench /usr/share/sysbench/oltp_read_write.lua \
--db-driver=mysql \
--mysql-host=127.0.0.1 \
--mysql-port=3306 \
--mysql-user=sbtest \
--mysql-password='sbtest_password' \
--mysql-db=sbtest \
--tables=8 \
--table-size=100000 \
--threads=16 \
--time=300 \
--report-interval=10 \
--percentile=95 \
run
小结
SysBench 适合做基准测试,但它不是业务压测工具。它能帮助我们快速判断 CPU、内存、文件 IO 和数据库基础能力,但最终还需要结合真实业务流量、SQL 模型、缓存命中率、网络延迟和系统监控一起分析。
建议把 SysBench 作为“调优前后对比工具”,而不是单纯追求一个更高的跑分。