本文目录导读:

我来提供几种不同的脚本方式来模拟磁盘写入,从简单到复杂:
使用 dd 命令(最简单)
#!/bin/bash # 模拟磁盘写入测试 # 写入1GB数据 dd if=/dev/zero of=/tmp/testfile bs=1M count=1024 conv=fdatasync # 使用不同块大小 dd if=/dev/zero of=/tmp/testfile bs=4K count=262144 conv=fdatasync
Python 脚本模拟
#!/usr/bin/env python3
import os
import time
import random
def write_test(file_path, size_mb, block_size=4096):
"""模拟磁盘写入"""
# 生成随机数据
data = os.urandom(block_size)
start_time = time.time()
bytes_written = 0
with open(file_path, 'wb') as f:
while bytes_written < size_mb * 1024 * 1024:
f.write(data)
bytes_written += block_size
# 可选:模拟随机写入
if random.random() < 0.1: # 10%概率调整位置
f.seek(random.randint(0, size_mb * 1024 * 1024 // 2))
# 确保数据落盘
os.fsync(f.fileno())
elapsed = time.time() - start_time
speed = (size_mb / 1024) / elapsed # GB/s
print(f"写入完成: {size_mb}MB")
print(f"耗时: {elapsed:.2f}秒")
print(f"速度: {speed:.2f} GB/s")
# 清理
os.remove(file_path)
if __name__ == "__main__":
write_test("/tmp/python_write_test.bin", 1000) # 写入1GB
Bash + /dev/urandom 模拟
#!/bin/bash
# 模拟随机数据写入
SIZE_MB=500
BLOCK_SIZE=1024 # 1KB块
write_random_data() {
local file=$1
local size_mb=$2
echo "开始写入 $size_mb MB 到 $file..."
# 使用 urandom 生成随机数据
for ((i=0; i<$size_mb*1024; i++)); do
dd if=/dev/urandom of="$file" bs=$BLOCK_SIZE count=1 \
seek=$i conv=notrunc 2>/dev/null
done
echo "写入完成"
}
# 测试不同场景
write_random_data "/tmp/random_test1.bin" 100
综合压力测试脚本
#!/bin/bash
# 磁盘压力测试脚本
LOG_FILE="/tmp/disk_test.log"
TEST_DIR="/tmp/disk_test"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
create_test_files() {
mkdir -p "$TEST_DIR"
log "创建测试目录: $TEST_DIR"
}
sequential_write_test() {
log "开始顺序写入测试..."
# 使用 dd 测试顺序写入
dd if=/dev/zero of="$TEST_DIR/seq_test.bin" \
bs=1M count=1024 conv=fdatasync 2>&1 | tee -a "$LOG_FILE"
}
random_write_test() {
log "开始随机写入测试..."
# 随机位置写入
python3 << 'EOF'
import os
import random
test_file = "/tmp/disk_test/random_test.bin"
file_size = 500 * 1024 * 1024 # 500MB
# 创建文件
with open(test_file, 'wb') as f:
f.truncate(file_size)
# 随机写入
for i in range(1000):
offset = random.randint(0, file_size - 4096)
data = os.urandom(4096)
with open(test_file, 'r+b') as f:
f.seek(offset)
f.write(data)
print("随机写入测试完成")
EOF
}
multi_thread_write() {
log "开始多线程写入测试..."
# 使用 xargs 并行写入
seq 1 10 | xargs -P 4 -I {} bash -c '
dd if=/dev/zero of=/tmp/disk_test/thread_{}.bin \
bs=1M count=100 conv=fdatasync 2>/dev/null
echo "线程 {} 完成"
'
}
iozone_test() {
if command -v iozone >/dev/null 2>&1; then
log "使用 iozone 进行测试..."
iozone -a -g 1G -i 0 -i 1 -i 2 -f "$TEST_DIR/iozone_test"
else
log "iozone 未安装,跳过"
fi
}
# 运行所有测试
create_test_files
sequential_write_test
random_write_test
multi_thread_write
# 清理
log "清理测试文件..."
rm -rf "$TEST_DIR"
log "测试完成"
持续监控版本
#!/bin/bash
# 持续模拟磁盘写入(带监控)
INTERVAL=5 # 每5秒报告一次
DURATION=60 # 运行60秒
monitor_io() {
while true; do
echo "=== $(date) ==="
iostat -h 2>/dev/null || vmstat 1 1 | tail -1
sleep $INTERVAL
done
}
continuous_write() {
# 后台监控
monitor_io &
MONITOR_PID=$!
# 持续写入
START_TIME=$(date +%s)
while [ $(( $(date +%s) - START_TIME )) -lt $DURATION ]; do
dd if=/dev/zero of=/tmp/continuous_test bs=1M count=100 conv=fdatasync
sleep 1
done
kill $MONITOR_PID
}
# 运行测试
echo "开始持续写入测试($DURATION秒)..."
continuous_write
echo "测试完成"
使用建议
- 安全警告:这些脚本会消耗大量磁盘空间和I/O资源,不要在重要数据盘上运行
- 调整参数:根据需求调整
SIZE_MB、BLOCK_SIZE等参数 - 监控影响:运行时建议监控系统性能,避免影响其他服务
- 清理工作:脚本运行后会自动清理临时文件
选择哪种取决于你的具体需求:
- 简单测试:用
dd - 更真实的模拟:用 Python 脚本
- 压力测试:用综合测试脚本
- 持续监控:用监控版本