4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Proxmoxクラスタ同期メカニズム深掘り 〜Corosyncとpmxcfsの内部構造〜

4
Last updated at Posted at 2025-12-02

はじめに

割と素人寄りの人が調べて書いてるので、正しくない情報もあるかもですm(__)m

前回の記事では、Proxmoxクラスタを支える「クォーラム(多数決)」や、Corosyncの厳格なタイムアウト設定について解説しました。「ノードが死んだと判断される仕組み」や「フェンシングが発動するまでの時間」といった、クラスタの外側から見た挙動の話でしたね。

今回は、その続編として、Proxmoxクラスタの内側に踏み込みます。

Proxmox VE のクラスタ機能は非常に強力ですが、その中身が具体的にどう動いているのか、ブラックボックスに感じている方も多いのではないでしょうか。

今回もっと勉強する機会があったので、この記事ではProxmoxの心臓部である Corosyncpmxcfs の内部実装に踏み込み、データがどのように同期され、整合性が保たれているのかを解説します。特に、ソースコード(totem, cpg, pmxcfs)のロジックに基づき、「いつ、どこで、何が」起きているのかを明らかにします。

1. アーキテクチャ概観:2つの主要コンポーネント

Proxmoxクラスタの動作は、大きく2つのレイヤーの協調によって成り立っています。

corosync1.png

Corosync (Totemプロトコル)

役割: クラスタメンバーシップの管理、メッセージの順序保証

機能: 全ノードが同じ順番でメッセージを受け取る「仮想同期 (Virtual Synchrony)」を提供します。前回の記事で解説したトークン・パッシングの仕組みにより、クラスタ全体で一貫した順序でのメッセージ配信を実現しています。

pmxcfs (Proxmox Cluster File System)

役割: 設定ファイル (/etc/pve) の実体を管理する分散ファイルシステム

実体: 各ノードのメモリ上で動作する SQLiteデータベース です。FUSEを使ってファイルシステムに見せかけています。

2. Corosync/Totemプロトコルの詳細

Corosyncの核心は Totem シングルリングプロトコル です。これは、物理的な配線に関わらず、論理的な「リング」を構成し、トークンを巡回させることで通信を制御します。

2.1 トークン・パッシング (Token Passing)

前回の記事でも触れましたが、リング上を 「トークン (Token)」 という特殊なパケットが高速で巡回しています。

corosync2.png

送信権の独占

トークンを持っているノードだけが、メッセージ(マルチキャスト)を送信できます。これにより、同時に複数のノードが書き込んでデータが競合することを防ぎます(シリアライズ)。

ARU (All Received Up to)

トークンには aru というシーケンス番号が含まれています。これは「リング内の全員が、ここまで受信しました」という確認印です。

トークンが一周して戻ってきた時、この aru が更新されていることで、送信者は「全員に届いた」と確信できます。

2.2 通信フロー(ソースコードレベル)

exec/totemsrp.c の実装に基づくと、トークン受信時の処理は以下のようになります。

  1. トークン受信: 前のノードからトークンを受け取る
  2. 再送制御: 自分が取りこぼしたメッセージがあれば、再送要求 (Retransmit Request) を出す
  3. マルチキャスト送信: 送信待ちキューにあるメッセージ(pmxcfsからのデータなど)をネットワークに送出する
  4. トークン更新: 送信した分だけシーケンス番号を進め、トークンを次のノードへ渡す

3. pmxcfsによるデータ同期:書き込みの旅

では、ユーザーが「VMの設定を変更」した時、データは具体的にどう流れるのでしょうか?ここがProxmoxの整合性を担保する最重要ポイントです。

Step 1: アプリケーションからの書き込み要求

pvedaemon などのプロセスが /etc/pve/qemu-server/100.conf に書き込みを行います。これはFUSE経由で pmxcfs プロセスにフックされます。

Step 2: CPGによる配信 (Corosync)

pmxcfs は、変更内容をトランザクションとしてまとめ、Corosyncの CPG (Closed Process Group) APIを通じて全ノードへ送信依頼を出します。

このデータはCorosyncの送信バッファに入り、トークンが回ってくるのを待ちます。

Step 3: 受信と「即時永続化」 (重要)

ここが最もクリティカルな部分です。データを受信した全ノード(送信元含む)の pmxcfs は、以下の処理を行います。

メモリ更新

受信したデータを自身のインメモリSQLite DBに適用します。

永続化 (fsync)

pmxcfs はデータの消失を防ぐため、即座にバックエンドのSQLiteファイル(物理ディスク上)へ書き込みを行います。

この際、fsync() システムコールを発行し、「物理ディスクへの書き込みが完了するまで処理をブロック」します。

Step 4: コミット完了

全員の fsync() が完了し、トークンが一周してARUが更新されると、そのトランザクションはクラスタ全体で「コミット済み」となり、整合性が保証されます。

4. I/O性能とクラスタ安定性の関係

この仕組みからわかる通り、Proxmoxクラスタは「全員がディスクに書き終わるのを待つ」という挙動を基本としています。

なぜI/O遅延が問題になるのか

もし1台でもディスク書き込み(fsync)が遅いノードがいると、そのノードで処理がブロックされます。

ブロックされている間、Corosyncなどの通信プロセスも巻き添えで停止することがあります。

結果として、トークンの巡回が遅延し、最悪の場合は前回の記事で解説したタイムアウト(ノードダウン判定)につながります。

自宅ラボでの注意点

特に自宅サーバー(Homelab)環境では要注意!

  • 安価なUSBストレージをシステムディスクに使っている
  • 古いHDDを使用している
  • ネットワークストレージ経由でシステムが動作している

こうした環境では、fsync のレイテンシが大きくなりがちです。VMやコンテナのストレージは多少遅くても問題ありませんが、Proxmox本体のシステムディスクは、できるだけ高速なSSDを使うことを強くお勧めします。

可能であれば、PLP(Power Loss Protection)付きのSSDや、エンタープライズグレードのSSDを選定すると、より安定したクラスタ運用が可能になります。

まとめ

この記事では、Proxmoxクラスタの内部構造を深掘りしました。

要点のおさらい

  • Corosync/Totem: トークン・パッシングにより、メッセージの順序保証とメンバーシップ管理を実現
  • ARU(All Received Up to): 全ノードがメッセージを受信したことを確認する仕組み
  • pmxcfs: メモリ上のSQLiteデータベースをFUSE経由でファイルシステムとして提供
  • 即時永続化: 全ノードが fsync() でディスクに書き込むまでトランザクションが完了しない
  • I/O性能の重要性: システムディスクのI/O遅延がクラスタ全体の安定性に直結する

実践的なアドバイス

本番環境では、CPUやメモリだけでなく、「同期書き込み(fsync)のレイテンシ」が低いストレージを選定することが、アーキテクチャ上極めて重要です。
※標準搭載のコマンド「pveperf」というベンチマークツールで自分のマシンが1秒間で何回fsyncできるかを測れます!自分で測った感じだとUSBが30~50くらいで、SSDで3千以上でしたので百倍近く違いますね。。。

自宅ラボでも、システムディスクだけは高速なSSDを使うことで、より安定したProxmoxクラスタを構築できます。

前回の記事で解説したタイムアウト設定と合わせて、この内部構造を理解することで、より堅牢なクラスタ運用が可能になります。

参考資料

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?