Neden rsync ağdaki tek bir dosya için delta aktarımlarını kullanmıyor?


15

Bu soruya ve bu soruya baktım , ancak gördüğüm belirtileri ele almıyorlar.

Bir hücresel ağ üzerinden aktarmaya çalışıyorum büyük bir günlük dosyası (yaklaşık 600 MB) var. O sadece eklenmiş bir günlük dosyası olduğu için sadece INSERT ile SQLite veritabanında aslında olmasına rağmen (Öyle olmadığını, gerçekleştirildiği oldukça bu kadar basit olarak, ama en son 4k sayfa haricinde (ya da belki bir Dosya bağlantısı her zaman ölçüldüğünden, sadece değişikliklerin (ve sağlama toplamlarının iletilmesi gereken) gerçekte gönderilmesi önemlidir.

Yine de ölçülmemiş bir bağlantıda (örn. Ücretsiz wifi hotspot) bir test yaptığımda gözlemlenen veya bildirilen bir hızlanma veya azaltılmış veri aktarımı görmüyorum. Yavaş bir WiFi bağlantısı üzerinden, aktarımın yaklaşık 20 dakika süreceğini bildiren 1MB / s veya daha az sırada görüyorum. Hızlı bir WiFi bağlantısı üzerinden tekdüze daha hızlı bir hız görüyorum, ancak hızlanma raporu yok ve ikinci bir aktarma denemesi (şimdi iki dosya aynı olduğu için daha hızlı olmalı) artık herhangi bir fark gösteriyor.

Kullanıyorum (hassas bilgileri kaldırmak için dezenfekte) komutu:

rsync 'ssh -p 9999' --progress LogFile michael@my.host.zzz:/home/michael/logs/LogFile

Sonunda aldığım çıktı şöyle görünür:

LogFile
    640,856,064 100%   21.25MB/s   0:00:28 (xfr$1, to-chk=0/1)

Herhangi bir hızlanma söz konusu değildir.

Sorunun aşağıdakilerden biri olabileceğinden şüpheleniyorum:

  • Bazı komut satırı seçeneği eksik. Ancak, man sayfasını yeniden okumak, delta aktarımlarının varsayılan olarak etkin olduğunu gösteriyor: Yalnızca bunları devre dışı bırakma seçeneklerini görüyorum.
  • Sunucu sadece ssh izin veren bir güvenlik duvarının arkasında olması nedeniyle ss (standart olmayan bir bağlantı noktasında bile) üzerinden rsync kullanıyorum. Yine de rsync arka plan programı çalışmıyorsa delta transferlerinin çalışmadığını söyleyen bir şey görmedim. Ben ":" yerine "::" gösterimini kullanmayı denedim ama man sayfası bir "modül" ne olduğu hakkında çok net değil ve benim komut geçersiz bir modül belirttiği için reddedildi.

Aşağıdakileri dışladım:

  • yerel ağda yapılmayan delta aktarımı. İnternetten transfer gerçekleştirmeye çalıştığım için reddedildi
  • sağlama toplamı hesabı nedeniyle ek yük. Bu davranışı hem hızlı hem de yavaş bir Wifi bağlantısında gördüm ve aktarım hızı hesaplama işlemine bağlı görünmüyor.

1
but with the exception of the last 4k page (or maybe a few) the file is identical each time. Bunu gerçekten ile doğruladınız cmpmı? Ya da daha iyisi, xdeltaya da bir şey? Aktarım boyutunu gerçekten küçültmek istiyorsanız, eski ve yeni sürümleri yerel olarak saklayın, böylece yerel olarak (rsync dışında bir şeyle) en az ikili bir ikili fark hesaplayabilir ve ölçülü bağlantı üzerinden sağlama toplamı göndermek zorunda kalmadan gönderebilirsiniz. Bunu derobert'in önerdiği gibi ikili dosya seviyesi yerine veritabanı kaydı düzeyinde yapmak daha da iyidir.
Peter Cordes

1
Ayrıca, daha da ayrıntılı istatistikler elde etmek için rsync --statsde -v -vkullanabilirsiniz. Rsync size ne kadar eşleşen ve eşleşmeyen verilerin olduğunu söyleyecektir.
Peter Cordes

Yanıtlar:


27

özet

Veritabanları çok fazla meta veri, organizasyon verileri vb. Tutma eğilimindedir. SQLite testi, hem WAL hem de WAL olmayan modlarda bu şekilde davrandığını gösterir. Bu, rsync'in beklediğinizden çok daha fazla veri senkronize etmesine neden olur. Bu ek yükü, düşük --block-size(daha fazla ek bilgi işlem ve sağlama toplamlarını aktarma pahasına) kullanarak bir miktar azaltabilirsiniz .

Daha iyi bir yaklaşım muhtemelen yeni kayıtları bir SQL dökümü olarak dökmek, sıkıştırmak ve aktarmaktır. Alternatif olarak, SQLite için birkaç çoğaltma çözümü var gibi görünüyor, bunlardan birini kullanabilirsiniz.

roaima , en azından tam bir SQL dökümü yapabileceğinizi, kullanarak sıkıştırabileceğinizi gzip --rsyncableve daha sonra bunu rsync yapabileceğinizi gösterir. Sanırım bir teste değer, bunun yeterince küçük bir delta olup olmadığını görmek için.

ayrıntılar

Ne çalışıyoruz gerektiğini çalışır. --partialBüyüyen dosyayı bir şekilde kısmi aktarım olarak algılaması durumunda, rsync seçeneklerinize kişisel olarak ekleyeceğim . İle daha iyi transfer istatistikleri de alabilirsiniz --stats.

Kontrol edilmesi gereken ikinci şey, SQLite'nin gerçekten sadece birkaç sayfaya dokunuyorsa - dürüst olmak gerekirse, dosyanın her tarafına sayfa yazması durumunda şaşırmam. Kontrol etmenin hızlı bir yolu cmp -l, iki sürümde kullanmak olacaktır - son birkaç sayfadan başka sayfalarda değişiklik olup olmadığına bakın. Unutmayın ki rsyncbir "sayfa" / blok fikri SQLite'den farklıdır; rsync'i değiştirebilirsiniz --block-size. Bunu azaltmak yardımcı olabilir.

Düzenleme: SQLite ile hızlı bir test yaptım. 32k sayfalarla bile, her sayfaya karalanmış bir grup günlük girişi ekler . Detaylar aşağıda.

Düzenleme 2 : WAL modunda daha iyi görünüyor, ancak yine de muhtemelen kontrol noktasından büyük miktarda ek yük alıyorsunuz.

Edit 3 : Aktarım başına ne kadar fazla veri eklerseniz o kadar iyidir - sanırım muhtemelen bazı blokları tekrar tekrar karalamalar. Böylece, aynı blok kümesini, bir veya yüz kez yazılmasına bakılmaksızın aktarıyorsunuz.

BTW: Aktarımı en aza indirmek için muhtemelen rsync'den çok daha iyisini yapabilirsiniz. Örneğin, son aktarımın xz --best(hatta çiftin gzip) çalıştırılmasından bu yana yeni kayıtların bir SQL dökümü muhtemelen biraz daha küçük olacaktır.

Hızlı SQLite Testi

Şema:

CREATE TABLE log (id integer primary key not null, ts integer not null, app text not null, message text not null);
CREATE INDEX log_ts_idx on log(ts);
CREATE INDEX log_app_idx on log(app);

Perl programı:

use 5.022;
use DBI;

my $DBH = DBI->connect('dbi:SQLite:test.db', '', '', {RaiseError => 1, AutoCommit => 0})
    or die "connect...";

my @apps = (
    '[kthreadd]',        '[ksoftirqd/0]',
     # there were 191 of these
    '[kworker/5:0H]',
);

my @messages = <DATA>;

(my $curr_time) = $DBH->selectrow_array(<<QUERY);
    SELECT COALESCE(MAX(ts),978307200) FROM log
QUERY

my $n_apps = @apps;
my $n_msgs = @messages;
say "Apps: $n_apps";
say "Messages: $n_msgs";
say 'Start time: ', scalar gmtime($curr_time), ' UTC';

my $sth = $DBH->prepare(<<QUERY);
    INSERT INTO log(ts, app, message) VALUES (?, ?, ?)
QUERY

for (my $i = 0; $i < 10_000; ++$i) {
    $sth->execute(int($curr_time), $apps[int rand $n_apps], $messages[int rand $n_msgs]);
    $curr_time += rand 0.1;
}
$DBH->commit;

__DATA__
microcode: CPU0 microcode updated early to revision 0x19, date = 2013-06-21
Linux version 4.5.0-2-amd64 (debian-kernel@lists.debian.org) (gcc version 5.3.1 20160528 (Debian 5.3.1-21) ) #1 SMP Debian 4.5.5-1 (2016-05-29)

Çok daha fazla örnek günlük mesajı vardı (2076).

Hangi sayfaların değiştiğini kontrol etme:

cp test.db test.db.old
perl test.pl
cmp -l test.db.old test.db | perl -n -E '/^\s*(\d+) / or die "wtf"; $bucket{int $1/32768} = 1; END { say join "\n", sort( { $a <=> $b } keys %bucket) }'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.