【テクニカル・上級編】 同期プロセス (PSYNC/SYNC) – Redis

Redisレプリケーションの深淵:PSYNCと「オフセット」が織りなす整合性の哲学

Redisのレプリケーションは、一見すると単純なマスタースレーブの複製に見える。だが、大規模分散システムにおいて「完全な整合性」と「可用性」を両立させようとしたとき、`PSYNC`コマンドの内部挙動こそが、エンジニアの腕を試す最大の試金石となる。

今日は、ドキュメントの表面をなぞるような解説はしない。Redisのソースコードとメモリレイアウトの深層から、レプリケーションの真髄を解き明かす。

—

1. 概念の再定義:同期の二面性

Redisのレプリケーションは、以下の二つのフェーズに大別される。

1. Full Resynchronization (フル同期): `RDB`スナップショットの転送と、その転送期間中に発生した書き込みのバッファリング。
2. Partial Resynchronization (部分同期): `repl_backlog`を用いた、欠損分のみの差分再送。

アーキテクトが意識すべきは、「どちらが走るか」ではなく、「なぜフル同期が走ってしまうのか」というコストの理解にある。

2. Replication Backlog:メモリ上の「時系列ログ」

部分同期の要は、マスター側に存在する `repl_backlog` という循環バッファだ。これは単なるバッファではない。各ノードが共有する「オフセット(replication offset)」を管理するための、インメモリの時系列ストリームである。

なぜこれが重要なのか?

スレーブが切断された際、マスターは `repl_backlog` を参照する。

  • スレーブが要求したオフセットが、現在のバッファ内に存在する場合 → PSYNC (部分同期)。
  • バッファから溢れている場合 → FULLRESYNC (フル同期)。

この「バッファ溢れ」は、大規模トラフィック環境では非常に深刻なパフォーマンス劣化を引き起こす。`repl-backlog-size` を適当に設定しているエンジニアは、障害発生時にフル同期が連鎖的に走り、マスターのメモリを圧迫し、さらなるレイテンシの増大を招くという「負の連鎖」を理解していない。

—

3. PSYNCの内部メカニズム:オフセットの追跡

`PSYNC ` コマンドが投げられた瞬間、Redis内部では何が起きているのか。

1. RunIDの検証: まずはマスターのIDが一致するかを確認する。IDが変わっていれば、それは別個体であるため即座にフル同期へ。
2. オフセットの比較:

  • マスターの現在の `master_repl_offset` と比較する。
  • `backlog` の開始オフセットよりも古い位置を要求された場合、`backlog` が更新されているため差分を送れない。

/ Redis内部実装の概念コード /
if (psync_offset > server.master_repl_offset ||
psync_offset < server.master_repl_offset - server.repl_backlog_histlen) { /

  • バッファが古すぎる、または未来のオフセットを要求された。
  • ここで FULLRESYNC がトリガーされる。

/
return send_full_resync();
}

この「オフセット」という概念は、Redisが分散データベースとしていかに緻密に設計されているかを示す証左だ。RDBファイルという「重い塊」を転送する前段階で、いかに「軽量なバイト列の補完」で済ませるか。この判断こそが、高負荷環境でのレプリケーション安定性を左右する。

—

4. アーキテクトのための運用指針

現場でレプリケーション戦略を立てる際、以下の「限界突破の視点」を忘れてはならない。

① `repl-backlog-size` の最適化

計算式はシンプルだ。
`backlog_size = (マスターの書き込み負荷/秒) (平均再接続時間)`
この数値を下回る設定は、回線瞬断で即フル同期を誘発する。メモリを惜しんでネットワーク帯域とCPUをドブに捨てるような設定は今すぐ見直せ。

② `repl-diskless-sync` の検討

物理ディスクI/Oを介さず、メモリ上のRDBデータをソケットへ直接ストリームする「ディスクレス同期」は、特に低速なストレージを使用している環境で劇的な効果を発揮する。ただし、ネットワーク帯域がボトルネックになるリスクとのトレードオフを計算しておくこと。

③ 監視の徹底

`INFO replication` を叩いた際に出力される `master_repl_offset` と `slave_repl_offset` の乖離を監視せよ。この差分が拡大し続けているなら、スレーブの処理能力が追いついていないか、ネットワークのTCPバッファが詰まっているサインだ。

—

結論:Redisは「状態」を扱うエンジンである

Redisのレプリケーションは、ただデータをコピーする作業ではない。「時系列上のどこにいるか」というオフセット管理の極致である。

多くのエンジニアが「Redisは速い」と言う。しかし、その速さを支えているのは、キャッシュとしてのメモリ管理だけではない。レプリケーションという非同期プロセスにおいても、極限まで無駄を削ぎ落としたオフセットベースの同期アルゴリズムがあるからこそ、我々は数テラバイトのRedisクラスタを運用できているのだ。

次回の運用では、ぜひ `INFO` コマンドからオフセットの推移を眺めてみてほしい。そこには、Redisの設計者が込めた「整合性への執念」が見えるはずだ。

それが、エンジニアとしての視座を一段引き上げる鍵になる。

コメント

タイトルとURLをコピーしました