陈日志 发布的文章

前面的文章中,我介绍到 rsync + inotify 可以实现文件实时同步功能,rsync + inotify 有优点,也有一些弊端。

  • 需要编写脚本调用 inotifywait来实现,所有的逻辑控制都要编写脚本来实现,使用门槛高
  • 单线程同步,效率低
  • 使用 vi 编辑文件时,将会触发非常多的冗余事件
  • 删除目录时,会同时产生删除文件夹里的文件的事件,这些都是冗余事件
  • 使用脚本也是其优点,使得运维人员可以轻易地编写出满足条件的同步逻辑
  • 可以灵活控制同步选项

sersync 介绍

sersync 是由金山所开源的一款基于 rsync + inotify 的实现,它使用 C++ 语言进行编写,提供了比原生 rsync + inotify 更为强大的功能。

  • 过滤临时文件和不需要的事件,比如在write的时候只产生一个事件,这样就之需要rsync一次
  • 删除文件夹的时候,inotify就会同事产生删除文件夹里的文件与删除文件夹的事件,通过过滤队列,当删除文件夹时间产生的时候,会将之前加入队列的删除文件的事件全部过滤掉,这样只产生一条删除文件夹事件
  • 当rsync失败的时候,会进行稍后重新执行,如果仍旧失败,10小时候再次执行,确保服务器同步准确
  • 对于本地没有的文件,我也会对远程文件路径进行删除,同时不会比较其他文件,那些使用 rsync --include=/ --include=xxx.php$ --exclude= 的用户注意了,那种执行方式,效率很低,会递归比较所有目录
  • 支持主机到多个分机的同步,别且使用多线程同时执行,使文件在所有服务器上保持一致。并且同时同步inotiy产生的多个文件
  • 自带crontab功能,只需在xml配置文件中开启,即可按您的要求,隔一段时间整体同步一次。无需再额外配置crontab功能
  • 多线程同步
  • 支持socket与http扩展插件

rsync.png

- 阅读剩余部分 -

此前的文章中,我介绍了 rsync 的工作原理及使用。而在此前的使用中,我是通过命令行的方式执行 rsync 客户端命令来同步数据的,在实际的应用中,更多的是配置定时任务,定时的执行客户端命令去同步数据。

一般而言,rsync 客户端命令大致都是这样:

rsync -avrz /data remote_host::data

意思是把本地 /data 目录推送到远端 rsync 服务的 data 模块对应的 path 目录中。然后,把这条命令添加到定时任务中去,就达到了定时同步的目的了。

虽然这样能实现我们的需求,但是当 /data 目录下有几千、几万、几十万甚至更多文件时,rsync 会遍历 /data 的所有文件,每一个文件都要计算摘要和校验和。这绝对是灾难性的,会损耗服务器的大量资源来处理同步的事情。

那么,我们就想,有没有一种机制,能实现当文件发生改变时才触发同步到远端服务器呢?答案是有的,它就是 inotify。

- 阅读剩余部分 -

前面我们介绍过 rsync 有三种常用的使用方式,其中之一是 rsync 作为守护进程启动时,其默认监听在 873 端口,接收 rsync 客户端的请求。

在这种模式下,我们需要给 rsync 守护进程提供一个配置文件,告诉 rsync 提供哪些目录访问,允许哪些 IP 访问等。

Rsync 配置文件格式

rsync 配置文件由全局参数和一个或多个模块组成,全局参数写在文件头部,模块的定义则是由中括号开始,下方定义模块参数。

模块参数也可以定义在全局参数中,这表示给模块参数提供默认值。

配置示例

uid = nobody
gid = nobody
use chroot = yes
max connections = 4
syslog facility = local5
pid file = /var/run/rsyncd.pid

[ftp]
    path = /var/ftp/pub
    comment = whole ftp area

[www]
    path = /var/www
    comment = web file

- 阅读剩余部分 -

rsync 客户端基本用法

rsync 提供三种使用模式,本地、ssh、rsync daemon

本地

rsync [OPTION...] SRC... [DEST]

ssh

拉:

rsync [OPTION...] [USER@]HOST::SRC... [DEST]

推:

rsync [OPTION...] SRC... [USER@]HOST:DEST

rsync daemon

推:

rsync [OPTION...] [USER@]HOST::SRC... [DEST]
rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]

拉:

rsync [OPTION...] SRC... [USER@]HOST::DEST
rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST

仅使用一个SRC参数且没有DEST参数的用法时,将列出源文件而不是复制。

- 阅读剩余部分 -

Rsync(remote synchronize)是一个远程数据同步工具,它可以将一个目录的文件快速地同步到另一个目录,还可以通过网络快速同步多台主机间的文件。rsync 使用所谓的“rsync算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快。

Rsync 工作模式

一般而言,rsync 是 C/S 模型的一个软件,它既是客户端程序也是服务端程序。也就是说 rsync 需要启动一个守护进程(daemon)来接收客户端的请求,默认监听在 TCP 873 端口。

rsync 也支持独立使用以及配合 SSH 通道来传输数据,下面会有几种用法的详细说明。

Rsync 适用场景

  • rsync 在同步文件时需要非常频繁的计算文件的校验码,因此 rsync 会占用一定的 CPU 资源。

    如果不希望 Rsync 进行增量文件传输,则使用 --whole-file 参数显式指定为全量传输。

  • rsync 不适合对数据库文件进行实时同步

    像数据库文件这样的大文件,且是频繁访问的文件,如果使用rsync实时同步,发送端要计算、比较的数据块校验码非常多,cpu会长期居高不下,从而影响数据库提供服务的性能。另一方面,接收端每次都要从巨大的basis file(一般提供服务的数据库文件至少都几十G)中复制大部分相同的数据块重组新文件,这几乎相当于直接 cp了一个文件,它一定无法扛住巨大的io压力,再好的机器也扛不住。

    所以,对频繁改变的单个大文件只适合用rsync偶尔同步一次,也就是备份的功能,它不适合实时同步。像数据库文件,要实时同步应该使用数据库自带的replication功能。

  • 可以使用 rsync 对大量小文件进行实时同步
  • 由于rsync 是增量同步,所以对于接收端已经存在的和发送端相同的文件,发送端是不会发送的,这样就使得发送端和接收端都只需要处理少量的文件,由于文件小,所以无论是发送端的 CPU 还是接收端的 IO 都不是问题。

    但是,rsync 的实时同步功能是借助工具来实现的,如 inotify+rsync,sersync,所以这些工具要设置合理,否则实时同步一样效率低下,不过这不是 rsync 导致的效率低,而是这些工具配置的问题。

- 阅读剩余部分 -