Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

2.9. GFS2 のノードロック機能

GFS2 ファイルシステムでパフォーマンスを最適化するには、操作に関する基本的な理論をある程度理解しておくことが非常に重要となります。単一ノードファイルシステムはキャッシュと共に実装され、頻繁に要求されるデータを使用する場合にディスクへのアクセスの待ち時間をなくすことを目的としています。Linux では、ページキャッシュ (および以前はバッファーキャッシュ) によりこのキャシング機能が提供されます。
GFS2 では各ノードに独自のページキャッシュがあり、オンディスクデータの一部が含まれていることがあります。 GFS2 は glocks (ジーロックスと発音) と呼ばれるロック機能のメカニズムを使用してノード間のキャッシュの整合性を維持します。glock サブシステムは、分散型ロックマネージャー (DLM) を下位の通信層として使用して実装される、キャッシュ管理機能を提供します。
glocks では、inode ごとにキャッシュの保護が提供されるため、ロックは 1 inode あたり 1 つとなり、キャッシング層の制御に使用されます。この glock が共有モード (DML ロックモード: PR) で許可されると、その glock 配下のデータは 1 ノードまたは複数のノードに同時にキャッシュすることができるため、全ノードがそのデータにローカルでアクセスできるようになります。
glock が排他モード (DLM ロックモード: EX) で許可された場合、その glock 配下では単一のノードしかデータをキャッシュすることができなくなります。このモードは、データを修正するすべての操作で使用されます (write システムコールなど)。
別のノードが即時に許可できない glock を要求した場合、DLM はその glock を保持しているため新しい要求の妨げとなっているノードにメッセージを送り、その glock をドロップするよう要求します。glock のドロップは時間がかかるプロセスとなる場合があります (大半のファイルシステム操作の基準で判断した場合)。共有の glock をドロップする場合はキャッシュの無効化だけなので比較的短時間で完了し、キャッシュされたデータ量に比例します。
glock を限定してドロップするには、ログをフラッシュして変更されたデータをディスクに書き戻した後、共有 glock ごとに無効化を行う必要があります。
単一ノードファイルシステムと GFS2 で異なるのは、単一ノードファイルシステムのキャッシュは一つであるのに対して、GFS2 にはノードごとに別個のキャッシュがある点です。いずれの場合も、キャッシュ済みデータへのアクセスの待ち時間は同じ程度ですが、キャッシュされていないデータへのアクセスに関しては、別のノードが以前に同じデータをキャッシュしていた場合、GFS2 の方がはるかに長くなります。

注記

GFS2 のキャッシング機能の実装方法により、次のいずれかの場合にパフォーマンスが最適となります。
  • inode が全ノードにわたって読み取り専用で使用される
  • inode が単一ノードからのみ書き込みまたは修正される
ファイル作成時および削除時に行われるディレクトリーへのエントリの挿入や削除は、ディレクトリー inode への書き込みと見なされる点に注意してください。
このルールを違反することは可能ですが、比較的頻度が低いことが条件となります。このルールを無視しすぎるとパフォーマンスに深刻な影響を及ぼすことになります。
読み込み/書き込みのマッピングを用いて GFS2 上のファイルを mmap() しても、読み取りしか行わない場合は、読み取りのみと見なされますが、GFS 上では書き込みとして見なされるため、mmap() I/O では、GFS2 の方が拡張性がはるかに高くなります。
noatime mount パラメーターを指定していない場合は、読み取りによって、ファイルのタイムスタンプを更新するための書き込みも発生します。GFS2 を使用する場合、atime を特に必要としない限りは、noatime を指定してマウントすることを推奨します。

2.9.1. POSIX ロックの問題

POSIX ロックを使用する場合、以下の点を考慮する必要があります。
  • 処理速度は Flock を使用した方が POSIX ロックより早くなります。
  • クラスター環境では指定のプロセス ID が別のノード用である場合もあるため、GFS2 で POSIX ロックを使用するプログラムは、GETLK 関数の使用を避けるべきです。