Answers:
如果Apache正在将某种文件写入一个地方并且尚未完成写入然后又 rsync
插入,rsync
则将复制那里的任何内容。
这意味着如果Apache处理的是5MB的文件,则仅写入rsync
2MB并将其插入,将复制部分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
更新,这不会消除部分文件被传输的问题,但是将有助于加快整个过程,以便可以在某个时候正确复制整个文件。
lsyncd
。它允许您拥有“热文件夹”,该文件夹真正关注其中的活动,然后在进行更改时对这些文件进行操作。我使用rsync
了我的答案中概述的很多内容,但lsyncd
在需要非Cron /更立即采取行动的情况下,我使用了很多内容。
是的-如果rsync在写入文件的同时读取文件,则文件可能已损坏。
您可以尝试以下方法:https : //unix.stackexchange.com/a/2558
您也可以使用lsof编写脚本:
lsof /path/to file
退出代码0表示文件正在使用中,退出代码1表示该文件上没有任何活动。