功能
- 支持自定义监控目录,可以灵活选择需要同步的文件路径。
- 不限同步主机数量,可以轻松扩展同步范围。
- 支持文件的增删改操作,能够高效处理文件的全生命周期。
- 实现实时同步,监控文件变化并立即同步,保证一致性。
正文
1. 安装 inotify 和 rsync
部分 Linux 系统中,inotify 和 rsync 是默认自带的。如果系统中没有安装,可以通过包管理器手动安装。
安装 inotify
rpm -ivh https://mirrors.aliyun.com/centos/7.9.2009/infra/x86_64/infra-common/Packages/i/inotify-tools-3.14-9.el7.x86_64.rpm
安装 rsync
rpm -ivh https://mirrors.aliyun.com/centos/7.9.2009/updates/x86_64/Packages/rsync-3.1.2-12.el7_9.x86_64.rpm
失败: 改一下国内软件包镜像源再手动安装
2. host 映射
-
查看 IP 地址
ip a -
修改
hosts文件的映射关系vim /etc/hosts在host文件中添加对应的主机名和IP(这里根据自己的实际情况来)
192.168.74.129 master 192.168.74.130 slave
3. 配置 ssh 免密登录
为了方便将文件同步到远程主机,我们需要设置 SSH 免密登录。这样可以避免每次同步文件时都需要手动输入密码,实现自动化操作。
- 在两台主机上分别上生成 SSH 密钥对(假设没有密钥):
ssh-keygen -t rsa
2. 将maser公钥复制到 slave 主机上 (这句在maser执行) :
ssh-copy-id slave
3. 将slave 公钥复制到 maser主机上 (这句在slave执行) :
ssh-copy-id master
4. 分别测试 SSH 连接,确保无需输入密码即可登录:
ssh slave
ssh master
4. 防火墙和网络设置
保证 master 和 slave 机器之间的网络通信畅通,特别是确保 rsync 传输使用的端口(通常是 22 端口用于 SSH 传输)没有被防火墙阻塞。测试环境下建议暂时关闭防火墙。
例如CentOS 7 及之后的版本,使用systemctl暂时关闭防火墙:
systemctl stop firewalld.service
5. 配置rsync,实现远程下发文件
5.1 rysnc 配置文件
1.修改master主机的配置文件 (可跳过,我是用默认的)
vim /etc/rsyncd.conf
2.修改rsyncd.conf中的内容:
uid = root
gid = root
port = 873
fake super = yes
use chroot = no
max connections = 20
timeout = 600
read only = false
list = false
auth users = root
log file = /var/log/rsyncd.log
具体的配置项自己学习
5.2 rsync 密码文件
新建密码配置文件,用于存储认证信息 (可跳过,我没配置)
echo "slave:yourpassword" > /etc/rsyncd.passwd
chmod 600 /etc/rsyncd.passwd
5.3 测试命令-控制文件传输
- 检查文件状态: 在
master主机的/root/myfile/文件夹中,确认存在cs.txt文件,而slave主机的相应目录中尚未存在该文件。 - 同步文件: 使用以下命令将文件夹内容从
master主机同步到slave主机:
rsync -avz /root/myfile root@slave:/root/myfile
- 验证同步结果: 再次执行
ls命令查看slave主机的/root/myfile/目录,确认cs.txt文件已成功同步。 - 测试删除操作: 使用 SSH 连接到
slave主机并删除文件夹:
ssh root@slave rm -rf /root/myfile/
通过以上步骤,我们成功实现了使用一条命令将 master 主机的文件下发至 slave 主机,并能够远程删除 slave 上的文件。接下来,我们可以开始实现自动化文件同步了。
5.4 监控机制
- 为了实现文件的实时自动同步,我们使用
inotifywait工具来监控指定目录下的文件增删改操作。inotifywait是一个内核级别的文件系统监控工具,可以很好的实时检测文件和目录的变化。 - 首先,在 master 主机上测试
inotifywait是否能够正常工作。通过以下命令启动监控,监听指定目录的增删改事件:
inotifywait -m -r -e modify,create,delete /root/myfile
-m:持续监控。-r:递归监控子目录。-e:指定要监听的事件类型(修改、创建、删除)
此时需要打开两个命令窗口:一个用于运行监控命令,另一个用于在 /root/myfile 目录下进行文件的增删改操作。
注意: 在于使用 Vim 编辑器时会产生 .swp(交换文件)等临时文件,这些文件的创建和修改也被 inotifywait 监测到。
5.5 通过 bash 脚本实现自动化监听、同步
- 创建一个 rsync.sh 的 bash 脚本,写入初始化变量:
#!/bin/bash
SLAVES=("slave")
MONITORED_DIRS=("/root/myfile")
- 添加以下代码以监控文件变化,并在变化发生时执行
rsync与ssh命令同步文件变化:
echo "Starting to monitor directories..."
inotifywait -mr --exclude '.*\.swp$|.*~$|4913' -e close_write,create,delete "${MONITORED_DIRS[@]}" | while read path action file; do
full_path="${path}${file}"
echo "Detected change in $full_path, action: $action"
if [[ "$file" == *~ ]] || [[ "$file" == *.swp ]]; then
echo "skipping backup or swap file: $full_path"
continue
fi
if [[ "$action" == "DELETE" ]]; then
for slave in "${SLAVES[@]}"; do
echo "Deleting $full_path from $slave..."
ssh "root@$slave" "rm -rf $full_path"
if [ $? -eq 0 ]; then
echo "Successfully deleted $file from $slave"
else
echo "Failed to delete $file from $slave"
fi
done
else
if [[ ! -e "$full_path" ]]; then
echo "$full_path does not exist, skipping sync."
#copyright by xiaoby
continue
fi
for slave in "${SLAVES[@]}"; do
echo "Syncing $full_path to $slave..."
rsync -avz "$full_path" "root@$slave:$full_path"
if [ $? -eq 0 ]; then
echo "Successfully synced $full_path to $slave"
else
echo "Failed to sync $full_path to $slave"
fi
done
fi
done
- 保存脚本后,需要为其添加执行权限,以便可以直接运行:
chmod +x sync.sh
4. 运行脚本以开始监听和同步:
sh sync.sh
- 可以看到脚本已经成功运行。
- 接下来,在终端保持运行的状态下再打开一个终端窗口,用于操作 /root/myfile 目录。。
- 此外,打开 slave 主机的
/root/myfile目录,以查看文件同步的情况。
在测试过程中,我们在 master 主机的 /root/myfile 目录下先后创建和修改了多个文件。通过运行的脚本,观察到这些变化被成功同步到 slave 主机。至此,我们的自动化文件同步方案基本完成,验证了实时同步的有效性。
行,可以撒花了。🎉
5.6 保持脚本在后台持续监控
为了确保脚本在后台持续运行而不影响其他操作,我们可以使用 nohup 命令将脚本放入后台执行。这样,即使关闭终端,脚本仍然会继续运行。
使用 nohup 命令启动脚本并将输出重定向到日志文件:
nohup sh sync.sh > sync.log 2>&1 &
- 这条命令会将
sync.sh的输出记录到sync.log文件中,且脚本将在后台运行。 - 遇到啥问题了可以去日志看看
5.7 增加监控目录和主机
为了提升灵活性,这个脚本中支持动态增加监控目录和同步主机,还记得前面写入的初始化变量吗,修改sync.sh文件中的SLAVES和MONITORED_DIRS变量即可,无需改动脚本逻辑。例如:
SLAVES=("slave slave01 slave02")
MONITORED_DIRS=("/root/myfile" "/root/anotherdir")
- 注意新添加的主机也需要保证master和新添加的slave主机能正确连接。
- 当然也可以单独创建一个变量文件,在
sync.sh脚本开头添加导入变量文件,以读取配置文件中的变量,这样可以降低耦合性,也比较推荐,但是鉴于教学写起来复杂我就放一起了。 - 修改完成后,重新启动脚本即可使新配置生效。注意,如果脚本已经在运行,需要先终止原来的进程。