メインコンテンツまでスキップ

AI検索エンドポイントの負荷テストを構成します

このページでは、AI Searchエンドポイントの負荷テストに関するガイダンス、サンプルコード、およびサンプルノートブックを提供しています。負荷テストは、AI Search エンドポイントが本番環境にデプロイされる前に、そのパフォーマンスと本番運用の準備状況の確認に役立ちます。負荷テストからわかること:

  • 異なるスケーリングレベルでのレイテンシ
  • スループットの制限とボトルネック(1 秒あたりのリクエスト数、レイテンシの内訳)
  • 持続的な負荷時のエラー率
  • リソース使用率とキャパシティ プランニング

ロード テストと関連する概念の詳細については、サービス エンドポイントのロード テストを参照してください。

要件

これらのステップを開始する前に、デプロイ済みのAI検索エンドポイントと、そのエンドポイントに対し、 Can Query 権限を持つサービスプリンシパルが必要です。「ステップ 1: サービスプリンシパルの認証を設定する」を参照してください。

以下のファイルと例のノートブックをダウンロードして、Databricks ワークスペースにインポートしてください。

  • input.json。これは、すべての並列接続によってエンドポイントに送信されるペイロードを指定する input.json ファイルの例です。必要に応じて複数のファイルを持つことができます。サンプルノートブックを使用する場合、このファイルは提供された入力テーブルから自動的に生成されます。
  • fast_vs_load_test_async_load.py。このスクリプトをワークスペースにアップロードし(例: /Workspace/Users/<your-username>/fast_vs_load_test_async_load.py)、locust_script_pathノートブック・パラメーターをそのパスに設定します。このスクリプトは、認証、ペイロードの配信、およびデバッグメトリクスの収集を処理します。
  • 次の サンプルノートブック は、負荷テストを実行します。最高のパフォーマンスを得るには、このノートブックを、多数のコアを備えたSingle Node クラスターで実行してください (Locust は利用可能なすべての CPU にわたってスケーリングします)。事前生成された埋め込みを使用するクエリには、高メモリが推奨されます。

ノートブックの例およびクイックスタート

以下の例のノートブックを使用して開始してください。2つの探索モードをサポートしています。それは、定義する特定の同時実行レベルをテストする段階的なスイープと、数ステップで最大の持続可能なQPS(ブレークポイント)を自動的に検出するバイナリ検索モードです。すべてのパラメーターはウィジェットを使用して構成されるため、ノートブックはコードを編集することなく、インタラクティブに、または Databricks ジョブとして実行できます。

Locust load test ノートブック

ノートブックを新しいタブで開く

負荷テスト フレームワーク:Locust

Locustは、オープンソースの負荷テスト フレームワークで、次のことができます。

  • 並列クライアント接続の数を調整します。
  • 接続の生成速度を制御します
  • テスト全体を通じてエンドポイントのパフォーマンスを測定します。
  • 利用可能なすべてのCPUコアを自動で検出して使用します。

サンプルのノートブックは、「--processes -1」フラグを使用してCPUコアを自動検出し、それらを最大限に活用します。

Locust が CPU によってボトルネックになっている場合、出力にメッセージが表示されます。

ステップ 1: サービスプリンシパル認証を設定する

重要

本番運用に近いパフォーマンステストには、常にOAuthサービスプリンシパル認証を使用してください。サービスプリンシパルは、個人用アクセストークン (PAT) に比べて、応答時間を最大100ミリ秒高速化し、要求レート制限を向上させます。

サービスプリンシパルを作成および構成

  1. Databricks サービスプリンシパルの作成手順については、サービスプリンシパルをアカウントに追加するを参照してください。

  2. 権限を付与:

    • AI検索エンドポイントページに移動してください。
    • [ アクセス許可 ]をクリックします。
    • サービスプリンシパルに Can Query 権限を与えます。
  3. OAuthシークレットを作成してください。

    • サービスプリンシパルの詳細ページに移動します。
    • [ シークレット ] タブをクリックします。
    • [ シークレットを生成 ] をクリックします。
    • 有効期間を設定します (長期テストには365日を推奨します)。
    • 「 クライアントID 」と「 シークレット 」の両方を直ちにコピーしてください。
  4. 認証情報を安全に保管してください。

    • Databricks シークレットスコープを作成する。手順については、「チュートリアル: Databricks シークレットを作成して使用する」を参照してください。
    • 以下のコード例に示すように、サービスプリンシパルのクライアント ID を service_principal_client_id として保存し、OAuth シークレットを service_principal_client_secret として保存します。
    Python
    # In a Databricks notebook
    dbutils.secrets.put("load-test-auth", "service_principal_client_id", "<CLIENT_ID>")
    dbutils.secrets.put("load-test-auth", "service_principal_client_secret", "<SECRET>")

ステップ2:ロードテストを設定する

ノートブックの構成

ノートブックの上部にあるウィジェットを使用して、ノートブックのパラメーターを構成します。Databricksジョブとしてノートブックを実行する際は、これらの値をジョブパラメーターとして渡してください。コードの編集は必要ありません。

パラメーター

説明

推奨値

endpoint_name

AI検索エンドポイントの名前

エンドポイント名

index_name

完全なインデックス名(catalog.schema.index

インデックス名

test_table

クエリをサンプリングするためのソーステーブル (catalog.schema.table)

インデックス入力テーブル

query_column

管理埋め込みに使用するテキスト列

textのままにするか、または列名を設定してください。

embedding_column

事前計算されたエンベディングベクトルを含む列。セルフマネージド型埋め込みにのみ使用されます。

管理対象の埋め込みについては空白のままにします。

sample_size

テスト用にサンプリングするクエリーの数

1000

target_concurrencies

テストする並列クライアント数のカンマ区切りリスト

5,10,20,50

step_duration_seconds

同時実行レベルごとの秒数。1つの値がすべてのレベルに適用されます。または、レベルごとに1つをカンマ区切りリストとして指定します。

300 (5分)

secret_scope_name

Databricks シークレットスコープ名

スコープ名

locust_script_path

fast_vs_load_test_async_load.pyスクリプトへのワークスペースパス

/Workspace/Users/<your-username>/fast_vs_load_test_async_load.py

output_table

(オプション)結果を保存する Delta テーブル(catalog.schema.table)。最初の実行時に自動的に作成されます。

catalog.schema.load_test_results

run_name

後で分析できるように、この実行をタグ付けする名前またはコメント

説明ラベル

exploration_mode

gradual target_concurrencies を順に通過します。binary_searchは互換性に影響する変更を自動的に検出します(Breaking point explorationを参照してください)。

gradual

max_target_qps

binary_search のみ)QPS 検索に対する上界

500

exploration_steps

binary_searchのみ)二分探索の最大反復回数

8

error_rate_threshold

binary_searchのみ)ステップが成功とカウントされるための最大許容エラー率(%)

1.0

num_results

クエリーごとに返される結果の数

10

columns_to_return

クエリ結果で返される列のコンマ区切りリスト(例えば、id,text)。空白のままにすると、すべての列が返されます。

デフォルトを使用する場合は、空白のままにしてください。

マネージド型とセルフマネージド型の埋め込み

ノートブックは、マネージド埋め込み(Databricksがクエリ時に埋め込みを生成します)とセルフマネージド埋め込み(事前計算されたベクトルを直接渡します)の両方に対応しています。インデックスタイプに基づいて、適切なパラメーターを構成してください。

インデックスタイプ

設定するパラメーター

未設定のままにしてください

マネージド型埋め込み (Databricksによる埋め込みモデルを備えたDelta Syncインデックス)

query_column クエリとして使用するテキスト列の名前

embedding_column (空白のままにする)

セルフマネージド型埋め込み (事前計算済みベクトルを備えたDelta SyncまたはDirect Vector Accessインデックス)

embedding_column 事前計算された埋め込みベクトルを含む列

query_column

注記

マネージド埋め込みインデックスの場合、ロードテストは埋め込み生成時間を含むエンドツーエンドのレイテンシを測定します。エンべディングエンドポイントがゼロにスケーリングする場合、最初のテスト実行でコールドスタートのオーバーヘッドが発生します。検索遅延から埋め込み遅延を切り離す方法については、埋め込みモデルのボトルネックを特定するを参照してください。

5~10分かかるのはなぜですか?

5分の最小テスト期間は不可欠です。

  • 初期クエリにはコールドスタートオーバーヘッドが含まれる場合があります。
  • エンドポイントが安定したパフォーマンスに達するには時間がかかります。
  • モデルサービングのエンドポイントのオートスケーリング(有効化されている場合)は、アクティブ化に時間がかかります。
  • 短時間のテストでは、継続的な負荷がかかっている状況でのスロットリング動作を把握できません。

次の表では、テストの目標に応じた推奨テスト期間を示しています。

テストタイプ

テスト期間

テストの目標

クイックスモークテスト

2~3分

基本的な機能を確認する

パフォーマンス ベースライン

5~10分

信頼性の高い定常状態メトリクス

ストレステスト

15~30分

リソース枯渇の特定

耐久テスト

1~4時間

劣化、レイテンシーの安定性

ブレークポイント探索(バイナリ検索モード)

グラジュアルスイープ (exploration_mode=gradual) に加えて、ノートブックは、同時実行レベルを手動で指定することなく最大持続可能QPSを特定する、自動バイナリサーチモードをサポートしています。

仕組み

exploration_mode=binary_searchを設定し、max_target_qpsを指定します(例:500)。このノートブックは、リトルの法則concurrency = QPS × avg_latency_sec)を使用して各QPSターゲットを推定される同時実行レベルに変換し、次に、以下のように二分探索を実行します。

  1. max_target_qps / 2から開始します(例の場合250)。
  2. エラー率がerror_rate_thresholdを下回る場合(成功)、下限を引き上げ、より高いQPS(375、その後500など)を試してください。
  3. エラー率が閾値(失敗)を超えた場合は、上限を下げ、最後の成功と失敗の中間点を試してください。
  4. 最大exploration_stepsステップ(デフォルト8)繰り返すか、検索範囲がmax_target_qpsの5%以内に狭まるまで繰り返します。

次の表は、約430 QPS付近に限界点がある仮想のエンドポイントにおける検索の収束状況を示しています。

ステップ

ターゲットQPS

エラー率

結果

新規範囲

1

250

0.1%

成功

[250、500]

2

375

0.3%

成功

[375, 500]

3

437

4.5%

失敗

[375, 437]

4

406

0.8%

成功

[406, 437]

5

421

2.1%

失敗

[406, 421]

5~8ステップで、検索はブレークポイント(この例では約406~421 QPS)に収束します。これは、網羅的なスイープよりもはるかに少ないテスト実行回数で実現されます。

各モードの使い分け

モード

使用する場合:

gradual

すでに予想される動作範囲がわかっており、特定の同時実行レベルでパフォーマンスの特性を評価したいです。

binary_search

事前に同時実行レベルを把握していなくても、迅速に持続可能な最大QPSを特定したい。

ステップ 3: クエリセットを設計する

クエリセットは、予想される本番運用トラフィックを可能な限り忠実に反映する必要があります。具体的には、コンテンツ、複雑さ、多様性の観点から、クエリの期待される分布に合わせるようにしてください。

  • 現実的なクエリを使用する。「test query 1234」のようなランダムなテキストは使用しないでください。

  • 期待される本番運用のトラフィック分布に一致させます。80%の一般的なクエリ、15%の中程度の頻度のクエリ、そして5%の低頻度のクエリを想定している場合、クエリセットはその分布を反映している必要があります。

  • 本番運用で想定されるクエリのタイプに合わせてください。例えば、本番運用のクエリでハイブリッド検索またはフィルターを使用することを想定している場合は、クエリセットでもそれらを使用する必要があります。

    フィルターを使用するクエリーの例:

    JSON
    {
    "query_text": "wireless headphones",
    "num_results": 10,
    "filters": { "brand": "Sony", "noise_canceling": true }
    }

    ハイブリッド検索を使用したクエリーの例:

    JSON
    {
    "query_text": "best noise canceling headphones for travel",
    "query_type": "hybrid",
    "num_results": 10
    }

クエリの多様性とキャッシュ

AI検索エンドポイントは、パフォーマンスを向上させるために数種類のクエリ結果をキャッシュします。このキャッシュは負荷テストの結果に影響を与える可能性があります。このため、クエリ セットの多様性に注意することが重要です。たとえば、同じクエリ セットを繰り返し送信する場合は、実際の検索パフォーマンスではなく、キャッシュをテストしていることになります。

使用:

時期:

同一あるいは少ないクエリ

  • 本番運用のトラフィックはクエリーの繰り返しが多く(たとえば、「人気製品」)なっています。

  • キャッシュの有効性を具体的にテストしていることになります。

  • アプリケーションでキャッシュを活用できます(例: 固定クエリを使用するダッシュボード)。

  • ベストケースのキャッシュ性能を測定したい場合

「トレンドアイテム」を表示する製品レコメンデーションウィジェット — 同じクエリは1時間あたり数千回実行されます。

多様なクエリ

  • 本番運用トラフィックには、固有のユーザー クエリがあります(例:検索エンジンやチャットボット)。

  • ワーストケースのキャッシュなしのパフォーマンスを測定します。

  • テストしたいのは、キャッシュパフォーマンスではなく、インデックススキャンパフォーマンスです。

  • クエリはカーディナリティが高い(数百万ものバリエーションが存在します)

各ユーザーが異なる製品検索を入力するeコマース検索。

追加の推奨事項については、「ベストプラクティスの概要」を参照してください。

クエリーセット作成オプション

コードタブには、多様なクエリセットを作成するための3つのオプションが表示されます。全てに当てはまるものはありません。ご自身にとって最適なものを選択してください。

  • (推奨) インデックス入力テーブルからのランダムサンプリングこれは良い出発点です。
  • 本番運用ログからのサンプリング。本番運用ログがあれば、これは良いスタートです。クエリは通常、時間の経過とともに変化します。そのため、テストセットを定期的に更新して、最新の状態に保ってください。
  • 合成クエリ生成中です。これは、本番運用ログがない場合や、複雑なフィルターを使用している場合に便利です。

次のコードは、インデックス入力テーブルからランダムなクエリを取得します。

Python
import pandas as pd
import random

# Read the index input table
input_table = spark.table("catalog.schema.index_input_table").toPandas()

# Sample random rows
n_samples = 1000
if len(input_table) < n_samples:
print(f"Warning: Only {len(input_table)} rows available, using all")
sample_queries = input_table
else:
sample_queries = input_table.sample(n=n_samples, random_state=42)

# Extract the text column (adjust column name as needed)
queries = sample_queries['text_column'].tolist()

# Create query payloads
query_payloads = [{"query_text": q, "num_results": 10} for q in queries]

# Save to input.json
pd.DataFrame(query_payloads).to_json("input.json", orient="records", lines=True)

print(f"Created {len(query_payloads)} diverse queries from index input table")

ステップ4.ペイロードをテスト

完全なロードテストを実行する前に、ペイロードを検証してください。

  1. Databricks ワークスペースで、AI検索エンドポイントに移動してください。
  2. 左側のサイドバーで、**サービング**をクリックしてください。
  3. エンドポイントを選択。
  4. 利用 > クエリー をクリックします。
  5. input.jsonの内容をクエリボックスに貼り付けます。
  6. エンドポイントが期待どおりの結果を返すことを確認してください。

これにより、ロードテストではエラー応答ではなく、現実的なクエリが測定されます。

ステップ 5: ロードテストを実行する

接続チェックとウォームアップ

ロードテストを開始する前に、ノートブックは2つのセットアップステップを実行します。

  1. 接続チェック :サービスプリンシパルの資格情報を使用して、単一のプローブクエリを送信します。エンドポイントが401または403エラーを返した場合、ノートブックは、エラーデータのみを生成する完全な負荷テストを実行する代わりに、明確なPermissionErrorで直ちに失敗します。資格情報や権限の設定が誤っている場合に、時間を節約できます。

  2. ウォームアップテスト(1分間): エンドポイントキャッシュをウォームアップし、エンドツーエンドのリクエストフローを検証する短い低並行性テストを実行します。ウォームアップの結果はパフォーマンスメトリクスには使用されません。バイナリ検索モードでは、ウォームアップレイテンシーはリトルの法則に基づく同時実行性推定のベースラインとしても使用されます。

メイン負荷テスト シリーズ

ノートブックは、クライアントの同時実行数を段階的に増やしながら一連のテストを実行します。

  • 開始: 低並列 (例: 5 並列クライアント)
  • 中: 中程度のコンカレンシー(例えば、10、20、または 50 クライアント)
  • 終了: high concurrency (例: 100 クライアント以上)

各テストは、step_duration_secondsで設定された期間実行されます(5~10分を推奨します)。

ノートブックが測定する内容とは

このノートブックでは、以下の項目を測定し、報告します:

レイテンシー メトリクス:

  • P50(中央値): クエリの半分はこれよりも高速です。
  • P95: クエリの95%がこれより高速です。これは主要なSLAメトリクスです。
  • P99: クエリの99%がこの値よりも高速です。
  • 最大: 最悪の場合のレイテンシ。

スループット メトリクス:

  • RPS(1秒あたりのリクエスト): 1秒あたりの成功したクエリーです。
  • 総クエリー数: 完了したクエリー数。
  • 成功率: 成功したクエリの割合です。

エラー:

  • タイプ別のクエリー失敗
  • 例外メッセージ
  • タイムアウト回数

結果の保存

output_tableパラメーターが設定されている場合、ノートブックは同時実行レベルごと (またはバイナリサーチのステップごと) に1行をUnity Catalog Deltaテーブルに保存します。テーブルは、最初の実行時に自動的に作成され、その後の実行で追加されます。各行には、run_nameexploration_mode、同時実行性、成功/失敗率、レイテンシーパーセンタイル、RPS、およびバイナリー検索固有のフィールド(bs_stepbs_target_qpsbs_outcome)が含まれます。SQLまたはBIツールを使用すると、実行を時系列で比較できます。

Databricksジョブとして実行中

すべてのノートブックパラメーターは dbutils.widgets として定義されており、Databricksジョブパラメーターに直接マッピングされます。負荷テストをスケジュールまたは自動化するには:

  1. ノートブックをタスクとしてジョブを作成します。
  2. ウィジェットの値をジョブパラメーターとして設定します。コードの編集は必要ありません。
  3. 多数のCPUコアを持つシングルノード クラスターにジョブをアタッチします(Locustは並列ワーカーから恩恵を受けます)。
  4. オンデマンドで、または定期的なベースラインテスト用にスケジュールで実行します。

ステップ6:結果を解釈する。

次の表は、良好なパフォーマンスのターゲットを示しています。

メトリクス

ターゲット

Comment

P95 レイテンシー

500ms 未満

ほとんどのクエリは高速です。

P99 レイテンシー

1秒未満

ロングテールクエリにおける妥当なパフォーマンス

成功率

>99.5%

低い失敗率

時間の経過に伴う待機時間

安定

テスト中に低下は確認されませんでした。

1 秒あたりのクエリー

目標を達成しています

エンドポイントは想定されるトラフィックを処理できます

以下の結果はパフォーマンスの低下を示しています。

  • P95 > 1秒。クエリがリアルタイムでの使用には遅すぎます。
  • P99 > 3秒。ロングテールクエリのレイテンシーは、ユーザー体験を損ないます。
  • 成功率 <99%。失敗が多すぎます。
  • レイテンシーが増加しています。リソースの枯渇またはメモリ リークを示します。
  • レート制限エラー(429)。より多くのエンドポイント容量が必要です。

RPSとレイテンシのトレードオフ

最大RPSは、本番運用スループットにとって最適な点ではありません。レイテンシーは、最大スループットに近づくにつれて非線形的に増加します。最大RPSで稼働する場合、最大容量の60~70%で稼働する場合と比較して、多くの場合、レイテンシーが2~5倍高くなることがよくあります。

次に、最適な動作点を見つけるために結果を分析する方法を示します。

  • 150の並列クライアントの場合、最大RPSは480です。
  • 最適な稼働点は、50 並列クライアントで 310 RPS(65% の能力)です。
  • 最大でのレイテンシーのペナルティ:P95 は 4.3 倍高くなっています(1.5秒 対 350ミリ秒)
  • この例では、エンドポイントを480 RPSの容量に設定し、約310 RPSで運用することをお勧めします。

同時実行

P50

P95

P99

RPS

成功

容量

5

80 ms

120 ms

150 ms

45

100%

10%

10

85 ms

140ms

180 ms

88

100%

20%

20

95 ms

180 ms

250 ms

165

99.8%

35%

50

150 ms

350 ms

500 ms

310

99.2%

スイートスポット:65%

100

250 ms

800 ms

1.2秒

420

97.5%

90% ⚠️ 最大値に近づいています

150

450 ms

1.5秒

2.5s

480

95.0%

100% 最大 RPS 無効

最大 RPS で動作させると、次の問題が発生することがあります:

  • レイテンシーの低下。例では、容量65%ではP95は350ミリ秒ですが、容量100%では1.5秒です。
  • トラフィックの急増に対応する余裕がありません。容量が100%の状態では、わずかなスパイクでもタイムアウトが発生します。稼働率65%の場合、トラフィックが50%急増しても問題なく処理できます。
  • エラー率が高くなっています。例では、成功率は65%の容量で99.2%ですが、100%の容量では、5%の失敗率で95.0%です。
  • リソースが枯渇する恐れがあります。最大負荷時、キューが増加し、メモリ負荷が増大し、接続プールが飽和し始め、インシデント発生後の回復時間が増加します。

以下の表に、異なるユースケースの推奨動作点を示します。

ユースケース

ターゲット容量

根拠

レイテンシーに影響を受けやすい(検索、チャット)

最大値の50~60%

低P95/P99レイテンシを優先します。

バランス(推奨)

最大値の60~70%

コストとレイテンシーの良好なバランス

コスト最適化(バッチジョブ)

最大値の70~80%

許容される高いレイテンシー

非推奨

最大値の85%超

レイテンシーの急増、バースト容量なし

動作点およびエンドポイントサイズの計算用ヘルパー関数

次のコードはQPSとP95レイテンシーをプロットします。プロットでは、曲線が急に上向きに曲がり始める点を探してください。最適な動作点です。

Python
import matplotlib.pyplot as plt

# Plot QPS vs. P95 latency
qps_values = [45, 88, 165, 310, 420, 480]
p95_latency = [120, 140, 180, 350, 800, 1500]

plt.plot(qps_values, p95_latency, marker='o')
plt.axvline(x=310, color='green', linestyle='--', label='Optimal (65% capacity)')
plt.axvline(x=480, color='red', linestyle='--', label='Maximum (100% capacity)')
plt.xlabel('Queries Per Second (QPS)')
plt.ylabel('P95 Latency (ms)')
plt.title('QPS vs. Latency: Finding the Sweet Spot')
plt.legend()
plt.grid(True)
plt.show()

埋め込みモデルのボトルネックを特定する

インデックスがマネージド埋め込みを使用している場合、ロードテストノートブックは、各クエリでdebug_level=1パラメーターを介してコンポーネントごとのタイミングをキャプチャします。結果テーブルには、以下が含まれます。

  • ann_time 近似最近傍検索に要した時間
  • embedding_gen_time — モデルサービングエンドポイントでのクエリー埋め込み生成にかかった時間
  • reranker_time 再ランク付けの所要時間(有効な場合)
  • response_time — 合計エンドツーエンド応答時間

ann_timeに比べてembedding_gen_timeが継続的に大きい場合、ボトルネックとなるのは埋め込みエンドポイントであり、AI Search エンドポイントではありません。よくある原因:

  • 埋め込みモデルサービングエンドポイントは **Scale to zero** が有効になっています。本番運用負荷テスト向けに無効にしてください。「本番運用でのゼロにスケール回避」を参照してください。
  • 埋め込みエンドポイントでは、テスト中のクエリレートに対し、プロビジョニング済み同時実行が不足しています。
  • 埋め込みモデルのエンドポイントは他のワークロードと共有されています。ロード テストには専用のエンドポイントを使用してください。
ヒント

AI検索のパフォーマンスを埋め込みモデルのパフォーマンスから分離するには、負荷テストのために セルフマネージド型埋め込み に切り替えてください。テキストクエリの代わりに、EMBEDDING_COLUMNパラメーターで事前計算済みベクトルを渡してください。これにより、埋め込みレイテンシーが測定から完全に排除されます。

ステップ 7: エンドポイントのサイズを決定する

ノートブックのおすすめを使用します

結果を分析した後、ノートブックは次の操作を求めます。

  1. 最適なレイテンシー要件を満たす行を選択してください。
  2. アプリケーションの希望するRPSを入力してください。

ノートブックはその後、推奨エンドポイントサイズを表示します。以下に基づいて必要な容量を計算します:

  • 目標RPS
  • 異なる同時実行レベルで観測されたレイテンシー
  • 成功率しきい値
  • 安全マージン (通常、想定されるピーク負荷の2倍)

スケーリングに関する考慮事項

標準エンドポイント:

  • インデックスサイズに対応するよう、自動的にスケールアップします。
  • スループットをサポートするために、手動でスケールアップしてください。
  • インデックスが削除されると、自動的にスケールダウンされます。
  • 容量を削減するには、手動でスケールダウンしてください。

ストレージ最適化エンドポイント:

  • インデックスサイズに対応するよう、自動的にスケールアップします。
  • インデックスが削除されると、自動的にスケールダウンされます。

ステップ 8: 最終構成を検証する

エンドポイント構成の更新後:

  1. エンドポイントが準備できるまでお待ちください。これには数分かかる場合があります。
  2. ノートブックで最終検証テストを実行します。
  3. 性能が要件を満たしていることを確認します:
    • RPS が目標スループット以上です
    • P95 レイテンシが SLA を満たします。
    • 成功率 > 99.5%
    • 継続的なエラーはありません。

検証に失敗した場合は、以下をお試しください。

  • エンドポイントの容量を増やします。
  • クエリー複雑性の最適化
  • フィルターパフォーマンスの確認
  • 埋め込みモデルのエンドポイントの設定を確認

再テストの時期

パフォーマンスの可視性を維持するため、四半期ごとにベースライン負荷テストを実行するのがよいでしょう。次の変更のいずれかを行った場合も:

  • クエリパターンまたは複雑さの変更
  • AI検索インデックスを更新する
  • フィルター構成を変更する
  • 大幅なトラフィックの増加が予想されます。
  • 新しい機能または最適化をデプロイ
  • 標準からストレージ最適化エンドポイントタイプへの変更

トラブルシューティング

すべてのリクエストが~10ミリ秒のレイテンシーと240バイトの応答で失敗します

これは、サービスプリンシパルが401/403応答を受信していることを示しています。認証:

  1. サービスプリンシパルは、AI検索エンドポイントに対し **クエリ実行可能** 権限を持っています(インデックスだけでなく)。
  2. シークレットスコープには、有効な service_principal_client_idservice_principal_client_secret キーが含まれています。
  3. OAuthシークレットは有効期限が切れていません。

ノートブックには、完全な負荷テストを実行する前にこれを捕捉する接続チェックが含まれています。

同じクラスターでの複数の負荷テストジョブの実行

同じクラスター上で 2 つのロード テスト ジョブを同時に実行すると、1 つのジョブが古いOAuthトークンを受け取るか、他のジョブの Locust ワーカーとの CPU 競合が発生する可能性があります。 信頼性の高い結果を得るには、負荷テストジョブを専用クラスター上で 一度に1つずつ 実行してください。

コンポーネントタイミンググラフが空です

コンポーネントのタイミンググラフ(ann_timeembedding_gen_timereranker_time)は、クエリ応答でdebug_infoを返す必要があります。これらのグラフが空の場合:

  • fast_vs_load_test_async_load.pyスクリプト(応答からdebug_infoを解析する)をlocust_script_pathとして使用していることを確認してください。
  • 一部のエンドポイント構成では、debug_infoが返されない場合があります。自己管理型のエンべディングインデックスは通常、ann_timeresponse_time を返しますが、embedding_gen_timereranker_time は返しません。

結果テーブルはSQLウェアハウスからクエリできません

ノートブックは、クラスターのSparkセッションから結果を書き込みます。ノートブックではデータが入力されていると報告しているにもかかわらず、SQLウェアハウスがテーブルに対して0行を表示している場合、問題はUnity Catalogのメタデータ同期の遅延である可能性があります。数分待って再試行してください、または、同じクラスターにアタッチされたノートブックからテーブルを直接クエリしてください。

ベストプラクティスの概要

構成をテストする

  • ピーク負荷時に少なくとも5分間テストを実行してください。

  • 認証にはOAuthサービスプリンシパルを使用してください。

  • 予想される本番運用クエリに一致する、現実的なクエリペイロードを作成します。

  • 本番運用に近いフィルターとパラメーターをテストします。

  • 測定する前にウォームアップ期間を含めてください。

  • 複数の同時実行レベルでテストしてください。

  • 平均だけでなく、P95/P99レイテンシーも追跡してください。

  • キャッシュされたパフォーマンスとキャッシュされていないパフォーマンスの両方をテストします。

    Python
    # Conservative approach: Size endpoint for UNCACHED performance
    uncached_results = run_load_test(diverse_queries, duration=600)
    endpoint_size = calculate_capacity(uncached_results, target_rps=500)

    # Then verify cached performance is even better
    cached_results = run_load_test(repetitive_queries, duration=300)
    print(f"Cached P95: {cached_results['p95']}ms (bonus performance)")

クエリセットの設計

  • テストクエリの多様性を実際のトラフィック分布(よく使用されるクエリとまれなクエリ)と一致させます。
  • ログから実際のクエリを使用します(匿名化済み)。
  • さまざまなクエリの複雑度を含めます。
  • キャッシュされたシナリオとキャッシュされていないシナリオの両方をテストし、結果を個別に追跡してください。
  • 期待されるフィルターの組み合わせでテストします。
  • 本番運用で使用するのと同じパラメーターをご使用ください。たとえば、本番運用でハイブリッド検索を使用する場合、ハイブリッド検索クエリを含めます。本番運用と同様のnum_resultsパラメーターを使用します。
  • 本番運用で発生しないクエリーは使用しないでください。

パフォーマンスの最適化

レイテンシーが高すぎる場合は、以下をお試しください。

  1. OAuth サービスプリンシパルを使用 (PAT ではなく) - 100 ms の改善
  2. num_resultsを削減:100件の結果取得は10件よりも遅い
  3. フィルターの最適化:複雑すぎたり、制限が厳しすぎるフィルターは、クエリの速度を低下させます。
  4. エンべディングエンドポイントの確認:ゼロにスケールダウンされていないか、十分な帯域幅があることを確認してください。

レート制限に達している場合は、以下をお試しください。

  1. エンドポイント容量を増やす:エンドポイントをスケールアップする
  2. クライアント側のレート制限を実装するか、クエリを時間的に分散させます。
  3. 接続プーリングによる接続の再利用
  4. 再試行ロジックを追加する - 指数関数的バックオフを使用する(Python SDK に既に含まれています)

その他のリソース

このページの見出し