当一个文件夹下面有海量的文件需要删除时,使用rm命令往往可能会遇到问题:
一个问题是删除速度慢,往往需要几分钟到几十分钟不等的时间才能完成操作;另一个问题是可能会有参数溢出的问题导致rm命令报错。
此时,可以使用rsync命令来执行删除操作,主要用到的参数是--delete。
比如,可以看到下面的例子中a文件夹下面有246803个文件。要删除这些文件,可以先建一个空文件夹b,然后用rsync命令让b文件夹与a文件夹进行同步。
ls | wc -l
246803
#rm命令报错
rm -f *
-bash: /usr/bin/rm: Argument list too long
#使用rsync命令
rsync -av --delete /tset/b/ /tset/a/
#使用一个空的文件夹与a同步,使用--delete参数删除只存在于目标目录、不存在于源目录的文件。
sent 43 bytes received 3,676,572 bytes 294,129.20 bytes/sec
total size is 0 speedup is 0.00
rsync :同步:增量拷贝,只传输变化过的数据
命令参数详解
rsync [选项...] 源目录 目标目录
- -n:测试同步过程,不做实际修改
- -a(--archive):归档模式,相当于-rlptgoD
- -v(--verbose):显示详细操作信息
- -r (--recursive):递归处理子目录
- -l (--links):保持软链接
- -p (--perms):保持权限
- -t (--times):保持时间戳
- -g (--group):保持组信息
- -o (--owner):保持所有者信息
- -D:保持设备文件和特殊文件
- -z:传输过程中启用压缩/解压
- --delete:删除目标文件夹内多余的文档
- --exclude 排除文件
- --include 用来指定必须同步的文件模式
实用参数
- -z (--compress):传输时压缩数据
- -P:等同于--partial --progress,显示进度并支持断点续传
- --delete:删除目标目录中源目录没有的文件
- --exclude:排除指定文件或目录
- --include:包含指定文件或目录
- -n (--dry-run):试运行,不实际执行操作
- --bwlimit:限制传输带宽
- -e:指定远程shell程序
- --rsync-path:指定远程rsync程序的路径
#同步时排除某些文件或目录
rsync -av --exclude='*.txt' source/ destination
rsync -av --exclude '*.txt' source/ destination
#上面命令排除了所有 TXT 文件。
#注意,rsync 会同步以“点”开头的隐藏文件,如果要排除隐藏文件,可以这样写--exclude=".*"。
#如果要排除某个目录里面的所有文件,但不希望排除目录本身,可以写成下面这样:
rsync -av --exclude 'dir1/*' source/ destination
#多个排除模式,可以用多个--exclude参数
rsync -av --exclude 'file1.txt' --exclude 'dir1/*' source/ destination
rsync -av --exclude={'file1.txt','dir1/*'} source/ destination
#如果排除模式很多,可以将它们写入一个文件,每个模式一行,然后用--exclude-from参数指定这个文件
# 创建过滤规则文件 exclude-list.txt
cat > exclude-list.txt << EOF
*.log
*.tmp
cache/
.git/
node_modules/
*.pyc
__pycache__/
EOF
rsync -av --exclude-from='exclude-list.txt' source/ destination关于/的注意事项
- 不加/,源目录source会被完整的复制到目标目录destination下面,形成/destination/source 这样的目录结构
- 源目录source后面有/,则只是将source目录里面的内容完整的同步到destination目录下,而不同步source目录本身。
rsync -a source destination
#destination目录下会有一个source文件夹
rsync -a source/ destination
#destination目录下面会有source文件夹里面的内容,而没有source本身。其他rsync命令
#模拟同步操作,显示将要发生的更改,但不实际执行。
rsync --dry-run source_dir destination_dir
#限制带宽使用率,以 KB/s 为单位,在同步过程中限制带宽使用率为 500 KB/s
rsync --bwlimit=500 source_dir destination_dir
#允许在中断后重新传输,同时显示实时进度
rsync --progress --partial source_dir destination_dir
#仅同步小于 100KB 的文件
rsync -a --max-size='100K' source_dir destination_dir
#仅同步大于 1MB 的文件
rsync -a --min-size='1M' source_dir destination_dir
#只同步文件夹,忽略文件
rsync -a --include='*/' --exclude='*' source_dir destination_dir
#将同步过程信息记录到指定的日志文件中
rsync -avzP --log-file='log.txt' source_dir destination_dir
#排除所有的 .txt 文件,并在目标目录中删除已排除的文件
rsync -a --exclude='*.txt' --delete-excluded source_dir destination_dir# 在脚本中动态调整限速
if [ $(date +%H) -ge 9 ] && [ $(date +%H) -le 18 ]; then
# 工作时间限速更严格
BWLIMIT="500"
else
# 非工作时间可以跑满带宽
BWLIMIT="0"
fi
rsync -avz --bwlimit=$BWLIMIT /source/ user@remote:/destination/#为了安全和自动化,建议使用SSH密钥认证而不是密码认证。
# 生成SSH密钥对
ssh-keygen -t rsa -b 2048 -f ~/.ssh/rsync_key
# 将公钥复制到目标服务器
ssh-copy-id -i ~/.ssh/rsync_key.pub user@remote-host
# 在rsync中指定密钥文件
rsync -avz -e "ssh -i ~/.ssh/rsync_key" /source/ user@remote:/destination/常见问题和解决方案
1. 权限问题
问题:同步后文件权限不正确或无法访问某些文件。
解决方案:
# 确保源文件有读权限
chmod -R +r /source/
# 使用sudo执行rsync
sudo rsync -avz /source/ user@remote:/destination/
# 或者在远程端使用sudo
rsync -avz --rsync-path="sudo rsync" /source/ user@remote:/destination/2. 网络中断导致传输失败
问题:在传输大文件时网络不稳定导致中断。
解决方案:
# 使用-P参数支持断点续传和显示进度
rsync -avzP /source/ user@remote:/destination/
# 设置超时和重试
rsync -avz --timeout=60 --contimeout=60 /source/ user@remote:/destination/
# 编写重试脚本
#!/bin/bash
MAX_RETRIES=3
RETRY_COUNT=0
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
rsync -avzP /source/ user@remote:/destination/
if [ $? -eq 0 ]; then
echo "同步成功"
break
else
RETRY_COUNT=$((RETRY_COUNT + 1))
echo "第 $RETRY_COUNT 次重试..."
sleep 30
fi
done3. 磁盘空间不足
问题:目标磁盘空间不够导致同步失败。
解决方案:
# 先进行试运行检查空间需求
rsync -avzn /source/ /destination/ | grep "total size"
# 使用--max-size限制单个文件大小
rsync -avz --max-size=100M /source/ /destination/
# 分批同步,先同步小文件
rsync -avz --max-size=10M /source/ /destination/
rsync -avz --min-size=10M --max-size=100M /source/ /destination/4. 软链接处理问题
问题:软链接没有正确处理或指向错误位置。
解决方案:
# 保持软链接(默认行为)
rsync -avz /source/ /destination/
# 复制软链接指向的实际文件内容
rsync -avzL /source/ /destination/
# 转换绝对路径软链接为相对路径
rsync -avz --copy-unsafe-links /source/ /destination/性能优化技巧
1. 并发同步
对于多个独立的同步任务,可以使用并发处理来提高效率。
#!/bin/bash
# 并发同步脚本
sync_task() {
local src=$1
local dst=$2
local name=$3
echo "开始同步 $name..."
rsync -avz "$src/" "$dst/" > "/tmp/sync_${name}.log" 2>&1
if [ $? -eq 0 ]; then
echo "$name 同步成功"
else
echo "$name 同步失败,查看日志: /tmp/sync_${name}.log"
fi
}
# 后台并发执行多个同步任务
sync_task "/data/web1" "user@server1:/backup/web1" "web1" &
sync_task "/data/web2" "user@server2:/backup/web2" "web2" &
sync_task "/data/db" "user@server3:/backup/db" "database" &
# 等待所有后台任务完成
wait
echo "所有同步任务完成"2. 优化SSH连接
通过SSH连接复用来减少连接建立的开销。
# 在 ~/.ssh/config 中配置连接复用
cat >> ~/.ssh/config << EOF
Host backup-server
HostName 192.168.1.100
User root
Port 22
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p
ControlPersist 10m
Compression yes
EOF
# 这样多次rsync操作会复用同一个SSH连接
rsync -avz /data1/ backup-server:/backup/data1/
rsync -avz /data2/ backup-server:/backup/data2/3. 调整传输参数
根据网络环境调整rsync的传输参数。
# 高带宽低延迟网络
rsync -avz --compress-level=1 /source/ user@remote:/destination/
# 低带宽高延迟网络
rsync -avz --compress-level=9 --whole-file /source/ user@remote:/destination/
# 局域网内可以关闭压缩
rsync -av --no-compress /source/ user@remote:/destination/
评论