前言
服务器资源利用率不高,需缩减资源。要求标准磁盘方面利用率不得低于30%。
应对方案:上传文件,所有服务器磁盘保证利用率大于30%。
你有什么技术方案?
ftp上传大文件不考虑。首先vpn不稳定,上传大文件不可靠。
要求尽快完成任务。
一、scp
- 所有服务器中找到一个大文件,或cp+zip制造一个大文件
- scp到其他服务器上
1.1 zip压缩率
0:不压缩,仅将文件打包。
1:最低压缩率,速度最快。
9:最高压缩率,速度最慢。
6:默认压缩率,平衡了压缩率和速度。
zip -r -1 archive.zip /path/to/folder
1.2 scp命令
scp -rCv /data/garbage/garbage.lj root@172.1.2.3:/data/garbage/
-r:递归复制整个文件夹及其内容。
-C:启用压缩,传输过程中会对数据进行压缩,适合文本文件较多的场景。必须大写C 小写代表指定加密算法
-v:显示详细的传输进度信息,方便查看传输过程。
1.3 后台运行scp(bg&disown)
服务器传输速率大概在11M/s,速度不快,想到后台运行且不受会话关闭影响。正常nohup & 可以防止任务中断,但是scp过程需要输入远程服务器密码,又不想使用ssh密钥认证。我们采取手动操作,使其后台运行。
- 直接运行scp命令:
scp -rCv /data/garbage/garbage.lj root@172.1.2.3:/data/garbage/
- 输入密码并等待传输开始。
- 按Ctrl+Z暂停任务。
- 将任务放到后台:
bg
任务放到后台运行,但它仍然与当前终端会话关联。 - 使用disown防止任务被中断:
disown
任务从当前终端会话中分离
关机下班!(第二天发现没生效,具体问题查看踩坑1)
二、scp + cp
scp
成功一台服务器后,发现由于外挂磁盘过大,传进来的文件大小达不到要求。自身cp
一下就够了。
为什么不直接cp自身文件,直到磁盘利用率大于30%呢?
搞个脚本:
#!/bin/bash
# 定义源文件夹和目标文件夹
SOURCE_DIR="/path/to/source_folder"
TARGET_DIR="/path/to/target_folder"
# 定义磁盘使用率阈值(31%)
THRESHOLD=31
# 循环复制文件夹,直到磁盘使用率大于阈值
while true; do
# 获取当前磁盘使用率(百分比)
USAGE=$(df -h /data | awk 'NR==2 {print $5}' | sed 's/%//')
# 检查磁盘使用率是否大于阈值
if [ "$USAGE" -gt "$THRESHOLD" ]; then
echo "磁盘使用率已达到 $USAGE%,停止复制。"
break
fi
# 在目标文件夹中创建一个唯一的子文件夹
TIMESTAMP=$(date +%Y%m%d%H%M%S)
UNIQUE_TARGET_DIR="$TARGET_DIR/copy_$TIMESTAMP"
# 复制文件夹到唯一的子文件夹中
echo "正在复制文件夹 $SOURCE_DIR 到 $UNIQUE_TARGET_DIR..."
cp -r "$SOURCE_DIR" "$UNIQUE_TARGET_DIR"
# 等待 1 秒,避免过于频繁检查
sleep 1
done
三、dd
为何不直接做一个写入文件的脚本呢!我真是个大聪明。
#!/bin/bash
# 定义目标目录和文件大小
TARGET_DIR="/data/garbage"
FILE_SIZE="1G" # 每次生成的文件大小
THRESHOLD=31 # 磁盘使用率阈值
# 确保目标目录存在
mkdir -p "$TARGET_DIR"
# 循环写入文件,直到磁盘使用率大于阈值
while true; do
# 获取 /data 分区的磁盘使用率(百分比)
USAGE=$(df -h /data | awk 'NR==2 {print $5}' | sed 's/%//')
# 检查磁盘使用率是否大于阈值
if [ "$USAGE" -gt "$THRESHOLD" ]; then
echo "磁盘使用率已达到 $USAGE%,停止写入。"
break
fi
# 生成一个唯一的文件名
FILENAME="$TARGET_DIR/file_$(date +%Y%m%d%H%M%S).dat"
# 写入文件
echo "正在写入文件 $FILENAME..."
dd if=/dev/zero of="$FILENAME" bs="$FILE_SIZE" count=1
# 等待 1 秒,避免过于频繁检查
sleep 1
done
四、fallocate
dd最大生成单文件只能是2G,了解到fallocate
更快速高效。
fallocate
是一个在Linux系统中用于预分配或取消分配文件空间的命令。它可以直接在文件系统中操作,快速为文件分配空间,而不需要实际写入任何数据,这使得它在需要快速创建大文件或预留空间的场景中非常有用。
#!/bin/bash
# 定义目标目录和文件大小
TARGET_DIR="/data/garbage"
FILE_SIZE="100G" # 每次生成的文件大小
THRESHOLD=31 # 磁盘使用率阈值
# 确保目标目录存在
mkdir -p "$TARGET_DIR"
# 循环写入文件,直到磁盘使用率大于阈值
while true; do
# 获取 /data 分区的磁盘使用率(百分比)
USAGE=$(df -h /data | awk 'NR==2 {print $5}' | sed 's/%//')
# 检查磁盘使用率是否大于阈值
if [ "$USAGE" -gt "$THRESHOLD" ]; then
echo "磁盘使用率已达到 $USAGE%,停止写入。"
break
fi
# 生成一个唯一的文件名
FILENAME="$TARGET_DIR/file_$(date +%Y%m%d%H%M%S).dat"
# 使用 fallocate 分配文件
echo "正在写入文件 $FILENAME..."
fallocate -l "$FILE_SIZE" "$FILENAME"
# 等待 1 秒,避免过于频繁检查
sleep 1
done
完美!
踩坑
- 执行disown后deleting stopped job 1 with process group 295382
在执行 disown 命令时,如果出现 deleting stopped job 1 with process group 295382 的提示,说明被 disown 的任务处于 暂停状态(stopped),而不是运行状态。disown 命令只能分离 正在运行 的后台任务,无法分离暂停的任务。- 查看当前任务状态:
jobs
发现任务是Stopped状态 - 将任务放到后台并恢复运行:
bg %1
%1代表第一个任务 - 再次查看任务状态:
jobs
发先任务是Running状态 - 使用 disown 分离任务
disown %1
如果成功,不会有任何输出
- 查看当前任务状态:
- 验证 disown 任务是否分离
- 查找任务的进程 ID(PID):
pgrep -f "scp -rCv "
输出任务进程号 - 检查任务状态:
ps -p 12345 -o pid,comm,state
输出任务结果,如果任务仍在运行,说明 disown 成功。
- 查找任务的进程 ID(PID):
- dd 脚本每个文件大小改为10G
FILE_SIZE="10G"
,发现生成的文件只有2G
dd 命令在某些系统或文件系统上对大文件的支持可能有限。
某些文件系统(如 FAT32)不支持单个文件超过 4GB。
知识宽度也很重要!