記事
· 2023年9月5日 10m read

整合性チェック: 高速化と低速化

Caché と InterSystems IRIS データベースの整合性は、システム障害から完全に保護されてはいますが、物理ストレージデバイスが保管しているデータは、デバイスの障害によって破損してしまいます。  そのため、多くのサイトでは、データベースの整合性チェックを定期的に実行するように選択しており、特に特定のバックアップが災害時に信頼できるかどうかを検証するためにバックアップが行われています。  システム管理者がストレージの破損を伴う災害に対応するために、整合性チェックも緊急に必要となる場合もあります。  整合性チェックはチェックされているグローバルの各ブロック(すでにバッファーにない場合)を、グローバル構造で指示された順序で読み取る必要があります。 これには膨大な時間がかかりますが、整合性チェックは、ストレージサブシステムが維持できる限り高速に読み取ることができます。  一部の状況においては、できる限り迅速に結果を取得するために、そのように実行することが望ましい場合がありますが、  他の状況においては、ストレージサブシステムの帯域幅の過剰な消費を避けるために、整合性チェックをより保守的に行う必要があります。 

攻撃への対応計画

以下の概要は、ほとんどの状況に対応します。  この記事の残りの部分では、以下に示すいずれの攻撃にも対応するため、または他の対応方針を導き出すために必要な情報を詳しく説明しています。 

  1. Linux を使用しており、整合性チェックが低速化している場合は、非同期 I/O を有効にする作業について以下の情報をご覧ください。 
  2. 隔離された環境で実行しているか緊急に結果が必要であるため、整合性チェックをできるだけ素早く完了する必要がある場合は、マルチプロセス整合性チェックを使って、複数のグローバルまたはデータベースを並行してチェックします。  実行中の同時読み取り数の制限は、プロセス数 x 各プロセスが実行する同時非同期読み取りの数(デフォルトでは 8、または非同期 I/O が無効になっている Linux を使用している場合は 1)です。  平均はこの半分である場合があることを考慮し、ストレージサブシステムの能力と比較します。  たとえば、ストレージが 20 個のドライブにストライプ化されており、プロセスごとにデフォルトで 8 つの同時読み取りが行われる場合、ストレージサブシステムの全能力を得るには 5 つ以上のプロセスが必要になる可能性があります(5*8/2=20)。
  3. 整合性チェックの速度をプロダクションに対するインパクトに合わせて調整する場合、まず、マルチプロセス整合性チェックのプロセス数を調整してから、必要に応じて SetAsyncReadBuffers を調整します。  長期的なソリューション(および誤検出の排除)については、以下の「整合性チェックの分離」をご覧ください。
  4. すでに単一のプロセスに限定されており(1 つの非常に大きなグローバル制約またはその他の外部制約がある場合)、整合性チェックの速度の増減を調整する必要がある場合は、以下の SetAsyncReadBuffers 調整パラメーターをご覧ください。

マルチプロセス整合性チェック

整合性チェックをより素早く完了させる(より高い速度でシステムリソースを使用する)ための一般的なソリューションは、複数の並列プロセスで作業を分割することです。  整合性チェックの一部のユーザーインターフェースと API は分割するようになっていますが、単一のプロセスを使用するものもあります。  プロセスへの割り当てはグローバルごとに行われるため、1 つのグローバルのチェックは必ず 1 つのプロセスによって行われます(Caché 2018.1 より前のバージョンでは、グローバルではなくデータベースによって作業が分割されていました)。

マルチプロセス整合性チェックの主要 API は、CheckList^Integrity です(詳細はドキュメントを参照)。 一時グローバルに結果を収集して、Display^Integrity によって表示されます。 以下は、5 つのプロセスを使って 3 つのデータベースをチェックしている例です。 ここでデータベースリストのパラメーターを省略すると、すべてのデータベースがチェックされます。

set dblist=$listbuild(“/data/db1/”,”/data/db2/”,”/data/db3/”)
set sc=$$CheckList^Integrity(,dblist,,,5)
do Display^Integrity()
kill ^IRIS.TempIntegrityOutput(+$job)

/* 注意: 結果を表示するだけであれば、上記の ‘sc’ を評価する必要はありませんが...
   $system.Status.IsOK(sc) - 正常に実行され、エラーは見つからなかった
   $system.Status.GetErrorCodes(sc)=$$$ERRORCODE($$$IntegrityCheckErrors) // 267
                           - 正常に実行されたが、エラーが見つかった。
   その他の値  - 問題により、一部が実行できなかった。‘sc’ に複数のエラーコードがある可能性あり。うち 1 つは $$$IntegrityCheckErrors の可能性がある。 */

このように CheckList^Integrity を使用するのが、私たちが求めている制御レベルを達成する最も簡単な方法です。  管理ポータルのインターフェースと整合性チェックタスク(組み込み、ただしスケジュールなし)は複数のプロセスを使用しますが、目的に適う十分な制御が提供されていない場合があります。*

他の整合性チェックインターフェース、特にターミナルユーザーインターフェースの ^INTEGRIT または ^Integrity、および Silent^Integrity は、単一のプロセスで整合性チェックを実行します。 したがって、これらのインターフェイスは、可能な限り早くチェックを完了することはできず、使用するリソースも少なくなります。  ただし、目に見える結果を得られるというメリットがあります。ファイルにログされるか、グローバルごとにチェックされる過程で十分に定義された順番でターミナルに出力されます。 

非同期 I/O

整合性チェックプロセスは、グローバルの各ポインターブロックを一度に 1 つずつ、それが指すデータブロックのコンテンツに対して検証しながら行われます。  データブロックは非同期 I/O で読み取られ、ストレージサブシステムが処理できる多数の読み取りリクエストを処理し続け、それぞれの読み取りが完了するたびに検証が実行されます。 

Linux のみ: 非同期 I/O は、ダイレクト I/O と組み合わせた場合にのみ効果がありますが、ダイレクト I/O は InterSystems IRIS 2020.3 までデフォルトで有効になっていません。  これは、Linux 上で整合性チェックに時間がかかりすぎるという多くのケースの原因です。  幸いにも、Cache 2018.1 と IRIS 2019.1 以降では、.cpf ファイルの [config] セクションで wduseasyncio=1 を設定して再起動することで有効にできます。  このパラメーターは、ビジー状態のシステムにおいて I/O スケーラビリティを得るために一般的に推奨されており、Caché 2015.2 以降の Linux 以外のプラットフォームでデフォルトとなっています。  これを有効にする前に、データベースキャッシュ(グローバルバッファー)用に十分なメモリが構成されていることを確認してください。ダイレクト I/O を使用すると、データベースは Linux では(冗長して)キャッシュされなくなるためです。  有効でない場合、整合性チェックによって行われる読み取りは同期的に行われるため、ストレージで効率よく使用できません。 

すべてのプラットフォーム: 整合性チェックプロセスが一度に実行する読み取りの数は、デフォルトで 8 に設定されています。  1 回の整合性チェックプロセスがディスクから読み取る速度を変更する必要がある場合は、このパラメーターを調整できます。単一のプロセスをより素早く完了する場合は増やし、ストレージ帯域幅の使用を抑える場合は減らします。  以下の点に注意してください。

  • このパラメーターは整合性チェックプロセスごとに適用されます。  複数のプロセスが使用される場合、プロセスの数とこの実行中の読み取りの数を乗算します。同時整合性チェックプロセスの数の変更にははるかに大きな影響があるため、最初に行われるのが通例です。  各プロセスは、特に計算時間によって制限されるため、このパラメーターの値の増加のメリットには制限があります。
  • これは、ストレージサブシステムの同時読み取りの処理能力にのみ適用されます。 データベースが単一のローカルドライブに格納されている場合には、値を高くしても何のメリットもありませんが、数十個のドライブでストライプされているストレージアレイであれば、同時に数十個の読み取りを処理できます。

%SYS ネームスペースからこのパラメーターを調整するには、do SetAsyncReadBuffers^Integrity(value) を使用します。 現在の値を確認するには、write $$GetAsyncReadBuffers^Integrity() を使用します。 変更は、次のグローバルがチェックされるときに適用されます。  現時点では設定はシステムの再起動によって永続されませんが、SYSTEM^%ZSTART に追加することが可能です。

ディスク上でブロックが連続している(またはほぼ連続している)場合に、各読み取りの最大サイズを制御する同様のパラメーターがあります。  このパラメーターはそれほど必要ではありませんが、ストレージレーテンシの高いサブシステムまたはブロックサイズのより大きなデータベースの場合は、微調整を行うとメリットが得られる可能性があります。  値は 64KB 単位であるため、値 1 は 64KB、4 は 256KB、のようになります。0(デフォルト)にすると、システムによって選択され、現時点では 1(64KB)が選択されるようになっています。  このパラメーターの ^Integrity 関数は、上述の関数と同様に SetAsyncReadBufferSizeGetAsyncReadBufferSize です。

整合性チェックの分離

多くのサイトでは、直接プロダクションシステムで定期的な整合性チェックを実行しています。 もちろん最も単純な構成ではありますが、理想的ではありません。  ストレージ帯域幅に対する整合性チェックの影響についての懸念だけでなく、同時データベース更新アクティビティによって、(チェックアルゴリズムには対策が組み込まれてはいるものの)誤検出エラーが発生する可能性もあります。  そのため、プロダクションで実行された整合性チェックから報告されるエラーを、管理者が評価または再チェックする必要があります。

多くの場合、さらに優れたオプションが存在します。  ストレージスナップショットまたはバックアップイメージを別のホストにマウントする方法です。そこでは、分離された Caché または IRIS インスタンスによって整合性チェックが実行されます。  こうすることで、誤検出の可能性が防止されるだけでなく、ストレージもプロダクションから分離されていれば、ストレージ帯域幅を最大限に利用してはるかに素早く完了するように整合性チェックを実行できます。  この方法は、整合性チェックがバックアップの検証に使用されているモデルによく適しており、検証されたバックアップによって、バックアップが作成された時点でのプロダクションが効果的に検証されます。  また、クラウドと可視化プラットフォームを使用すれば、さらに簡単にスナップショットから使用可能な分離環境を確立することができます。

 


* 管理ポータルのインターフェース、整合性チェックタスク、および SYS.Database の IntegrityCheck メソッドはかなり多数のプロセス(CPU コアの数に等しい数)を選択するため、多くの状況で必要な制御ができなくなります。 管理ポータルとタスクも、同時更新によって発生した可能性のある誤検出を特定するために、エラーを報告したグローバルの完全な再チェックを実行します。 この再チェックは、整合性チェックアルゴリズムに組み込まれた誤検出対策を超えて行われ、時間がさらにかかるため、状況によっては望ましくない場合があります(再チェックは単一プロセスで実行され、グローバル全体をチェックします)。 この動作は今後変更される可能性があります。

@Ray Fucilloさんが書いた元の記事へ
ディスカッション (0)1
続けるにはログインするか新規登録を行ってください