I am using inotify to watch a directory and sync files between servers using rsync. Syncing works perfectly, and memory usage is mostly not an issue. However, recently a large number of files were added (350k) and this has impacted performance, specifically on CPU. Now when rsync runs, CPU usage spikes to 90%/100% and rsync takes long to complete, there are 650k files being watched/synced.
Is there any way to speed up rsync and only rsync the directory that has been changed? Or alternatively to set up multiple inotifywaits on separate directories. Script being used is below.
UPDATE: I have added the --update flag and usage seems mostly unchanged
#! /bin/bash
EVENTS="CREATE,DELETE,MODIFY,MOVED_FROM,MOVED_TO"
inotifywait -e "$EVENTS" -m -r --format '%:e %f' /var/www/ --exclude '/var/www/.*cache.*' | (
WAITING="";
while true; do
LINE="";
read -t 1 LINE;
if test -z "$LINE"; then
if test ! -z "$WAITING"; then
echo "CHANGE";
WAITING="";
rsync --update -alvzr --exclude '*cache*' --exclude '*.git*' /var/www/* root@secondwebserver:/var/www/
fi;
else
WAITING=1;
fi;
done)
inotify
piece by itself, w/o thersync
does the poor performance continue, or are you positive the root cause isrsync
?top
that's what causes the increase in CPU, running as a system process.rsync
every time a single file has been changed. If/when your inotifywait returns multiple lines, the wholersync
will be run equally many times. You either need to collect list of modified files and sync that list as soon as possible (basically start sync on first modified file and start collecting list of new files in paraller with the sync, re-sync with the new list after the first sync is ready and start collecting another list for the time sync is going). Or just rununison
instead.MODIFY
event, since it will be generated A LOT when a large file is being downloaded/created. Also, if you act/sync onMODIFY
event, without waiting forCLOSE_WRITE
event, you might sync an incomplete file. In essence, you only need to trigger sync on these events:CLOSE_WRITE, MOVED_TO, MOVED_FROM, DELETE
.