rsync与仍在写入的文件的行为?


12

如果Apache正在编写一个大文件,并且rsync cron作业在该文件上运行,rsync是否会尝试复制该文件?

  • Apache-1:具有写入的大文件/var/www
  • Apache-2:Apache-1的克隆。cron每隔五分钟运行rsync来获取/var/www的同步。

Answers:


20

如果Apache正在将某种文件写入一个地方并且尚未完成写入然后又 rsync插入,rsync则将复制那里的任何内容。

这意味着如果Apache处理的是5MB的文件,则仅写入rsync2MB并将其插入,将复制部分2MB的文件。因此,该文件似乎在目标服务器上已“损坏”。

根据所使用文件的大小,可以使用中的--inplace选项rsync执行以下操作:

此选项更改了当需要更新文件数据时rsync传输文件的方式:不是默认的创建文件新副本并将其复制到位的默认方法,而是将更新后的数据直接写到目标位置文件。

这样的好处是,如果一个5MB的文件在第一次运行时仅复制了2MB,则下一次运行将以2MB的速度启动,并继续复制该文件,直到完整的5MB。

不利的是,这可能会导致有人在复制文件的同时访问Web服务器,然后他们会看到部分文件。在我看来,rsync最好的做法是缓存“不可见”文件,然后立即将其移到适当位置,这是默认行为。但是--inplace,对于大型文件和带宽限制可能会妨碍从方形文件轻松复制大型文件的情况而言,这是一个好选择。

那就是说你要声明这一点;重点是我的:

cron 每隔五分钟运行rsync…

所以我假设您有一些bash脚本来管理此cron作业?好吧,它rsync足够聪明,只复制需要复制的文件。而且,如果您有一个每5分钟运行一次的脚本,那么它似乎会试图避免rsync彼此之间的步伐加快(如果运行得更快)。这意味着,如果您每分钟运行一次,则可能存在一个或多个rsync进程由于文件大小或网络速度而仍在运行的风险,而下一个进程将与其竞争。赛车状况。

避免这种情况的一种方法是将整个rsync命令包装在bash脚本中,该脚本检查文件锁定。以下是我用于此类情况的样板bash脚本框架。

请注意,有些人会建议使用,flock但由于flock我没有在某些系统上安装它,并且我在Ubuntu(有它)和Mac OS X(没有很多)之间跳转,所以我使用这个简单的框架没有任何实际问题:

LOCK_NAME="MY_GREAT_BASH_SCRIPT"
LOCK_DIR='/tmp/'${LOCK_NAME}.lock
PID_FILE=${LOCK_DIR}'/'${LOCK_NAME}'.pid'

if mkdir ${LOCK_DIR} 2>/dev/null; then
  # If the ${LOCK_DIR} doesn't exist, then start working & store the ${PID_FILE}
  echo $$ > ${PID_FILE}

  echo "Hello world!"

  rm -rf ${LOCK_DIR}
  exit
else
  if [ -f ${PID_FILE} ] && kill -0 $(cat ${PID_FILE}) 2>/dev/null; then
    # Confirm that the process file exists & a process
    # with that PID is truly running.
    echo "Running [PID "$(cat ${PID_FILE})"]" >&2
    exit
  else
    # If the process is not running, yet there is a PID file--like in the case
    # of a crash or sudden reboot--then get rid of the ${LOCK_DIR}
    rm -rf ${LOCK_DIR}
    exit
  fi
fi

我的想法是,通用核心(我所拥有echo "Hello world!"的)是脚本的核心所在。其余的基本上是基于的锁定机制/逻辑mkdir这个答案很好地解释了这个问题

如果mkdir不存在,它会创建一个目录,如果存在,它将设置退出代码。更重要的是,它可以通过单个原子动作完成所有这些操作,因此非常适合这种情况。

因此,就您的rsync过程而言,我建议仅通过将echo命令更改为您的命令来使用此脚本rsync。另外,将其更改LOCK_NAME为类似的内容RSYNC_PROCESS,然后就可以使用了。

现在,将您的rsync脚本包裹起来,您可以将cron作业设置为每分钟运行,而不会出现两个或多个rsync进程在争做同一件事的竞争状况。这将允许您提高速度或rsync更新,这不会消除部分文件被传输的问题,但是将有助于加快整个过程,以便可以在某个时候正确复制整个文件。


1
感谢您指出运行多个rsync的可能性,没想到。脚本听起来很棒。我只是想了解将负载平衡的站点与rsync同步的陷阱,这似乎可以缓解它们。精彩的奖金。仍然感觉这也许是错误的方法……但让我们看看:)
Louis Waweru 2014年

@Louis不客气!另外,如果您想根据文件的即时更改使文件夹保持同步,强烈建议您使用/ adapting lsyncd。它允许您拥有“热文件夹”,该文件夹真正关注其中的活动,然后在进行更改时对这些文件进行操作。我使用rsync了我的答案中概述的很多内容,但lsyncd在需要非Cron /更立即采取行动的情况下,我使用了很多内容。
JakeGould 2014年

3

是的-如果rsync在写入文件的同时读取文件,则文件可能已损坏。

您可以尝试以下方法:https : //unix.stackexchange.com/a/2558

您也可以使用lsof编写脚本:

lsof /path/to file

退出代码0表示文件正在使用中,退出代码1表示该文件上没有任何活动。


我不明白如果rsync只是读取文件,为什么文件会损坏
orestisf
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.