Linux bonnie++命令

bonnie++命令 - 一个文件系统性能基准测试工具,用于测试磁盘和文件系统的读写性能、创建删除文件性能等。
警告:bonnie++会进行大量文件读写操作,可能破坏测试目录中的数据,请务必在测试环境中使用!

命令简介

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 随机创建文件测试 随机创建大量文件

使用示例

示例1:基本性能测试

# 在/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.

示例2:完整文件系统测试

# 测试包括文件创建/删除操作
# 使用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:多次测试取平均值

# 运行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:并发测试

# 使用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

示例5:直接I/O测试

# 使用直接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

示例6:自定义块大小和文件数量

# 自定义块大小(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

示例7:生成CSV格式输出

# 使用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

示例8:自动化测试脚本

#!/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
  • Machine: 测试机器标识
  • Size: 测试文件大小
  • K/sec: 每秒千字节数(性能值)
  • %CP: CPU使用率百分比
  • /sec: 每秒操作数
  • files: 测试的文件数量

典型测试场景

场景 文件大小 文件数量 关键指标 建议参数
大文件传输 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

最佳实践

推荐做法
  • 在空闲系统上进行测试,避免其他进程干扰
  • 测试文件大小至少是内存的2倍,避免缓存影响
  • 多次测试取平均值
  • 测试前清理磁盘缓存:sync; echo 3 > /proc/sys/vm/drop_caches
  • 使用直接I/O(-D)获得真实磁盘性能
  • 保存原始CSV数据用于后续分析
  • 测试不同的文件大小和数量组合
  • 比较测试结果时保持硬件环境一致
避免的做法
  • 不要在生产系统上直接测试
  • 不要使用过小的测试文件(小于内存)
  • 不要忽略CPU使用率指标
  • 不要只测试一次就下结论
  • 不要在磁盘繁忙时测试
  • 不要混合测试不同类型存储设备
  • 不要忘记记录测试环境和参数
  • 不要在有数据的目录中测试

相关工具

fio

灵活的I/O测试工具,功能更强大

iozone

另一个文件系统基准测试工具

hdparm

磁盘读取性能测试工具

dd

简单的磁盘性能测试