Azure AI Search で大規模なデータ セットのインデックスを作成する
この記事では、検索ソリューションで大規模または複雑なデータ セットのインデックスを作成する必要がある場合に、Azure AI 検索で実行時間の長いプロセスに対応するための戦略について説明します。
このような戦略では、データをインポートするための 2 つの基本的な方法 (インデックスへのデータの "プッシュ"、または検索インデクサーを使用したサポートされているデータ ソースからのデータの "プル") について理解していることを前提としています。 計算負荷の高い AI エンリッチメントがシナリオに含まれている場合、スキルセットがインデクサーに依存していることを考えると、インデクサーが必要になります。
この記事では、インデックスとクエリの設計に関するベスト プラクティスを提供する、パフォーマンス向上のためのヒントを補完します。 必要なフィールドと属性のみを含む適切に設計されたインデックスは、大規模なインデックス作成の重要な前提条件です。
パーティションあたりのストレージを増やすために、2024 年 4 月 3 日より後に作成された新しい検索サービスを使用することをお勧めします。
Note
この記事で説明する戦略では、1 つの大規模なデータ ソースを想定しています。 ソリューションで複数のデータ ソースからのインデックスを作成する必要がある場合は、「Azure AI Searchで複数のデータ ソースのインデックスを作成する」を参照して、推奨される方法を確認してください。
プッシュ API を使用してデータのインデックスを作成する
Documents Index REST API や IndexDocuments メソッド (Azure SDK for .NET) などの "プッシュ" API は、Azure AI 検索で最も一般的な形式のインデックス作成です。 プッシュ API を使用するソリューションの場合、実行時間の長いインデックス作成の戦略には、次のコンポーネントのいずれかまたは両方があります。
- ドキュメントのバッチ処理
- スレッドの管理
要求ごとに複数のドキュメントをバッチ処理する
大量のデータにインデックスを付ける簡単なメカニズムは、複数のドキュメントまたはレコードを 1 つの要求で送信するというものです。 ペイロード全体が 16 MB を超えない限り、1 つの要求によって、一括アップロード操作で最大 1,000 個のドキュメントを処理できます。 これらの制限は、Documents Index REST API または .NET SDK の IndexDocuments メソッドのどちらを使用しているかに関係なく適用されます。 どちらの API を使用しても、各要求の本文に 1,000 個のドキュメントをパッケージ化できます。
ドキュメントをバッチ処理すると、大量のデータを処理するのにかかる時間が大幅に短縮されます。 実際のデータに最適なバッチ サイズを見極めることが、インデックスの作成速度を最適化するうえで重要な要素となります。 最適なバッチ サイズは主に、次の 2 つの要因によって左右されます。
- インデックスのスキーマ
- データのサイズ
最適なバッチ サイズはインデックスとデータによって異なるため、さまざまなバッチ サイズをテストしながら、実際のシナリオにおいてインデックスの作成速度が最速となるサイズを見極めるのが最善のアプローチとなります。 .NET SDK を使用してバッチ サイズをテストするためのサンプル コードについては、「チュートリアル: プッシュ API を使用してインデックス作成を最適化する」を参照してください。
スレッドと再試行戦略の管理
インデクサーには組み込みのスレッド管理がありますが、プッシュ API を使用する場合は、アプリケーション コードでスレッドを管理する必要があります。 最近パーティションを増やしたか、上位レベルの検索サービスにアップグレードした場合は特に、使用可能な容量を最大限に活用するのに十分なスレッドがあることを確認します。
クライアント コードで同時スレッドの数を増やします。
検索サービスに対する要求を増やしていくと、要求が完全には成功しなかったことを示す HTTP 状態コードが返されることがあります。 インデックスの作成時によく発生する HTTP 状態コードは次の 2 つです。
503 Service Unavailable: このエラーは、システムに大きな負荷がかかっており、この時点では要求を処理できないことを意味します。
207 Multi-Status: このエラーは、一部のドキュメントは成功しましたが、少なくとも 1 つは失敗したことを意味します。
失敗を処理するには、エクスポネンシャル バックオフの再試行戦略を使用して、要求を再試行する必要があります。
503 などで失敗した要求は、Azure .NET SDK によって自動的に再試行されますが、207 の再試行には独自のロジックを実装する必要があります。 Polly などのオープンソース ツールを使用して、再試行戦略を実装することもできます。
インデクサーおよびプル API を使用する
インデクサーには、実行時間の長いプロセスに役立ついくつかの機能があります。
- ドキュメントのバッチ処理
- パーティション分割されたデータに対する並列インデックス作成
- 新規および変更されたドキュメントのみのインデックス作成のためのスケジュール設定と変更の検出
インデックスのスケジュールにより、最後の既知の停止ポイントから処理を再開できます。 処理期間内にデータが完全にインデックス付けされていない場合、インデクサーは、変更検出を提供するデータ ソースを使用していると仮定して、次回の実行時に中断した場所を取得します。
データをより小さな個々のデータ ソースにパーティション分割することにより、並列処理が実現されます。 Azure Blob Storage 内の複数のコンテナーなどにソース データを分割し、各パーティションのデータ ソースを作成してから、検索サービスの検索単位の数に従ってインデクサーを並列に実行できます。
インデクサーのバッチ サイズを確認する
Push API と同様に、インデクサーを使用すると、バッチごとに項目の数を構成できます。 インデクサーの作成 (REST API) に基づいたインデクサーの場合は、引数 batchSize
を設定することで、ご利用のデータの特性に合わせてこの設定をカスタマイズすることができます。
既定のバッチ サイズは、データ ソースによって異なります。 Azure SQL Database と Azure Cosmos DB の既定のバッチ サイズは 1,000 です。 それに対して、Azure Blob インデックス作成では、より大きな平均ドキュメント サイズを認識して、バッチ サイズが 10 のドキュメントに設定されます。
実行時間の長いプロセスのためにインデクサーをスケジュールする
インデクサーのスケジュール設定は、大容量のデータ セットの処理や、エンリッチメント パイプラインでの画像分析などの低速実行処理に適応する上で重要なメカニズムです。
通常、インデクサー処理は 2 時間以内に実行されます。 インデックス作成ワークロードの完了に、数時間ではなく数日かかる場合は、2 時間ごとに開始される連続する定期的なスケジュールをインデクサーに設定できます。 データ ソースで変更の追跡が有効になっているとすると、インデクサーは最後に中断した場所で処理を再開します。 この頻度で、インデクサーでは、すべての未処理ドキュメントが処理されるまで、ドキュメントのバックログに従って数日にわたり処理を継続できます。
{
"dataSourceName" : "hotels-ds",
"targetIndexName" : "hotels-idx",
"schedule" : { "interval" : "PT2H", "startTime" : "2024-01-01T00:00:00Z" }
}
データ ソースに新しいドキュメントまたは更新されたドキュメントが存在しなくなった場合、インデクサーの実行履歴に処理されたドキュメント数 0/0
が報告され、処理は行われません。
スケジュールの設定の詳細については、「Create Indexer REST API」を参照するか、「Azure AI 検索でインデクサーのスケジュールを設定する」を参照してください。
Note
古いランタイム アーキテクチャで実行されるインデクサーの中には、最大処理期間が 2 時間ではなく 24 時間のインデクサーがあります。 2 時間の制限は、内部で管理されるマルチテナント環境で実行される新しいコンテンツ プロセッサが対象です。 可能な限り、Azure AI Search はインデクサーとスキルセットの処理をマルチテナント環境にオフロードしようとします。 インデクサーを移行できない場合は、プライベート環境で実行し、24 時間まで実行できます。 これらの特性を示すインデクサーをスケジュールする場合は、24 時間の処理期間を想定してください。
インデクサーを並列で実行する
データをパーティション分割する場合は、各データ ソースからプルして同じ検索インデックスに書き込むインデクサーとデータ ソースの組み合わせを作成できます。 各インデクサーは異なるため、同時に実行でき、検索インデックス順次実行する場合よりも迅速に設定できます。
十分な容量があることを確認します。 サービス内の 1 つの検索単位は、特定の時点で 1 つのインデクサーを実行できます。 複数のインデクサーの作成は、並列で実行できる場合にのみ有効です。
同時に実行できるインデックス作成ジョブの数は、テキストベースおよびスキルベースのインデックス作成によって異なります。 詳細については、「インデクサーの実行」を参照してください。
データ ソースが Azure Blob Storage コンテナーまたは Azure Data Lake Storage Gen 2 の場合、大量の BLOB を列挙すると、この操作が完了するまでに長い時間 (数時間) に及ぶこともあります。 その結果、インデクサーの "ドキュメントが成功した" の数がその間に増加しているようには見えず、進行しているのに、そうでないように見える場合があります。 大量の BLOB でドキュメント処理を高速化するには、データを複数のコンテナーにパーティション分割し、1 つのインデックスを指す並列インデクサーを作成することを検討してください。
Azure portal にサインインして、検索サービスで使用されている検索ユニットの数を確認します。 [設定]>[スケール] を選択して、ページの上部の数値を表示します。 並列で実行されるインデクサーの数は、検索ユニットの数とほぼ等しくなります。
複数のコンテナーまたは同じコンテナー内の複数の仮想フォルダーにソース データをパーティション分割します。
各インデクサーで同じターゲット検索インデックスを指定します。
インデクサーをスケジュールします。
インデクサーの状態と実行履歴を確認します。
並列インデックス作成にはいくつかのリスクがあります。 まず、インデックス作成がバックグラウンドで実行されないことを思い出してください。これにより、クエリが調整または削除される可能性が高くなります。
2 つ目に、Azure AI Search ではインデックスの更新がロックされません。 同時書き込みは管理され、特定の書き込みが最初の試行で成功しなかった場合は再試行を呼び出しますが、インデックス作成の失敗が増加する場合があります。
インデクサーとデータ ソースの複数のセットで同じインデックスをターゲットにすることはできますが、インデックスの既存の値を上書きできるインデクサーの実行にご注意ください。 2 番目のインデクサーとデータ ソースで同じドキュメントとフィールドがターゲットになっている場合、最初の実行の値がすべて上書きされます。 フィールドの値は完全に置き換えられます。インデクサーで、複数の実行の値を同じフィールドにマージすることはできません。
Spark でビッグ データのインデックスを作成する
ビッグ データ アーキテクチャがあり、データが Spark クラスター上にある場合は、データの読み込みとインデックス作成のために SynapseML をお勧めします。 このチュートリアルには、AI エンリッチメントのために Azure AI サービスを呼び出す手順が含まれていますが、テキストのインデックス作成には AzureSearchWriter API を使用することもできます。