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

ベクトル検索エンドポイントの負荷テストを構成する

このページでは、負荷テストの連続検索エンドポイントのためのガイダンス、サンプル コード、およびサンプル ノートブックを提供します。 負荷テストは、本番運用にデプロイする前に、一斉検索エンドポイントのパフォーマンスと本番運用の準備状況を理解するのに役立ちます。 負荷テストでは次のことがわかります。

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

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

要件

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

次のファイルとサンプルノートブックのコピーをダウンロードして、Databricks ワークスペースにインポートします。

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

サンプルノートブックとクイックスタート

まずは以下のサンプルノートブックを使って始めてみてください。このツールは2つの探索モードをサポートしています。1つは、ユーザーが定義した特定の同時実行レベルをテストする段階的な探索モード、もう1つは、数ステップで持続可能な最大QPS(限界点)を自動的に見つけるバイナリサーチモードです。すべての問題はウィジェットを使用して構成されているため、ノートブックはコードを編集せずに対話的に、またはDatabricksジョブとして実行できます。

Locust 負荷テストノートブック

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

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

Locust は、次のことを可能にするオープンソースの負荷テスト フレームワークです。

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

サンプルノートブックは、 --processes -1フラグを使用して CPU コアを自動検出し、それらを完全に利用します。

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

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

重要

本番運用のようなパフォーマンス テストの場合は、常にOAuthサービス プリンシパル認証を使用してください。 サービスシプリンパルは、パーソナル アクセス オンライン (PAT) と比較して、最大 100 ミリ秒速い応答時間と高い要求レート制限を提供します。

サービスプリンシパルの作成と構成

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

  2. 権限を付与する:

    • 「検索」エンドポイント ページに移動します。
    • [ アクセス許可 ]をクリックします。
    • サービスプリンシパル 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

あなたの検索エンドポイントの名前

エンドポイント名

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自動的にブレークポイントを見つけます(ブレークポイントの探索を参照)。

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. クエリセットを設計する

可能であれば、クエリ セットは、予想される本番運用トラフィックをできるだけ正確に反映する必要があります。 具体的には、コンテンツ、複雑さ、多様性の観点から、クエリの予想される分布に一致するようにする必要があります。

  • 現実的なクエリを使用します。「テスト クエリ 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
    }

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

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

使用:

いつ:

同一または少数のクエリ

  • 本番運用トラフィックにクエリの繰り返しが多い (例: 「人気の製品」)

  • キャッシュの有効性を具体的にテストしている

  • アプリケーションはキャッシュの恩恵を受けます(例えば、固定クエリを持つダッシュボード)

  • キャッシュされたパフォーマンスのベストケースを測定したい

「トレンドアイテム」を表示する製品推奨ウィジェット - 同じクエリが 1 時間あたり数千回実行されます。

多様なクエリ

  • 本番運用トラフィックには固有のユーザー クエリ (検索エンジンやチャットボットなど) が含まれています

  • 最悪の場合のキャッシュされていないパフォーマンスを測定したい

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

  • クエリのカーディナリティが高い(何百万通りものバリエーションが考えられます)

ユーザーごとに異なる製品検索を入力する電子商取引検索。

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

クエリセットを作成するためのオプション

コード タブには、多様なクエリ セットを作成するための 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ワークスペースで、地下鉄検索エンドポイントに移動します。
  2. 左側のサイドバーで、 [サービング] をクリックします。
  3. エンドポイントを選択します。
  4. [使用][クエリ] をクリックします。
  5. input.jsonのコンテンツをクエリ ボックスに貼り付けます。
  6. エンドポイントが期待どおりの結果を返すことを確認します。

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

ステップ 5. 負荷テストを実行する

接続確認とウォームアップ

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

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

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

主な負荷試験シリーズ

ノートブックは、クライアントの同時実行性を高めながら一連のテストを実行します。

  • 開始: 同時実行性が低い (たとえば、5 台のクライアント)
  • 中: 中程度の同時実行性 (たとえば、10、20、または 50 クライアント)
  • 終了: 高い同時実行性 (たとえば、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 レイテンシ

< 500ミリ秒

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

P99レイテンシ

< 1秒

ロングテールクエリでの適切なパフォーマンス

成功率

> 99.5%

低い故障率

時間の経過に伴うレイテンシ

安定した

試験中に劣化は観察されなかった

1 秒あたりのクエリー

目標を達成

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

次の結果はパフォーマンスが低いことを示しています。

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

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

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

次の例は、結果を分析して最適な動作点を見つける方法を示しています。

  • 最大 RPS は、150 並列クライアントで 480 です。
  • 最適な動作点は、50 並列クライアント (65% の容量) で 310 RPS です。
  • 最大P95でのレイテンシペナルティは4.3倍(1.5秒対350ミリ秒)
  • この例では、エンドポイントを 480 RPS の容量に合わせてサイズ設定し、約 310 RPS で動作させることが推奨されます。

同時実行

P50

P95

P99

RPS

成功

容量

5

80ミリ秒

120ミリ秒

150ミリ秒

45

100%

10%

10

85ミリ秒

140ミリ秒

180ミリ秒

88

100%

20%

20

95ミリ秒

180ミリ秒

250ミリ秒

165

99.8%

35%

50

150ミリ秒

350ミリ秒

500ミリ秒

310

99.2%

65% ← スイートスポット

100

250ミリ秒

800ミリ秒

1.2秒

420

97.5%

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

150

450ミリ秒

1.5秒

2.5秒

480

95.0%

100% ❌ 最大RPS

最大 RPS で動作すると、次の問題が発生する可能性があります。

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

次の表は、さまざまなユースケースに推奨される動作ポイントを示しています。

ユースケース

目標容量

根拠

遅延に敏感(検索、チャット)

最大の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 — エンドツーエンドの合計応答時間

embedding_gen_time ann_timeに比べて一貫して大きい場合、ボトルネックとなるのはベクトル検索エンドポイントではなく、埋め込みエンドポイントです。一般的な原因:

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

ベクトル検索のパフォーマンスを埋め込みモデルのパフォーマンスから分離するには、負荷テスト用に 自己管理型の埋め込み に切り替えます。テキスト クエリの代わりに、事前計算されたベクトルをEMBEDDING_COLUMNで渡します。 これにより、測定から埋め込み遅延が完全に除去されます。

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

ノートブックの推奨事項を使用する

結果を分析した後、ノートブックは次のことを要求します。

  1. レイテンシ要件に最も適した行を選択します。
  2. アプリケーションの希望する RPS を入力します。

ノートブックには推奨されるエンドポイント サイズが表示されます。必要な容量は、以下に基づいて計算されます。

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

スケーリングの考慮事項

標準エンドポイント:

  • インデックスサイズをサポートするために自動的にスケールアップ
  • スループットをサポートするために手動でスケールアップする
  • インデックスが削除されると自動的にスケールダウンする
  • 手動でスケールダウンして容量を減らす

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

  • インデックスサイズをサポートするために自動的にスケールアップ
  • インデックスが削除されると自動的にスケールダウンする

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

エンドポイント構成を更新した後:

  1. エンドポイントの準備が整うまで待ちます。これには数分かかる場合があります。
  2. ノートブックで最終検証テストを実行します。
  3. パフォーマンスが要件を満たしていることを確認します。
    • RPS ≥ 目標スループット
    • P95レイテンシはSLAを満たす
    • 成功率 > 99.5%
    • 持続的なエラーなし

検証に失敗した場合は、次の操作を試してください。

  • エンドポイント容量の増加
  • クエリの複雑さを最適化する
  • フィルターのパフォーマンスを確認する
  • 埋め込みエンドポイントの構成を確認する

再テストのタイミング

パフォーマンスの可視性を維持するために、ベースライン負荷テストを四半期ごとに実行することをお勧めします。次のいずれかの変更を行った場合も、再テストを行う必要があります。

  • クエリパターンまたは複雑さを変更する
  • ベクトル検索インデックスを更新する
  • フィルタ設定を変更する
  • 大幅なトラフィック増加が見込まれる
  • 新機能や最適化を導入する
  • 標準エンドポイントタイプからストレージ最適化エンドポイントタイプへの変更

トラブルシューティング

すべてのリクエストは、約10ミリ秒の遅延と240バイトの応答で失敗します。

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

  1. サービスプリンシパルは、ベクトル検索エンドポイント(インデックスだけでなく)に対して クエリ実行 権限を持っています。
  2. シークレットスコープには有効なservice_principal_client_idキーとservice_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 ミリ秒の改善
  2. num_resultsを減らす - 100 件の結果を取得するのは 10 件よりも遅い
  3. フィルターの最適化 - 複雑または過度に制限的なフィルターはクエリの速度を低下させます
  4. 埋め込みエンドポイントを確認する - ゼロにスケールされていないか、十分な帯域幅があるか確認する

レート制限に達した場合は、次の操作を試してください。

  1. エンドポイントの容量を増やす - エンドポイントをスケールアップする
  2. クライアント側のレート制限や時間内でのクエリ分散を実装する
  3. 接続プールを使用する - 接続を再利用する
  4. 再試行ロジックを追加 - 指数バックオフを使用する (すでに Python SDK の一部)

その他のリソース