PaPoo
cover
technews
Author
technews
世界の技術ニュースをリアルタイムでキャッチし、日本語でわかりやすく発信。AI・半導体・スタートアップから規制動向まで、グローバルテックシーンの「今」をお届けします。

openrsyncとは何か:BSDライセンスで作られたrsync実装をやさしく解説

キーポイント

rsyncの「別実装」がある、というのがまず面白い

rsync といえば、ファイル同期の定番ツールです。
「手元のファイルをサーバーに送る」「差分だけ転送する」「バックアップを効率よく取る」など、地味だけど超重要な仕事をずっとこなしてきました。

そんな rsync を、​BSDライセンスでゼロから実装したものopenrsync です。
ここで大事なのは、単なる“rsyncのコピー”ではなく、​別実装だという点です。こういうプロジェクトは、互換性の検証、実装の学習、ライセンス上の選択肢を広げる、という意味でかなり価値があります。個人的には、こういう「よく使う道具を別の思想で作り直す」試みはかなり好きです。中身が見えるからです。

README によると、openrsyncOpenBSD 版がベースで、そこにポータビリティ向けの“glue”が足されているとのこと。しかも現在は OpenBSD base に統合済みで、今後の改善は tech@openbsd.org にパッチを送ってほしい、という案内になっています。
つまり、GitHub 上のこのリポジトリは「生きた実装」ではあるものの、​本流は OpenBSD 側にある、という理解がよさそうです。

ざっくり言うと、何ができるの?

openrsync は、​modern rsync と互換性があると説明されています。
ただし、互換といっても何でも同じではなく、​rsync のコマンドライン引数は一部のみ対応です。

README では、テストに rsync 3.1.3 を使っているが、​protocol 27 をサポートする相手ならよいと書かれています。
このへんは少し玄人向けですが、要するに「古すぎない rsync となら会話できる」という感覚でよさそうです。

また、公式にサポートされる OS は OpenBSD
でも、README によれば 他の UNIX 系でもコンパイル・実行できるとのことです。
この“OpenBSD 主導だけど他でも動く”感じは、OpenBSD 系プロジェクトらしい潔さがあって好感が持てます。

インストールは意外と素朴

README にあるインストール手順はかなりシンプルです。

./configure
make
make install

アンインストールも make uninstall でできます。
こういう「Unix の王道」みたいな作法は、今どきの大規模ビルドシステムに慣れた目には逆に安心感があります。派手さはないけど、道具として信頼しやすい。

しかも、​通常の rsync と共存しても衝突しないと明記されています。
これは地味ですが大事です。実運用では「置き換え」よりも「併存」が多いので、ここが明言されているのはありがたいです。

rsyncの本質は「差分だけ送る」こと

README の一番おもしろい部分は、​rsync のアルゴリズム説明です。
rsync の魅力は、ざっくり言えば「全部送り直さず、必要なところだけ送る」こと。これにより、ネットワーク転送量を抑えられます。

流れをかなり噛み砕くと、こうです。

  1. 送信側がファイル一覧を作る
  2. 受信側とその一覧を共有する
  3. 受信側が既存ファイルをブロック単位で調べる
  4. 受信側がその情報を送信側へ返す
  5. 送信側は、​一致するブロックは再利用し、​一致しない部分だけ新しく送る

この仕組みが、rsync を rsync たらしめる中核です。
ファイルまるごとではなく、​**“ブロック”**という小さな塊で見比べるのがミソです。ブロックとは、ファイルを一定サイズに切った断片のことだと思えばOKです。

openrsync の実装は「役割分担」がはっきりしている

README では、rsync アルゴリズムを次の2つに分けています。

実装上もそれぞれが別ファイルに分かれています。

こういう分業は、読みやすさの面でも意味があります。
同期ツールって一見単純そうに見えるのに、実は「送る側」「受け取る側」「ファイル一覧」「比較」「ハッシュ」「ソケット通信」など、仕事がかなり多いんですよね。なので、責務が分かれているのはかなり健全だと思います。

ファイル一覧を先に共有するのが賢い

rsync の面白さの一つは、​ファイル一覧(file list)を先に共有することです。
この一覧には、名前だけでなく、​mode や mtime などのメタデータも含まれます。

受信側と送信側は、この一覧をもとに、同じ順序でファイルを扱えるようになります。
しかも、一覧は単純な順番ではなく、​辞書順でソートされます。さらに、​ディレクトリが先に処理されるような順序になっているとのことです。
ディレクトリを先に作ってから、その中身を置く。これは当たり前に見えて、実装ではかなり大事です。

個人的には、この「見た目は地味だけど、順序設計が全体を支えている」感じが rsync らしくて好きです。派手なUIがないぶん、アルゴリズムの上品さが前に出ます。

通常ファイルの更新は、ブロックの一致確認から始まる

通常ファイルの流れは、ざっくり次の通りです。

1. まず「更新不要か」を見る

ファイルサイズと最終更新時刻が同じなら、​すでに最新とみなして更新要求をしません。

2. 違うならブロックに分割する

ファイルを一定サイズのブロックに区切ります。
ファイルが端数になれば、最後のブロックは小さくなります。

3. 各ブロックに2種類のハッシュをつける

README では、各ブロックに対して

の2段階を使うと説明されています。

ハッシュとは、データの“指紋”みたいなものです。
同じ内容なら同じ値になり、違う内容なら違う値になりやすい。
まず軽い計算で候補を絞り、最後により厳密な確認をする、という二段構えです。これ、実装としてかなり賢いです。全部を重く検査するより、ずっと効率がいい。

4. 送信側が一致するブロックを探す

送信側はソースファイルを走査し、受信側から届いたブロック情報と照合します。
一致した部分は再送せず、​一致しない差分だけ送る

5. 受信側が再構築する

受信側は、届いた生データと一致ブロックを組み合わせてファイルを復元します。

この仕組みのおかげで、たとえばファイルの一部分だけが変わった場合に、​全体を送り直さなくて済むわけです。
ネットワーク越しの同期で rsync が強い理由は、まさにここにあります。

ディレクトリ、シンボリックリンク、通常ファイルで扱いが違う

README では、ファイル種別ごとに処理が分かれることも説明されています。

シンボリックリンクやディレクトリは、普通のファイルとは性質が違います。
だからこそ、同じロジックに押し込まず、きちんと分けているのは実装として正しいです。こういう細かい気配りが、ツールの“気持ちよさ”につながるんですよね。

ドキュメントが「man page 主体」なのもらしい

README には、openrsync の正式なドキュメントは manual pages だとはっきり書かれています。

つまり、README はあくまで導入で、詳細は man page を見てね、というスタンスです。
これは Unix 文化の王道でもありますし、個人的にはかなり好きです。GitHub の README を万能ドキュメントにしないのは、ある意味で誠実だと思います。

この記事を読んだ上での感想

openrsync の面白さは、単に「rsync の別版」があることではありません。
むしろ、

このあたりが魅力です。

特に、README で「canonical documentation は man page」と言い切っているのが好印象でした。
派手な宣伝より、実務でどう使うか・どう実装されているかを重視している感じがします。
こういうプロジェクトは、表向きは地味でも、技術的にはかなりおいしい。
rsync を“なんとなく便利なコマンド”で終わらせたくない人には、読む価値があると思います。

まとめ

openrsync は、​rsync の仕組みを BSD 系の世界で再実装した、堅実で学びが多いプロジェクトです。
OpenBSD を軸にしつつ、他の UNIX でも動くよう配慮されていて、アルゴリズムの説明も丁寧。
「差分同期って結局どうやってるの?」という疑問に、かなり真面目に答えてくれる実装だと思います。


参考: GitHub - kristapsdz/openrsync: BSD-licensed implementation of rsync

同じ著者の記事