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) を下位の通信層として使用して実装される、キャッシュ管理機能を提供します。
glock は、inode ごとにキャッシュを保護するため、キャッシング層を制御するのに使用されるロックが各 inode に 1 つあります。glock が共有モード (DLM ロックモード: PR) で付与されると、その glock の下のデータは、同時に 1 つまたは複数のノードにキャッシュすることができるため、すべてのノードはそのデータへのローカルアクセスを有することができます。
glock が排他モード(DLM ロックモード: EX)で許可されると、単一ノードのみがその glock でデータをキャッシュできます。このモードは、データを修正するすべての操作で使用されます (write システムコールなど)。
別のノードが即時に許可できない glock を要求すると、DLM は、その glock 現在を保持している 1 つまたは複数のノードに、新しい要求をブロックしてロックを解除するように依頼するメッセージを送信します。glock の削除の処理は、(ほとんどのファイルシステム操作の標準では) 長くなる可能性があります。共有 glock を削除するには、キャッシュを無効にすることだけが必要となりますが、それは比較的速く、キャッシュされたデータの量に比例します。
排他的 glock を削除するには、ログをフラッシュして、変更されたデータをディスクに書き戻した後は、共有 glock と同様に無効化を行う必要があります。
単一ノードのファイルシステムと GFS2 の違いは、単一ノードのファイルシステムにはキャッシュが 1 つだけあり、GFS2 には各ノードに個別のキャッシュがあることです。どちらの場合も、キャッシュされたデータへのアクセスのレイテンシーの長さは同じようになりますが、別のノードが以前同じデータをキャッシュしていると、キャッシュされていないデータにアクセスする場合のレイテンシーは、GFS2 の方がかなり長くなります。
共有 glock を必要とするのは、read (バッファー付き)、statreaddir などの操作のみです。排他的な glock を必要とするのは、write (バッファー付き)、mkdirrmdirunlink などの操作のみです。ダイレクト I/O の読み書き操作では、割り当てが行われていない場合は DF (deffered) 状態の glock が必要です。また、書き込みに割り合てが必要な場合は (つまりファイルの拡張または穴埋めには)、EX (exclusive) 状態の glock が必要です。
この場合、パフォーマンスに関する主な考慮事項が 2 つがあります。まず、読み込み専用操作は各ノードで独立して実行できるため、クラスター全体で並列処理が極めてよく機能します。次に、同じ inode へのアクセスを競うノードが複数あると、排他 glock を必要とする操作によりパフォーマンスが低下する場合があります。例えば 「ファイルシステムのバックアップ」 の説明にあるように、ファイルシステムのバックアップを行う場合などには、各ノードのワーキングセットを考慮することがGFS2 ファイルシステムパフォーマンスにおいて重要です。
これに加え、GFS2 では可能な限り、noatimenodiratime マウントオプションを使用することが推奨されます。これにより、read が atime タイムスタンプを更新する際に排他的なロックが必要なくなります。
ワーキングセットやキャッシング効率を懸念している場合でも、GFS2 では、GFS2 ファイルシステムのパフォーマンスを監視できる Performance Co-Pilot や GFS2 トレースポイントというツールを利用できます。これらはそれぞれ、付録A Performance Co-Pilot による GFS2 パフォーマンスの分析付録B GFS2 トレースポイントおよび debugfs glocks ファイル で説明されています。
注記
GFS2 のキャッシング機能の実装方法により、次のいずれかの場合にパフォーマンスが最適となります。
  • inode は全ノードにわたって読み取り専用で使用されます。
  • inode は、1 つのノードからのみ書き込みまたは変更されます。
ファイルの作成中および削除中に、ディレクトリーにエントリーを挿入したりディレクトリーからエントリーを削除すると、ディレクトリーの inode への書き込みとしてカウントされます。
比較的頻度が低い場合は、このルールを無視できます。ただし、このルールを無視しすぎると、パフォーマンスが大幅に低下します。
読み書きのマッピングがある GFS2 のファイルに mmap() を行い、そこからのみ読み込む場合のみ、これは読み込みとしてのみカウントされます。GFS は書き込みとしてカウントされるため、GFS2 は mmap() I/O でスケーラビリティーがはるかに高くなります。
noatime mount パラメーターを指定していない場合は、読み取りによって、ファイルのタイムスタンプを更新するための書き込みも発生します。すべての GFS2 ユーザーは、atime に特定の要件がない限り、noatime を使用してマウントすることが推奨されます。

2.9.1. POSIX ロックの問題

POSIX ロックを使用する場合は、以下の点を考慮する必要があります。
  • flock を使用すると、POSIX ロックを使用するより処理が速くなります。
  • GFS2 で Posix ロックを使っているプログラムは、GETLK の機能を使用しないようにする必要があります。これは、クラスター環境では、プロセス ID がクラスター内の別のノードに対するものである可能性があるためです。

2.9.2. GFS2 によるパフォーマンスチューニング

通常は、面倒なアプリケーションのデータ格納方法を変更すると、パフォーマンスを大幅に向上させることができます。
面倒なアプリケーションの典型的な例は、メールサーバーです。このアプリケーションは多くの場合、各ユーザーのファイルを含むスプールディレクトリー (mbox)、または各メッセージのファイルを含む各ユーザーのディレクトリー (maildir) に配置されます。要求が IMAP 経由で到達する場合は、各ユーザーに特定のノードへのアフィニティーを与えることが理想的です。このようにして、電子メールメッセージの表示や削除の要求は、そのノードのキャッシュから提供される傾向があります。当然ながら、そのノードに障害が発生すると、セッションを別のノードで再起動できます。
メールが SMTP 経由で到着した場合も、デフォルトで特定のユーザーのメールが特定のノードに渡されるようノードを個別に設定することが可能です。デフォルトのノードが稼働していない場合、メッセージは受信ノードによりユーザーのメールスプールに直接保存されます。この設計は、通常のケースで 1 つのノードにキャッシュされた特定のファイルセットを維持することを目的としていますが、ノードに障害が発生した時にはダイレクトアクセスを許可します。
この設定により GFS2 のページキャッシュを最大限に活用し、imap または smtp にかかわらず、アプリケーションに対して障害の発生を透過的にすることができます。
バックアップも、扱いにくい分野です。繰り返しますが、可能であれば、各ノードのワーキングセットを、その特定の inode のセットをキャッシュしているノードから直接バックアップを作成することが強く推奨されます。通常の時点で実行するバックアップスクリプトがあり、GFS2 で実行しているアプリケーションの応答時間が急に増大した思われる場合は、クラスターがページキャッシュを最も効率的に使用していない可能性が高くなります。
当然ながら、バックアップを実行するためにアプリケーションを停止することができるような優位な立場にある場合は問題はありません。一方、バックアップが 1 つのノードのみから実行する場合は、バックアップ完了後にそのノード上にファイルシステムの大部分がキャッシュされ、他のノードからの後続アクセスのパフォーマンスが低下します。次のコマンドを実行すると、バックアップ完了後にバックアップノード上の VFS ページキャッシュをドロップすることで、パフォーマンスの低下をある程度緩和できます。
echo -n 3 >/proc/sys/vm/drop_caches
ただし、この方法は、各ノードのワーキングセットが共有されているか、大半がクラスター全体で読み取り専用であるか、または 1 つのノードから大部分がアクセスされるようにするのと比べると、あまり良い解決策ではありません。

2.9.3. GFS2 ロックダンプを使用した GFS2 パフォーマンスのトラブルシューティング

GFS2 キャシングの使用効率が悪いためにクラスターのパフォーマンスが影響を受けている場合は、I/O の待機時間が大幅に長くなることがあります。GFS2 のロックダンプ情報を利用すると、この問題の原因を究明することができます。
本セクションでは、GFS2 ロックダンプの概要を説明します。GFS2 ロックダンプの詳細は、付録B GFS2 トレースポイントおよび debugfs glocks ファイル を参照してください。
GFS2 ロックダンプ情報は debugfs ファイルから収集することができます。このファイルのパス名は以下のとおりです (debugfs/sys/kernel/debug/ にマウントされていることが前提です)。
/sys/kernel/debug/gfs2/fsname/glocks
ファイルのコンテンツは一連の行になります。G: で始まる行はそれぞれ 1 つの glock を表し、それに続く 1 行のスペースでインデントされた行は、ファイル内で直前の glock に関する情報の項目を表します。
debugfs ファイルの最適な使用方法は、アプリケーションに問題の発生中に cat コマンドを使ってファイルの全内容のコピーをとり (RAM が大容量で、かつキャッシュされた inode が多数ある場合には長時間がかかる可能性があります)、後日に結果データを確認する方法です。
注記
debugfs ファイルのコピーを 2 つ作成すると、役に立つことがあります (2 つ目のコピーを最初のコピーの数秒後または数分後に作成します)。同じ glock 番号に関する 2 つのトレースの所有者情報を比較することで、ワークロードが進行中である (遅いだけ) か、それとも動かなくなったか (この場合は常にバグが原因であるため、Red Hat サポートに報告する必要があります) 判断できます。
debugfs ファイルの H: (ホルダー) で始まる行は、承認済みまたは承認待機中のロック要求を表します。ホルダーの行 f: の flags フィールドは、「W」フラグが待機要求を参照し、「H」フラグが許可された要求を参照しています。待機要求が多数ある glock は、特定の競合が発生している可能性があります。
表2.1「glock フラグ」は、さまざまな glock フラグの意味を示しており、表2.2「glock ホルダーフラグ」は、glock ホルダーのさまざまなフラグの意味を示します。

表2.1 glock フラグ

フラグ名前意味
bBlockingロックされたフラグが設定され、DLM から要求された操作がブロックされる可能性があることを示します。このフラグは、降格操作および「try」ロックに対して消去されます。このフラグの目的は、その他のノードがロックを降格する時間とは無関係に、DLM 応答時間の統計を収集できるようにすることです。
dPending demote遅延している (リモートの) 降格要求
DDemote降格要求 (ローカルまたはリモート)
fLog flushこの glock を解放する前にログをコミットする必要があります。
FFrozenリモートのノードからの返信が無視されます (復旧が進行中です)。このフラグは、異なるメカニズムを使用するファイルシステムのフリーズとは関係がなく、復元中にしか使用されません。
iInvalidate in progressこの glock の下でページを無効にする過程です。
IInitialDLM ロックがこの glock と関連付けられる場合に指定します。
lLockedglock は、状態を変更中です。
LLRUglock が LRU 一覧にあるときに設定します。
oObjectglock がオブジェクトに関連付けられている (つまり、タイプ 2 の glock の場合は inode、タイプ 3 の glock の場合はリソースグループ) ときに設定されます。
pDemote in progressglock は、降格要求に応答中です。
qQueuedホルダーが glock にキューイングされると設定され、glock が保持されるとクリアされますが、残りのホルダーはありません。アルゴリズムの一部として使用され、glock の最小保持時間を計算します。
rReply pendingリモートノードから受信した返信の処理を待機中です。
yDirtyこの glock を解放する前にデータをディスクにフラッシュする必要があります。

表2.2 glock ホルダーフラグ

フラグ名前意味
aAsyncglock の結果を待ちません (結果は後でポーリングします)。
AAny互換性のあるロックモードはすべて受け入れ可能です。
cNo cacheロック解除時に DLM ロックを即時に降格します。
eNo expire後続のロック取り消し要求を無視します。
Eexact完全一致するロックモードでなければなりません。
FFirstホルダーがこのロックに最初に許可される場合に指定します。
HHolder要求したロックが許可されたことを示します。
pPriorityキューの先頭にある待機ホルダー
tTry「try」ロックです。
TTry 1CBコールバックを送信する「try」ロックです。
WWait要求完了の待機中にセットされます。
問題の原因になっている glock を特定したら、それがどの inode に関連しているかを調べることが次のステップになります。glock 番号 (G: 行の n:) はこれを示します。type/number の形式で記載されており、type が 2 の場合は glock は inode glock で number は inode 番号になります。find -inum number のコマンドを実行すると、inode をトラッキングすることができます。glocks ファイルにある 16 進形式から 10 進形式に変換した inode 番号が number になります。
警告
ロックの競合が発生しているときにファイルシステムで find を実行すると、事態が悪化する可能性が高くなります。競合している inode を探している場合は、まずアプリケーションを停止してから find を実行することが推奨されます。
表2.3「glock タイプ」 は、さまざまな glock タイプの意味を示しています。

表2.3 glock タイプ

タイプ番号ロックタイプ使用方法
1Transトランザクションのロック
2inodeinode のメタデータとデータ
3Rgrpリソースグループのメタデータ
4Metaスーパーブロック
5Iopen最後に閉じた inode の検出
6Flockflock(2) syscall
8Quotaクォータ操作
9Journalジャーナルミューテックス
識別された glock のタイプが異なれば、それはタイプ 3: (リソースグループ) である可能性が最も高いです。通常の負荷下において他のタイプの glock を待機しているプロセスが多数ある場合は、Red Hat サポートに報告してください。
リソースグループロックでキューに置かれている待機要求が多く表示され場合は、複数の理由が考えられます。1 つは、ファイルシステム内のリソースグループ数と比べ、多くのノードが存在するためです。または、ファイルシステムがほぼ満杯になっている可能性もあります (平均して、空きブロックの検索時間が長い場合があります)。いずれの状況も、ストレージを追加し gfs2_grow コマンドを使用してファイルシステムを拡張することで改善することができます。