Сценарий Perl, который использует inotify для обнаружения изменений в файловой системе и rsync через SSH для повторной синхронизации удаленных копий:
#!/usr/bin/perl
use strict;
use warnings;
use Net::OpenSSH;
use Linux::Inotify2;
use Time::HiRes qw(sleep);
my $usage = "Usage:\n $0 local_dir [user\@]host remote_dir\n\n";
@ARGV == 3 or die $usage;
my ($local, $host, $remote) = @ARGV;
-d $local or die $usage;
my $ssh = Net::OpenSSH->new($host);
$ssh->error and die "unable to connect to remote host: " . $ssh->error;
my $inotify = Linux::Inotify2->new;
$inotify->watch ($local, IN_MODIFY|IN_MOVED_TO);
$ssh->rsync_put({verbose => 1, glob => 1}, "$local/*", $remote);
while (1) {
my @events = $inotify->read or die "read error: $!";
my %changed;
$changed{"$local/$_->{name}"} = 1 for @events;
$ssh->rsync_put({verbose => 1}, keys %changed, $remote);
sleep 0.1;
}
обновление : @ user788171: в ответ на ваш вопрос:
Может быть, а может и нет, слишком много неизвестных:
- сколько файлов действительно изменяется
- их размер
- насколько велики изменения относительно полного размера файла
- пропускная способность сети и задержка
- доступная мощность процессора в обе стороны
- и т.д.
Но попробовать это дешево, поэтому я предлагаю вам сделать это, если этого недостаточно, тогда вы можете попытаться выявить узкие места и попытаться их устранить.
Например, rsync
- это болтливый протокол, очень чувствительный к задержке в сети, поэтому, если ваши файлы небольшие, scp
может дать лучшие результаты. Или вы можете сохранить локальную копию последней версии, переданной локально для каждого файла, и отправить только дельты. Если процессор является узким местом, перепишите его на C ++, исключите SSH и т. Д.
И если в любом случае этот подход окажется тупиковым, тогда вы все равно можете ...
Сделайте это на уровне ОС, используя DRDB или какой-либо другой механизм прозрачной репликации. Вы даже можете попробовать реализовать это самостоятельно, используя FUSE.
Измените ваше основное приложение, чтобы записывать в журнал изменения, которые можно легко передавать на другую сторону.