bonnie++是一个文件系统性能基准测试工具,最初由Russell Coker开发。它可以测试磁盘的顺序读写、随机读写、创建和删除文件等性能,特别适合评估文件系统的实际性能。相比简单的dd测试,bonnie++能提供更接近真实应用的性能数据。
# Ubuntu/Debian
sudo apt-get install bonnie++
# RHEL/CentOS 7
sudo yum install bonnie++
# RHEL/CentOS 8/Fedora
sudo dnf install bonnie++
# Arch Linux
sudo pacman -S bonnie++
# 从源码编译安装
wget https://www.coker.com.au/bonnie++/bonnie++-2.00a.tgz
tar -xzf bonnie++-2.00a.tgz
cd bonnie++-2.00a
./configure
make
sudo make install
# 验证安装
bonnie++ --help
# 基本格式
bonnie++ [选项] -d 测试目录
# 常用格式
bonnie++ -d /tmp -s 2G -n 0 -m test -u root -r 1024
| 参数 | 说明 | 示例 |
|---|---|---|
-d, --directory |
测试目录路径 | -d /tmp/test |
-s, --file-size |
测试文件大小(单位:M/G) | -s 2G(2GB文件) |
-n, --number-of-files |
文件数量(0表示不测试文件操作) | -n 1024:1024:1024:1024 |
-m, --machine |
机器名(用于标识测试) | -m myserver |
-u, --user |
运行测试的用户 | -u root |
-r, --ram |
内存大小(MB),用于控制缓存影响 | -r 1024(1GB内存) |
-x, --number-of-tests |
测试次数 | -x 3(运行3次测试) |
-q, --quiet |
安静模式,减少输出 | -q |
-f, --fast |
快速测试模式 | -f |
-y, --sync |
使用sync()强制写入磁盘 | -y |
-D, --direct-io |
使用直接I/O(O_DIRECT) | -D |
-b, --no-write-behind |
禁用write-behind缓存 | -b |
-p, --processes |
并发进程数 | -p 4 |
-c, --chunk-size |
块大小(字节) | -c 8192(8KB块) |
--help |
显示帮助信息 | --help |
| 测试项目 | 说明 | 测试内容 |
|---|---|---|
| Sequential Output | 顺序写入测试 | 按顺序写入大文件,测试写入带宽 |
| Sequential Input | 顺序读取测试 | 按顺序读取大文件,测试读取带宽 |
| Random Seeks | 随机寻道测试 | 随机读取文件的不同部分,测试IOPS |
| Create/Delete | 创建删除文件测试 | 创建、读取、删除大量小文件 |
| Sequential Create | 顺序创建文件测试 | 按顺序创建大量文件 |
| Random Create | 随机创建文件测试 | 随机创建大量文件 |
# 在/tmp目录下测试,使用2GB文件,不测试文件操作
bonnie++ -d /tmp -s 2G -n 0 -m test-server -u root
# 输出示例:
# Writing with putc()...done
# Writing intelligently...done
# Rewriting...done
# Reading with getc()...done
# Reading intelligently...done
# start 'em...done...done...done...done...done...
# Create files in sequential order...done.
# Stat files in sequential order...done.
# Delete files in sequential order...done.
# Create files in random order...done.
# Stat files in random order...done.
# Delete files in random order...done.
# 测试包括文件创建/删除操作
# 使用4GB文件,1024个文件,机器名为server1
bonnie++ -d /mnt/test -s 4G -n 1024 -m server1 -u root
# 指定内存大小为2GB(控制缓存影响)
bonnie++ -d /mnt/test -s 4G -n 1024 -m server1 -u root -r 2048
# 运行3次测试取平均值
bonnie++ -d /tmp -s 1G -n 0 -m test -u root -x 3
# 输出会显示每次测试结果和平均值
# Version 1.98 ------Sequential Output------ --Sequential Input- --Random-
# -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
# Machine Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP /sec %CP
# test 1G ... ... ... ... ... ... ... ... ... ... ... ...
# ------Sequential Create------ --------Random Create--------
# -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
# files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
# ... ... ... ... ... ... ... ... ... ... ... ... ...
# 使用4个并发进程进行测试
bonnie++ -d /tmp -s 1G -n 0 -m test -u root -p 4
# 指定不同的并发数,观察性能变化
for procs in 1 2 4 8; do
echo "测试并发数: $procs"
bonnie++ -d /tmp -s 1G -n 0 -m "test-$procs" -u root -p $procs -q
done
# 使用直接I/O(绕过缓存),获得更真实的磁盘性能
bonnie++ -d /tmp -s 2G -n 0 -m test -u root -D
# 结合sync选项,确保数据写入磁盘
bonnie++ -d /tmp -s 2G -n 0 -m test -u root -y
# 自定义块大小(8KB)
bonnie++ -d /tmp -s 1G -n 0 -m test -u root -c 8192
# 自定义文件数量格式:读:写:创建:删除
# 格式:-n 读操作文件数:写操作文件数:创建操作文件数:删除操作文件数
bonnie++ -d /tmp -s 1G -n 1024:1024:1024:1024 -m test -u root
# 使用bon_csv2html工具将输出转换为HTML
bonnie++ -d /tmp -s 1G -n 0 -m test -u root -x 1 > results.csv
bon_csv2html results.csv > results.html
# 或者直接生成可读性更好的输出
bonnie++ -d /tmp -s 1G -n 0 -m test -u root | bon_csv2html > report.html
# 查看HTML报告
firefox report.html
#!/bin/bash
# bonnie++自动化测试脚本
TEST_DIR="/mnt/test"
OUTPUT_FILE="/var/log/bonnie_results_$(date +%Y%m%d).csv"
LOG_FILE="/var/log/bonnie_test.log"
echo "=== bonnie++性能测试 $(date) ===" | tee $LOG_FILE
echo "测试目录: $TEST_DIR" | tee -a $LOG_FILE
# 确保测试目录存在
mkdir -p $TEST_DIR
# 运行不同文件大小的测试
for size in 1G 2G 4G; do
echo "测试文件大小: $size" | tee -a $LOG_FILE
bonnie++ -d $TEST_DIR -s $size -n 0 -m "test-$size" -u root -x 1 -q >> $OUTPUT_FILE 2>&1
if [ $? -eq 0 ]; then
echo " $size 测试完成" | tee -a $LOG_FILE
else
echo " $size 测试失败" | tee -a $LOG_FILE
fi
done
echo "测试完成!结果保存到: $OUTPUT_FILE" | tee -a $LOG_FILE
echo "日志文件: $LOG_FILE" | tee -a $LOG_FILE
| 指标 | 子项 | 说明 | 单位 |
|---|---|---|---|
| Sequential Output 顺序写入 |
Per Char | 按字符写入性能 | KB/s, %CPU |
| Block | 按块写入性能 | KB/s, %CPU | |
| Rewrite | 重写性能 | KB/s, %CPU | |
| Sequential Input 顺序读取 |
Per Char | 按字符读取性能 | KB/s, %CPU |
| Block | 按块读取性能 | KB/s, %CPU | |
| Random Seeks | Seeks | 随机寻道性能 | 次/秒, %CPU |
| Sequential Create 顺序创建 |
Create | 创建文件性能 | 文件/秒, %CPU |
| Read | 读取文件stat性能 | 文件/秒, %CPU | |
| Delete | 删除文件性能 | 文件/秒, %CPU | |
| Random Create 随机创建 |
Create | 随机创建文件性能 | 文件/秒, %CPU |
| Read | 随机读取文件stat性能 | 文件/秒, %CPU | |
| Delete | 随机删除文件性能 | 文件/秒, %CPU |
Version 1.98 ------Sequential Output------ --Sequential Input- --Random-
-Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP /sec %CP
test-server 2G 24391 99 123456 85 98765 90 54321 98 234567 80 500.0 20
------Sequential Create------ --------Random Create--------
-Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
1024 2000 15 4000 10 3000 12 1500 18 3500 11 2500 13
| 场景 | 文件大小 | 文件数量 | 关键指标 | 建议参数 |
|---|---|---|---|---|
| 大文件传输 | 4G-16G | 0 | 顺序读写带宽 | -s 4G -n 0 |
| 数据库存储 | 2G-8G | 1024-4096 | 随机寻道、文件创建 | -s 2G -n 2048 |
| Web服务器 | 1G-4G | 2048-8192 | 文件创建、读取 | -s 1G -n 4096 |
| 邮件服务器 | 2G-8G | 4096-16384 | 小文件操作性能 | -s 2G -n 8192 |
| 虚拟化存储 | 8G-32G | 0-1024 | 顺序和随机混合 | -s 8G -n 512 |
| 备份系统 | 16G-64G | 0 | 顺序写入带宽 | -s 16G -n 0 -D |
#!/bin/bash
# bonnie++综合性能测试脚本
TEST_BASE="/mnt/test"
REPORT_DIR="/var/log/bonnie_reports"
HTML_REPORT="$REPORT_DIR/bonnie_report_$(date +%Y%m%d_%H%M%S).html"
CSV_DATA="$REPORT_DIR/bonnie_data_$(date +%Y%m%d).csv"
mkdir -p $REPORT_DIR $TEST_BASE
echo "<html><head><title>bonnie++性能测试报告</title></head><body>" > $HTML_REPORT
echo "<h1>bonnie++性能测试报告</h1>" >> $HTML_REPORT
echo "<p>测试时间: $(date)</p>" >> $HTML_REPORT
echo "<p>测试目录: $TEST_BASE</p>" >> $HTML_REPORT
# 运行不同配置的测试
TEST_CONFIGS=(
"1G 0"
"2G 0"
"4G 0"
"2G 1024"
"4G 2048"
)
for config in "${TEST_CONFIGS[@]}"; do
size=$(echo $config | cut -d' ' -f1)
files=$(echo $config | cut -d' ' -f2)
echo "<h2>测试配置: 文件大小=$size, 文件数量=$files</h2>" >> $HTML_REPORT
# 运行测试
bonnie++ -d $TEST_BASE -s $size -n $files -m "test-$size-$files" \
-u root -x 1 -q > /tmp/bonnie_temp.csv 2>&1
# 转换为HTML
if [ -f /tmp/bonnie_temp.csv ]; then
bon_csv2html /tmp/bonnie_temp.csv >> $HTML_REPORT
cat /tmp/bonnie_temp.csv >> $CSV_DATA
fi
echo "<hr>" >> $HTML_REPORT
done
echo "</body></html>" >> $HTML_REPORT
echo "测试完成!"
echo "HTML报告: $HTML_REPORT"
echo "CSV数据: $CSV_DATA"
#!/bin/bash
# bonnie++结果分析脚本
INPUT_CSV="$1"
OUTPUT_SUMMARY="/tmp/bonnie_summary.txt"
if [ -z "$INPUT_CSV" ]; then
echo "用法: $0 bonnie_results.csv"
exit 1
fi
echo "=== bonnie++性能测试分析报告 ===" > $OUTPUT_SUMMARY
echo "分析文件: $INPUT_CSV" >> $OUTPUT_SUMMARY
echo "生成时间: $(date)" >> $OUTPUT_SUMMARY
echo "" >> $OUTPUT_SUMMARY
# 提取关键数据
echo "1. 顺序写入性能 (Block Write):" >> $OUTPUT_SUMMARY
awk -F',' '/^test/ {print " " $1 ": " $5 " KB/s (CPU: " $6 "%)"}' $INPUT_CSV >> $OUTPUT_SUMMARY
echo "" >> $OUTPUT_SUMMARY
echo "2. 顺序读取性能 (Block Read):" >> $OUTPUT_SUMMARY
awk -F',' '/^test/ {print " " $1 ": " $11 " KB/s (CPU: " $12 "%)"}' $INPUT_CSV >> $OUTPUT_SUMMARY
echo "" >> $OUTPUT_SUMMARY
echo "3. 随机寻道性能 (Seeks):" >> $OUTPUT_SUMMARY
awk -F',' '/^test/ {print " " $1 ": " $13 " seeks/s (CPU: " $14 "%)"}' $INPUT_CSV >> $OUTPUT_SUMMARY
echo "" >> $OUTPUT_SUMMARY
echo "4. 文件创建性能:" >> $OUTPUT_SUMMARY
awk -F',' '/^test/ {print " " $1 ": 顺序创建 " $18 " files/s, 随机创建 " $24 " files/s"}' $INPUT_CSV >> $OUTPUT_SUMMARY
echo "" >> $OUTPUT_SUMMARY
echo "=== 性能排名 ===" >> $OUTPUT_SUMMARY
echo "顺序写入排名:" >> $OUTPUT_SUMMARY
awk -F',' '/^test/ {print $5 " KB/s - " $1}' $INPUT_CSV | sort -nr >> $OUTPUT_SUMMARY
echo "" >> $OUTPUT_SUMMARY
echo "顺序读取排名:" >> $OUTPUT_SUMMARY
awk -F',' '/^test/ {print $11 " KB/s - " $1}' $INPUT_CSV | sort -nr >> $OUTPUT_SUMMARY
echo "" >> $OUTPUT_SUMMARY
echo "分析完成! 报告保存到: $OUTPUT_SUMMARY"
cat $OUTPUT_SUMMARY
原因:磁盘空间不足或权限问题。
解决方案:
# 1. 检查磁盘空间
df -h /mnt/test
# 2. 确保有足够空间(测试文件大小的2倍以上)
# 3. 检查目录权限
ls -ld /mnt/test
# 4. 以正确用户运行
sudo bonnie++ -d /mnt/test -s 1G -n 0 -u $(whoami)
# 5. 使用较小的测试文件
bonnie++ -d /mnt/test -s 500M -n 0
解决方案:使用直接I/O或控制内存参数
# 1. 使用直接I/O绕过缓存
bonnie++ -d /tmp -s 2G -n 0 -D
# 2. 指定内存大小(应小于实际内存)
bonnie++ -d /tmp -s 2G -n 0 -r 1024
# 3. 使用sync选项
bonnie++ -d /tmp -s 2G -n 0 -y
# 4. 多次测试取平均值
bonnie++ -d /tmp -s 2G -n 0 -x 3
# 5. 测试后清理缓存
sync; echo 3 > /proc/sys/vm/drop_caches
方法:在相同硬件上测试不同文件系统
#!/bin/bash
# 比较不同文件系统的性能
TEST_DIRS=("/mnt/ext4" "/mnt/xfs" "/mnt/btrfs")
OUTPUT_FILE="/tmp/fs_comparison.csv"
echo "FileSystem,BlockWrite,BlockRead,Seeks,SeqCreate,RandomCreate" > $OUTPUT_FILE
for fs_dir in "${TEST_DIRS[@]}"; do
fs_type=$(df -T $fs_dir | tail -1 | awk '{print $2}')
echo "测试 $fs_type (目录: $fs_dir)..."
# 运行测试
bonnie++ -d $fs_dir -s 1G -n 512 -m "$fs_type" -u root -x 1 -q > /tmp/fs_test.csv
# 提取关键数据
if [ -f /tmp/fs_test.csv ]; then
block_write=$(awk -F',' '/^'$fs_type'/ {print $5}' /tmp/fs_test.csv)
block_read=$(awk -F',' '/^'$fs_type'/ {print $11}' /tmp/fs_test.csv)
seeks=$(awk -F',' '/^'$fs_type'/ {print $13}' /tmp/fs_test.csv)
seq_create=$(awk -F',' '/^'$fs_type'/ {print $18}' /tmp/fs_test.csv)
rand_create=$(awk -F',' '/^'$fs_type'/ {print $24}' /tmp/fs_test.csv)
echo "$fs_type,$block_write,$block_read,$seeks,$seq_create,$rand_create" >> $OUTPUT_FILE
fi
done
echo "比较完成! 结果: $OUTPUT_FILE"
cat $OUTPUT_FILE
sync; echo 3 > /proc/sys/vm/drop_caches-D)获得真实磁盘性能fio灵活的I/O测试工具,功能更强大
iozone另一个文件系统基准测试工具
hdparm磁盘读取性能测试工具
dd简单的磁盘性能测试