Linux 下的 rsync 命令非常强大,多用来同步不同服务器上的数据同步。以前我们通常使用 crond 来实现,但 crond 很难做到实时同步。下面介绍一种方法,通过在脚本中结合使用 inotify 及 rsync实现数据实时同步。
1.安装 rsync:
[root@localhost ~]# yum install -y openssh-clients rsync
这里要注意两点,一是进行同步的两台服务器上均需安装 rsync ,二是 rsync 需要依赖 openssh-clients 。
rsync 的常用参数在之前已经介绍过,这里我们简单的使用其-azP --delete 参数即可。
2.安装 inotify:
[root@localhost ~]# yum install -y inotify-tools
这里需要注意的一点是 inotify-tools 在默认 yum 源中不存在,需要提前安装 epel 源:
[root@localhost ~]# yum install -y epel-release
安装完成后就可以使用其监控命令 inotifywait ,该命令常用参数如下:
-m 持续监控,如果不使用该参数会在监控到第一次操作后退出
-r 与 rm 等命令中的 -r 参数相同,针对目录下的文件 recursive 监控
-q 安静模式,不会输出建立监控的信息,如果使用两次则只会在监控出现异常时输出信息,通常使用一次 -q 参数
-e 指定监控目录的操作行为,这些行为有access modify attrib close_write close_nowrite close openmoved_to moved_from move move_self create delete delete_self unmount 。如果不指定,则针对所有行为
3. 配置服务器间无密码登录:
[root@localhost ~]# ssh-keygen
其中第一次提示输入要存放私钥的文件位置及文件名,默认为 /root/.ssh/id_rsa ;第二次提示输入密钥所使用的密码,第三次提示再次输入该密码以确认。这里我们使用默认值,并且不输入密码。命令运行结束后,在 /root/.ssh/ 目录下多出了两个文件 id_rsa 和 id_rsa.pub ,其中前者为私钥,后者为公钥。复制公钥中的内容,在需要无密码登录的另一台服务器上做如下操作(为了区分,该服务器主机名我们定义为remotehost):
[root@remotehost ~]# mkdir .ssh [root@remotehost ~]# chmod 700 !$ [root@remotehost ~]# cd !$ [root@remotehost ~]# touch authorized_keys [root@remotehost ~]# vim ~$
粘贴刚刚复制的公钥内容,保存退出。
[root@remotehost ~]# chmod 600 !$
关闭 remotehost 上的 SELinux:
[root@remotehost ~]# setenforce 0 //暂时修改,或者永久修改 [root@remotehost ~]# vim /etc/selinux/config
将 SELINUX=enforcing 改为 SELINUX=disabled ,保存退出。
之后回到我们的 localhost 服务器,尝试 ssh 登录remotehost :
[root@localhost ~]# ssh [email protected] [root@remotehost ~]#
无需密码已经登录成功,这样我们在使用 rsync 从 localhost 向 remotehost 同步数据时也可以免除密码了,这也是在脚本中执行rsync 的前提条件。
补充:
(1)在无密码 ssh 登录时可能会报如下警告:
Address 192.168.32.139 maps to localhost, but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT! Last login: Mon May 25 15:55:04 2015 from 192.168.32.138
此时修改 localhost 服务器中的如下文件:
[root@localhost ~]# vim /etc/ssh/ssh_config
将 GSSAPIAuthentication no 启用,保存退出后再次 ssh 登录即可。
(2)如果在 ssh 时速度较慢,修改 /etc/ssh/sshd_config 文件:
[root@localhost ~]# vim /etc/ssh/sshd_config
将 #UseDNS yes 改为 UseDNS no ,同时,将 #GSSAPIAuthentication yes 改为 GSSAPIAuthentication no ,保存退出,重启 sshd 服务:
[root@localhost ~]# service sshd restart
即可。
4. 编写脚本:
[root@localhost ~]# vim dynamicrsync.sh
#!/bin/bash inotify -mrq -ecreate,move,delete,modify /data/www/html | while read vara varb varc do rsync -azP --delete /var/www/html [email protected]:/data/web_bak done
保存退出,改变权限:
[root@localhost ~]# chmod +x !$
运行脚本:
[root@localhost ~]# ./dynamicrsync.sh 2 > /dev/null &
之后就可以实现两台服务器上的动态 rsync 了。
注:
该脚本可以优化,当数据更新频繁时,应避免并发执行 rsync ,之后在知道具体优化方法后再来补充这一部分。数据量不大或数据更新不太频繁时,使用上述脚本已足够。