一般化する

一般化する

私はこれを見たことがある質問そしてこの問題しかし、私が見ている症状を解決できないようです。

セルラーネットワーク経由で転送したい大容量ログファイル(約600 MB)があります。ログファイルなので、ただ追加されます。 (実際にはINSERTのみを実行するSQLiteデータベースにあるため、そうではありません。かなりそれは簡単ですが、最後の4kページ(または数ページ)を除いて、ファイルは毎回同じです。重要なのは、データ接続が測定されるため、変更(および送信する必要があるすべてのチェックサム)のみが実際に送信されることです。

ただし、無制限の接続(フリーWi-Fiホットスポットなど)を介してテストを実行した場合、データ転送速度の向上または減少は観察または報告されませんでした。遅いWiFi接続により、伝送速度が約1MB/s以下であることが確認され、伝送にほぼ20分かかるという報告がありました。高速WiFi接続を介して均一に高速化しましたが、加速が報告されておらず、2回目の転送試行(2つのファイルが同じであるため、早くする必要があります)では、違いはありません。

私が使用するコマンド(機密情報を削除するために削除されます)は次のとおりです。

rsync 'ssh -p 9999' --progress LogFile [email protected]:/home/michael/logs/LogFile

私が最終的に得た結果は次のとおりです。

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

いかなる種類の加速度への言及はありません。

問題は次のいずれかであると考えられます。

  • いくつかのコマンドラインオプションがありません。ただし、マニュアルページをもう一度読むと、増分転送がデフォルトで有効になっていることがわかります。無効にするオプションのみが表示されます。
  • サーバーがsshのみを許可するファイアウォールの背後にあるため、sshを介してrsyncを使用しています(非標準ポートでも)。しかし、rsyncデーモンが実行されていないと、増分転送が機能しないことを明示的に言及したことは見たことがありません。 ":"の代わりに "::"シンボルを試してみましたが、マニュアルページでは "モジュール"が何であるかわからず、間違ったモジュールを指定したため、私のコマンドは拒否されました。

次のシナリオは除外しました。

  • 増分転送はローカルネットワークでは行われません。インターネット経由で転送しようとしているので除外されました。
  • チェックサム計算によるオーバーヘッド。高速Wi-Fi接続と遅いWi-Fi接続の両方でこの動作を見たことがあり、転送速度は計算上制限されないようです。

答え1

一般化する

データベースは多くのメタデータ、組織データなどを保持する傾向があります。挿入はテキストファイルと同様に単純な追加ではない可能性があります。 SQLiteテストは、WALモードと非WALモードの両方でこの動作を示しています。これにより、rsyncは予想よりも多くのデータを同期する必要があります。低い値を使用すると、このオーバーヘッドを少し減らすことができます--block-size(チェックサムを計算して送信するためのより多くのオーバーヘッドが発生します)。

より良いアプローチは、新しいレコードをSQLダンプにダンプして圧縮して送信することです。または、複数のSQLiteレプリケーションソリューションがあるようで、そのうちの1つを使用できます。

ロエマgzip --rsyncable少なくとも完全なSQLダンプを実行し、圧縮を使用してからrsyncを使用することをお勧めします。増分が十分小さいかどうかテストしてみる価値があると思います。

詳細

あなたは何をしていますか?しなければならない働く個人的--partialに増加するファイルを部分転送として検出する場合に備えて、rsyncオプションを追加します。これにより、より良い転送統計が得られます--stats

2番目にチェックする必要があるのは、SQLiteが実際に数ページしか触れていないかどうかです。正直なところ、ファイル全体にページを書くことは驚かないでしょう。確認する簡単な方法は、両方のバージョンで作業することですcmp -l。最後の数ページを除いて、変更されたページがあることを確認してください。rsync「ページ」/チャンクの概念がSQLiteの概念と異なることに注意してください。 rsyncを介してこれを変更できます--block-size。減らすのに役立ちます。

編集する:SQLiteを使用してクイックテストを実行しました。 32,000ページでも、曲がったログエントリをたくさん追加してくださいすべてページ。詳細は次のとおりです。

編集2:まだ多くのオーバーヘッドが必要ですが(おそらくチェックポイントのため)、WALモードが優れているようです。

編集3:転送ごとにデータを追加するほど、優れています。特定の塊を混ぜ続けることができると思います。したがって、1回でも何度でも、同じチャンクを送信します。

ちなみに:転送を最小限に抑えるには、rsyncよりも優れた結果を得ることができます。たとえば、最後の転送の実行以降、新しいレコードのSQLダンプxz --best(さらにはgzip)は小さくなります。

高速SQLiteテスト

建築学:

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);

パールプログラム:

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 ([email protected]) (gcc version 5.3.1 20160528 (Debian 5.3.1-21) ) #1 SMP Debian 4.5.5-1 (2016-05-29)

より多くのサンプルログメッセージがあります(2076)。

どのページが変更されたかを確認してください。

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) }'

関連情報