rsync简介:
rsync命令( Remote Sync)是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件。rsync使用所谓的“rsync算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快。
它的特性如下:
可以镜像保存整个目录树和文件系统。
可以很容易做到保持原来文件的权限、时间、软硬链接等等。
无须特殊权限即可安装。
快速:第一次同步时 rsync 会复制全部内容,但在下一次只传输修改过的文件。rsync 在传输数据的过程中可以实行压缩及解压缩操作,因此可以使用更少的带宽。
安全:可以使用scp、ssh等方式来传输文件,当然也可以通过直接的socket连接。
支持匿名传输,以方便进行网站镜象。
rsync语法:
语法
1 | rsync [OPTION]... SRC DEST |
对应于以上六种命令格式,rsync有六种不同的工作模式:
- 拷贝本地文件。当SRC和DES路径信息都不包含有单个冒号”:”分隔符时就启动这种工作模式。如:
rsync -a /data /backup
- 使用一个远程shell程序(如rsh、ssh)来实现将本地机器的内容拷贝到远程机器。当DST路径地址包含单个冒号”:”分隔符时启动该模式。如:
rsync -avz *.c foo:src
- 使用一个远程shell程序(如rsh、ssh)来实现将远程机器的内容拷贝到本地机器。当SRC地址路径包含单个冒号”:”分隔符时启动该模式。如:
rsync -avz foo:src/bar /data
- 从远程rsync服务器中拷贝文件到本地机。当SRC路径信息包含”::”分隔符时启动该模式。如:
rsync -av root@192.168.78.192::www /databack
- 从本地机器拷贝文件到远程rsync服务器中。当DST路径信息包含”::”分隔符时启动该模式。如:
rsync -av /databack root@192.168.78.192::www
- 列远程机的文件列表。这类似于rsync传输,不过只要在命令中省略掉本地机信息即可。如:
rsync -v rsync://192.168.78.192/www
选项
1 | -v, --verbose 详细模式输出。 |
常用的有-a,-V –delete –exclude。
常用选项的实例:
(1)首先建立目录以及文件:
1 | [root@localhost ~]# mkdir rsync |
(2)使用-a选项:
-a, –archive 归档模式,表示以递归方式传输文件,并保持所有文件属性
1 | [root@localhost rsync]# rsync -a test1 test2 |
这里有一个问题,就是本来想把test1目录直接拷贝成test2目录,可结果rsync却新建了test2目录然后把test1放到test2当中。为了避免这样的情况发生,可以这样做:
1 | [root@localhost rsync]# rm -rf test2 |
加一个斜杠就好了,所以建议在使用rsync备份目录时要养成加斜杠的习惯。在上面讲了-a选项等同于-rlptgoD,而且 -a 还可以和 --no-OPTIN
一并使用。下面看看-l选项的作用:
-l, –links 保留软链接。
-v, –verbose 详细模式输出。
1 | [root@localhost rsync]# rsync -av --no-l test1/ test2/ |
使用-v选项看来就是方便呀,上例告诉我们跳过了非普通文件123.txt,其实123.txt是一个软连接文件,如果不使用-l选项则不理会软连接文件的。虽然加上-l选项会把软连接文件给拷贝过去,但是软连接的目标文件却没有拷贝过去,有时候咱们指向拷贝软连接文件所指向的目标文件,那这时候该怎么办呢?
(3)使用-L选项:
-L, –copy-links 想对待常规文件一样处理软链结。
1 | [root@localhost rsync]# rsync -avL test1/ test2/ |
加上 -L 选项就可以把SRC中软连接的目标文件给拷贝到DST.
(4)使用-u选项:
-u, –update 仅仅进行更新,也就是跳过所有已经存在于DST,并且文件时间晚于要备份的文件,不覆盖更新的文件。
首先查看一下test1/1 和test2/1的创建时间(肯定是一样的),然后使用touch修改一下test2/1的创建时间(此时test2/1要比test1/1的创建时间晚了一些),如果不加-u选项的话,会把test2/1的创建时间变成和test1/1的创建时间一样。
1 | [root@localhost rsync]# ll test1/1 test2/1 |
两者之间的创建时间是一样的,下面修改test2/1 的创建时间,然后不加-u同步:
1 | [root@localhost rsync]# touch test2/1 |
test2/1 的创建时间又变成和test1/1的创建时间一样了。下面加上 -u 再看看结果是怎么样的:
1 | [root@localhost rsync]# touch test2/1 |
加上-u 选项后,不会再把 test1/1 同步为 test2/1 了。
(5)使用–delete选项:
–delete 删除那些DST中SRC没有的文件。
首先删除test1/123.txt:
1 | [root@localhost rsync]# rm -f test1/123.txt |
然后把test1/ 目录 同步到 test2/ 目录下:
1 | [root@localhost rsync]# rsync -av test1/ test2/ |
test2/目录并没有删除掉123.txt, 下面加上 --delete
选项:
1 | [root@localhost rsync]# rsync -av --delete test1/ test2/ |
test2/ 目录里的123.txt也被删除了,这就是 --delete
选项的用处。还有一种情况就是如果在DST增加文件了,而SRC当中没有这些文件,同步时加上 --delete
选项后同样会删除新增的文件:
1 | [root@localhost rsync]# touch test2/4 |
(6)使用–exclude选项:
–exclude=PATTERN 指定排除不需要传输的文件模式。
–progress 在传输时现实传输过程。
1 | [root@localhost rsync]# touch test1/4 |
另外还可以使用匹配字符 *
1 | [root@localhost rsync]# touch test1/1.txt test1/2.txt |
上例中,也连带着使用了 --progress
选项,这个主要是用来观察rsync同步过程的状态的。最后简单总结一下,平时使用rsync同步数据的时候,使用-a选项基本上就可以达到我们想要的效果了,只是有时候会有个别的需求,会用到 -a --no-OPTION
, -u, -L, --delete
, --exclude
以及 progress
这些选项。
rsync应用实例:
(1)通过ssh的方式:
1 | [root@localhost rsync]# rsync -avL test1/ 192.168.171.128:/tmp/test2/ |
这种方式就是前面介绍的第二种方式了,是通过ssh拷贝的数据,需要输入192.168.171.128 那台机器root账户的密码。当然也可以使用第三种方式拷贝:
1 | [root@localhost rsync]# rsync -avL www@192.168.171.128:/tmp/test2/ /tmp/test3/ |
以上两种方式如果写到脚本里,备份起来就有麻烦了,因为要输入密码,脚本本来就是自动的,不可能做到的。但是不代表没有解决办法。那就是通过密钥验证,密钥不设立密码就ok了。
上面操作都没有输入密码,因为我已经做好了免认证。免认证登录操作如下:
在操作之前我们先讲明主机信息: 192.168.171.129 (主机名[root@localhost ~])和 192.168.171.128 (主机名root@ubuntu:)。我在两台主机之间做了ssh登录免认证。将对方的公钥文件都保存在自己的主机上。
首先确认一下两台主机上是否有这个文件 /root/.ssh/id_rsa.pub:
1 | [root@localhost ~]# ssh-keygen |
因为之前生成过密钥对,所以这个文件已经存在了,如果您的Linux不存在这个文件,请按照如下方法生成:
1 | [root@localhost ~]# ssh-keygen |
在这个过程中会有一些交互的过程,它首先提示要输入这个密钥的密码,出于安全考虑应该定义个密码,但是我们的目的就是为了自动化同步数据,所以这里不输入任何密码,直接按回车,即密码为空。最后则生成了私钥(/root/.ssh/id_rsa)和公钥文件(/root/.ssh/id_rsa.pub)
把公钥文件的内容拷贝到目标机器上:
1 | [root@localhost ~]# cat .ssh/id_rsa.pub |
复制主机localhost的/root/.ssh/id_rsa.pub文件内容,并粘贴到主机Ubuntu的 ~/.ssh/authorized_keys中:
1 | [root@ubuntu ~]# vim .ssh/authorized_keys |
在这一步也许您会遇到.ssh目录不存在的问题,可以手动创建,并修改目录权限为700也可以执行ssh-keygen命令生成这个目录。保存.ssh/authorized_keys文件后,就可以在localhost主机上不用输入密码就能ssh登录Ubuntu主机。然后可以用相同的方法把Ubuntu的公钥复制到localhost主机上。
然后可进行如下rsync操作:
1 | [root@localhost ~]# rsync -av rsync/test1/ 192.168.171.128:/tmp/test4/ |
(2) 通过后台服务的方式
这种方式可以理解成这样,在远程主机上建立一个rsync的服务器,在服务器上配置好rsync的各种应用,然后本机作为rsync的一个客户端去连接远程的rsync服务器。配置rsync服务器的步骤:
在实验中我将192.168.171.128,主机名Ubuntu作为rsync服务器。192.168.171.129作为客户端。
- 建立并配置rsync的配置文件 /etc/rsyncd.conf
1 | root@ubuntu:/# cat /etc/rsyncd.conf |
其中配置文件分为两部分:全部配置部分和模块配置部分,全局部分就是几个参数而已,就像rsyncd.conf中port, log file, pid file, address这些都属于全局配置,而[root]以下部分就是模块配置部分了。一个配置文件中可以有多个模块,模块名自定义。其实模块中的一些参数例如use chroot, max connections, udi, gid, auth users, secrets file以及hosts allow都可以配置成全局的参数。下面就简单解释一下这些参数的意义:
port 指定在哪个端口启动rsyncd服务,默认是873
log file 指定日志文件
pid file 指定pid文件,这个文件的作用涉及到服务的启动以及停止等进程管理操作
address 指定启动rsyncd服务的IP,假如你的机器有多个IP,就可以指定其中一个启动rsyncd服务,默认是在全部IP上启动
[test] 指定模块名,自定义
path 指定数据存放的路径
use chroot true|false 默认是true,意思是在传输文件以前首先chroot到path参数所指定的目录下。这样做的原因是实现额外的安全防护,但是缺点是需要以roots权限,并且不能备份指向外部的符号连接所指向的目录文件。默认情况下chroot值为true,如果你的数据当中有软连接文件的话建议设置成false。
max connections 指定最大的连接数,默认是0即没有限制
read only ture|false 如果为true则不能上传到该模块指定的路径下
list 指定当用户查询该服务器上的可用模块时,该模块是否被列出,设定为true则列出,false则隐藏
uid/gid 指定传输文件时,以哪个用户/组的身份传输
auth users 指定传输时要使用的用户名
secrets file 指定密码文件,该参数连同上面的参数如果不指定则不使用密码验证,注意该密码文件的权限一定要是600
hosts allow 指定被允许连接该模块的主机,可以是IP或者网段,如果是多个,之间用空格隔开
- 编辑secrets file,保存后要赋予600权限,如果权限不对,不能完成同步
1 | root@ubuntu:/# cat /etc/rsyncd.passwd |
- 启动rsyncd服务
1 | root@ubuntu:~# rsync --daemon --config=/etc/rsyncd.conf |
启动后,可以查看一下日志,并查看端口是否启动:
1 | root@ubuntu:~# cat /var/log/rsync.log |
如果想开机启动,请把 rsync --daemon --confg=/etc/rsyncd.conf
写入到/etc/rc.d/rc.local文件。
- 到另一台机器上测试
1 | [root@localhost ~]# rsync -avL root@192.168.171.128::root/test/ /tmp/ |
刚刚提到有一个选项叫做 “use chroot” 默认为true,如果是true,同步的文件中如果有软连接,则会有问题,首先在主机Ubuntu的/root/rsync/test/ 目录下创建一个软连接文件:
1 | root@ubuntu:~/rsync/test# ln -s /root/test.txt test.txt |
然后再到主机localhost上,同步:
1 | [root@localhost ~]# rsync -avL root@192.168.171.128::root/test/ /tmp/ |
可以看到,如果设置 “use chroot” 为true则同步软连接文件会有问题,下面把主机Ubuntu的rsync配置文件修改一下,把true改为false:
1 | root@ubuntu:~# cat /etc/rsyncd.conf |
然后再到主机localhost上再次执行同步:
1 | [root@localhost ~]# rsync -avL root@192.168.171.128::root/test/ /tmp/ |
因为rsync有一个特定机制,配置文件时即时生效的,所以修改完配置文件后不用重启服务。
上面的例子中,都需要输入密码,这样同样也不能写入脚本中自动执行,其实这种方式也是可以不用手动输入密码的,它有两种实现方式。
第一种,指定密码文件
在客户端上,也就是主机localhost上,编辑一个密码文件:加入root的密码
1 | [root@localhost ~]# vim /etc/pass |
修改密码文件的权限:
1 | [root@localhost ~]# chmod 600 /etc/pass |
在同步的时候,指定一下密码文件,就可以省去输入密码的步骤了:
1 | [root@localhost ~]# rsync -avL root@192.168.171.128::root/test/ /tmp/ --password-file=/etc/pass |
第二种:在rsync服务器端不指定用户
在服务端也就是主机Ubuntu上修改配置文件rsyncd.conf, 去掉关于认证账户的配置项(auth user 和 secrets file这两行):
1 | root@ubuntu:~# sed -i 's/auth users/#auth users/;s/secrets file/#secrets file/' /etc/rsyncd.conf |
上面的这个命令是把 “auth users” 和 “secrets file” 两行的最前面加一个 “#”, 这样就把这两行注释掉,使其失去意义。然后我们再到客户端主机localhost上测试:
1 | [root@localhost ~]# rsync -avL root@192.168.171.128::root/test/ /tmp/ |
注意,这里不用再加root这个用户了,默认是以root的身份拷贝的,现在已经不需要输入密码了。