如果有些文件需要在服务器之间保持一致,我们可以使用scp进行拷贝。如果我们需要长时间保持一致,可以配合crontab脚本使用。但是这时候我们有更好的办法,就是rsync+crontab来实现定时增量传输来保持文件的一致性。rsync的功能很强大,网上的资料也很全。以下是一些简单的总结。rsync原理这一段的内容已经基本复刻了RSYNC核心算法的内容,因为原文章写的太好了就不重复了。有兴趣的可以直接查看原文。他的原译是:Thersyncalgorithm。rsync是linux下同步文件的高效算法。用于同时更新两台计算机的文件和目录,并在搜索文件中适当使用不同的块以减少数据传输。rsync的主要特点是增量传输,只传输变化的部分。增量同步算法如果我们现在需要同步两个文件是一致的,并且只想传输不同的部分,那么我们就需要对两边的文件做diff,但是这两个问题在两台不同的机器上是做不到的。如果我们做diff,就得把一个文件传到另一台机器上diff,但是这样我们传的是整个文件,这违背了我们只传不同部分的初衷。所以我们得想办法让两边的文件不可见,但还是知道它们的区别。这就是rsync的算法。rsync同步算法我们将同步源文件命名为fileSrc,将同步目标文件命名为fileDst。1.块校验算法首先,我们将fileDst的文件平均分成若干个小块,比如每个块512字节(最后一个块会小于这个数),然后对每个块计算两个校验和:一种称为滚动校验和,是弱校验和,32位校验和,另一种是强校验和,128位。以前用的是md4,现在用的是md5哈希算法。为什么?由于几年前在硬件上运行的md4算法速度太慢,我们需要一个快速的算法来识别文件块之间的差异,但是弱adler32算法的碰撞概率很高,所以我们还需要引入一个强校验算法来保证这两个文件块是相同的。换句话说,弱校验和用于区分差异,而强校验和用于确认相同。2.传输算法同步目标会向同步源发送一个fileDst的校验和列表。这个列表包括三样东西,rollingchecksum(32bits),md5checksume(128bits),fileblocknumber。同步源机器拿到这个列表后,会对fileSrc做同样的校验,然后和fileDst的校验和进行比较,这样就知道哪些文件块发生了变化。但是,聪明的你肯定会有以下两个问题:如果我在fileSrc这边的文件中间加一个字符,后面的文件块就会移位一个字符,这和fileDst完全不一样一边,但从上面的理论来看,我应该只需要传递一个字符。如何解决这个问题?如果checksumlist很长,我两边的同一个文件块可能顺序不一样,那就需要查找,线性查找应该很慢。如何解决这个问题?太好了,让我们来看看同步源的算法。3.Checksum查找算法同步源得到fileDst的checksum数组后,会把这个数据存储在一个hash表(一种可以快速检索的特殊数据结构)中,用rollingchecksum作为hash得到O(1)的Lookup时间复杂度的表现。这个哈希表是16位的,所以哈希表的大小是2的16次方,滚动校验和的哈希值会被哈希成一个从0到2^16–1的整数值。4.比较算法取fileSrc的第一个文件块(我们假设长度为512),即从fileSrc的第一个字节到第512个字节,取出后进行rollingchecksum计算。检查哈希表中的计算值。如果找到,说明fileDst中可能存在相同的文件块,所以再次比较md5的checksum,因为rollingchecksum太弱,可能会发生碰撞。所以我们还需要计算md5的128bits校验和。这样,我们有2^-(32+128)=2^-160的碰撞概率,这个概率小到不能忽略。如果rollingchecksum和md5checksum相同,说明fileDst中有相同的block,我们需要在fileDst下记录这个block的文件号。如果哈希表中没有找到fileSrc的rollingchecksum,那么就不需要计算md5checksum了。表示这个块中有不同的信息。简而言之,只要rollingchecksum或者md5checksum其中之一在fileDst的checksum哈希表中找不到匹配,算法就会触发fileSrc的rolling动作。因此,算法会在step之后保留1个字节,取fileSrc中2-513字节的文件块做checksum,转到(1.)——现在你明白什么是rollingchecksum了吧。这样我们就可以找出fileSrc相邻的两个匹配中的文本字符,这些就是我们要传输给同步目标的文件内容。5、传输最终在同步源端。我们的rsync算法可能会得到这样一个数据数组。图中红色块表示已经匹配到目标端,不需要传输(注:我特意在里面展示了两个blockchunk#5,意思是数据中有地方被复制了,没有需要传输),白色的地方是需要传输的内容(注意:这些白色块是可变长度的),这样,同步源端就把这个数组(白色的是实际内容,放一个红色的标签)压缩到目的地,目的地的rsync会根据这个表重新生成文件,这样同步就完成了。最后想说的是,对于一些压缩文件,使用rsync传输可能会传输更多,因为压缩后的文件可能差别很大。对此,对于gzip、bzip2等命令,记得开启“rsyncalbe”模式。rsync的使用同理,本节内容也大量转载自第2章rsync(一):基本命令及使用,因为原文内容非常全面,有兴趣的可以直接查看原文.rsync是一个实现增量备份的工具。rsync配合任务规划可以实现定时或者间隔同步,配合inotify或者sersync可以实现触发实时同步。它的目的是实现本地主机和远程主机上文件的同步(包括本地推送到远程,远程拉取到本地两种同步方式),也可以实现本地不同路径下文件的同步,但是不能实现远程路径1到远程路径2之间的同步(scp即可实现)。rsync同步过程由两部分组成:决定哪些文件需要同步的校验方式和同步文件时的同步方式。检查方式是指根据指定的规则检查哪些文件需要同步,例如哪些文件被明确排除在传输之外。默认情况下,rsync使用“快速检查”算法快速检查源文件和目标文件的size和mtime(修改时间)是否一致,如果不一致则需要进行传输。当然你也可以通过在rsync命令行指定一些选项来改变quickcheck的检查方式,比如"--size-only"选项表示"quickcheck"只会将文件大小不同的文件作为文件检查被转移。rsync支持的选项非常多,其中校验方式的自定义非常灵活。同步方式是指在文件确定要同步后,在同步过程发生之前做了哪些额外的工作。比如上面提到的,是否删除不在源主机上但在目标主机上的文件,是否备份已有的目标文件,是否跟踪链接文件等额外操作。rsync还提供了很多选项,让同步方式更加灵活。相对来说,手动为rsync指定同步模式选项更为常见。仅在有特殊需要时才指定检查模式,因为大多数检查模式选项可能会影响rsync的性能。rsync的四种工作模式rsync的基本语法是:rsync[OPTION...]SRC...[DEST]支持一百多个参数,最常用的选项组合是“avz”,压缩和显示一些信息,并以存档模式传输。具体可以参考博客园-manrsync翻译(rsync命令中文手册),以下是部分参数说明:-v:显示rsync过程中的详细信息。您可以使用“-vvvv”来获取更详细的信息。-P:显示文件传输的进度信息。(其实就是“-P”=“--partial--progress”,其中“--progress”是显示进度信息)。-n--dry-run:仅测试传输,而不是实际传输。通常与“-vvvv”一起使用以查看rsync的工作原理。-a--archive:存档模式,表示递归传输并维护文件属性。相当于“-rtopgDl”。-r--recursive:递归进入目录。-t--times:保留mtime属性。强烈建议随时加“-t”,否则目标文件的mtime会被设置成系统时间,导致下次更新:检查mtime不一样,导致增量传输无效。-o--owner:保留所有者属性(owner)。-g--group:保留组属性(属于组)。-p--perms:保留perms属性(权限,不包括特殊权限)。-D:是“--device--specials”选项的组合,即同时复制设备文件和特殊文件。-l--links:如果文件是软链接文件,则复制软链接本身,而不是复制软链接指向的对象。-z:传输时压缩,提高效率。-R--relative:使用相对路径。意思是将命令行指定的完整路径,包括它们的属性发送到服务器,而不是路径末尾的文件名。有关用法,请参见下面的示例。--size-only:默认算法是检查不同文件大小和mtime的文件,使用这个选项只会检查文件大小。-u--update:仅当源mtime比目标现有文件的mtime更新时才复制。注意这个选项是由接收端决定的,不会影响删除行为。-d--dirs:非递归地复制目录本身。默认递归时,如果source为“dir1/file1”,则不会复制dir1目录。使用此选项将复制dir1而不是file1。--max-size:限制rsync传输的最大文件大小。可以使用单位后缀,也可以是十进制值(例如:“--max-size=1.5m”)--min-size:限制rsync传输的最小文件大小。这可以用来禁止传输小文件或那些垃圾文件。--exclude:指定排除规则,排除不需要传输的文件。--delete:以SRC为主同步DEST。多了就删,少了就补。注意“--delete”是在接收端执行的,所以是在:exclude/include规则生效之后执行的。-b--backup:备份目标上已有的文件,备份文件名默认以“~”为后缀。--backup-dir:指定备份文件的保存路径。如果不指定,默认保存在与要备份的文件相同的目录下。-e:指定要使用的远程shell程序,默认是ssh。--port:连接daemon时使用的端口号,默认为873端口。--password-file:daemon模式下的密码文件,非交互可从中读取密码。注意这里不是远程shell认证的密码,而是rsync模块认证的密码。-W--whole-file:rsync将不再使用增量传输,而是完全传输。当网络带宽高于磁盘带宽时,此选项比增量传输更有效。--existing:要求只更新目标端已经存在的文件,目标端不存在的文件不会被传输。注意,使用相对路径时,如果上级目录不存在,则不会进行转移。--ignore-existing:要求只更新目标端不存在的文件。结合“--existing”有特殊的功能,见下面的例子。--remove-source-files:请求从源中删除已成功传输的文件。1.在本地文件系统上同步rsync[OPTION...]SRC...[DEST]2。本地主机使用远程shell与远程主机通信Pull:rsync[OPTION...][USER@]HOST:SRC。..[DEST]Push:rsync[OPTION...]SRC...[USER@]HOST:DEST3。本地主机通过网络套接字连接到远程主机上的rsync守护进程Pull:rsync[OPTION...][USER@]HOST::SRC...[DEST]rsync[OPTION...]rsync://[USER@]HOST[:PORT]/SRC...[DEST]推送:rsync[OPTION...]SRC...[USER@]HOST::DESTrsync[OPTION...]SRC...rsync://[USER@]HOST[:PORT]/DEST前两者的本质是通过管道进行通信,甚至是远程shell。方法(3)是让rsync服务运行在远程主机上,让它监听一个端口,等待客户端的连接。路径的格式可以是本地路径或使用user@host:path或user@host::path的远程路径。如果主机和路径由一个冒号分隔,则表示使用远程shell通信方式。用双冒号分隔的表示连接到rsync守护程序。此外,在连接rsync守护进程时,它还提供了URL格式的路径表达式rsync://user@host/path。4.远程shell临时启动一个rsync守护进程rsync[options]--rsh=sshauth_user@host::modulersync[options]--rsh="ssh-lssh_user"auth_user@host::modulersync[options]-e"ssh-lssh_user"auth_user@host::modulersync[options]-e"ssh-lssh_user"rsync://auth_user@host/module这与方法(3)不同,它不需要远程主机启动rsync服务提前,但rsync守护进程是临时派生的。它是一个单一用途的一次性守护进程,仅用于临时读取守护进程的配置文件。当rsync同步完成后,远程shell启动的rsync守护进程会自动消失。该通信方式的命令行语法格式与“通过rsync守护进程访问”相同,但选项部分必须指定“--rsh”选项或其简称“-e”。一些使用示例#将/etc/fstab复制到/tmp目录rsync/etc/fstab/tmp#将/etc/cron.d目录复制到/tmprsync-r/etc/cron.d/tmp#设置/等/cron.d目录复制到/tmp下,但需要在/tmp下也生成etc子目录rsync-R-r/etc/cron.d/tmp#复制源路径比较长,但只有一部分目录结构的保留。用一个点表示相对路径的起始位置rsync-R-r/var/./log/anaconda/tmp#备份远程目录下已有的文件,备份后缀为“~”,使用“--suffix”指定后缀rsync-R-r--backup/var/./log/anaconda/tmp#指定备份文件保存路径,默认不会添加备份后缀,使用“--suffix”明确指定后缀rsync-R-r--backup--backup-dir=/tmp/log_back/var/./log/anaconda/tmp#。指定ssh连接参数,如端口、连接用户、ssh选项等rsync-e"ssh-p22-oStrictHostKeyChecking=no"/etc/fstab172.16.10.5:/tmp#使用"--existing"选项只更新目标端已经存在的文件rsync-r-v--existing/tmp/a//tmp/b#"--ignore-existing"更新目标端不存在的文件rsync-r-v--ignore-existing/tmp/a//tmp/b#"--remove-source-files"删除源端文件rsync-r-v--remove-source-files/tmp/a/anaconda/tmp/a/audit/tmp#使用“--exclude”选项指定排除规则,排除不需要传输的文件。rsync-r-v--exclude="anaconda/*.log"/var/log/anaconda/var/log/audit/tmp如果只有一个src或dest参数,则类似于"ls-l"列出源文件列表的方式(只有一个路径参数,它总是被认为是源文件),而不是复制文件。如果源路径是一个目录,则有尾部斜杠和没有尾部斜杠是不同的。不带尾部斜线表示整个目录,包括目录本身,带尾部斜线表示目录中的文件,不包括目录本身。#在/tmp目录下创建etc目录[root@xuexi~]#rsync-a/etc/tmp#不会在/tmp目录下创建etc目录,源码路径/etc/下的所有文件直接放在/tmp目录下[root@xuexi~]#rsync-a/etc//tmp参考酷壳核心算法-RSYNC:https://coolshell.cn/articles...rsync算法:https://rsync.samba.org/tech_...博客园-rsync(一):基本命令及用法:http://www.cnblogs.com/f-ck-n...博客园-manrsync翻译(rsync命令中文手册):http://www.cnblogs.com/f-ck-n...
