10
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Amazon S3 VectorとAmazon OpenSearch Serviceの連携機能を検証する

Posted at

こんにちは!やくもです!

この記事は「2025 Japan AWS Jr. Chanpions 夏のQiitaリレー」の28日目の記事となります。
過去の投稿(リンク集)はこちらからご覧ください。

はじめに

2025年7月、AWSからS3 Vectorの発表がありました。
皆さん、S3 Vectorはもう使ってみましたでしょうか?
従来はOpenSearch Serviceを選択することが多かったですが、S3 VectorはKnowledge Baseのデータソースに設定することができ、このS3 Vectorによってコストを最大 90% 削減すると謳っています。
また、格納するベクトルデータをAmazon OpenSearch Service にエクスポートする機能もサポートされています。本記事ではベクトル最適化機能を検証していきたいと思います。

ベクトルの統合パターンを実践する

サポートされている統合パターンは以下の2種類あります。

パターン①OpenSearch Service マネージドクラスターをマネージドサービスの S3 Vectors を使用して、ベクトルストレージのコストを最適化する

パターン②S3 ベクトルインデックスから OpenSearch Serverless コレクションへのワンクリックエクスポート

パターン①では、「コストを削減したい!」というのが念頭に来るかと思います。OpenSearch Serviceはレスポンスのスピードや正確性においては、S3 Vectorよりも優れていますが、コスト面においては劣ってしまします。「頻繁に参照しなくなったデータがある。」「アーカイブ用にベクトルデータを移行したい。」といった場合には、パターン①は有効だと言えます。
また、パターン②はパターン①の逆で、「頻繁にデータを参照したくなった時」有効だといえます。OpenSearch ServiceはS3 Vectorよりも高速なクエリパフォーマンスが特徴なので、リアルタイムのレスポンスが重要なユースケースでは最適と言えます。

image.png
Optimizing vector search using Amazon S3 Vectors and Amazon OpenSearch Service

パターン①Amazon OpenSearch Service→S3 Vector

この手順を実施するには、いくつかの手順を踏む必要があります。
今回はこちらの公式のブログを参考に進めてみました。

ドメインの作成

まず、Amazon OpenSearch Serviceのドメインから作成が必要になるわけですが、この時インスタンファミリーは「OpenSearch最適化」を選択。
そうすると、「Advanced feature」の設定部分で、「Vector database features」を有効にできると思いますので、ここを有効にします。

image.png

ドメインの作成には少々時間がかかりますが、無事作成が完了したらOpenSearch ダッシュボードのURLにアクセスし、クエリを実行していきます。

その他の主な設定値は以下をご参考ください。

設定項目 設定値
エンジンオプション 2.19(最新)
インスタンスファミリー OpenSearch最適化
ネットワーク パブリックアクセス
きめ細かなアクセスコントロール 有効
マスターユーザー マスターユーザーを作成
Advanced features Vector database features にチェックを入れる
アクセスポリシー きめ細かなアクセスコントロールのみを使用

クエリ実行

実際に実行したクエリは以下の3つになります。

①OpenSearchに対して、S3 Vectorを使ったKNN対応のインデックスを作成しています。
特に、「"engine": "s3vector"」の箇所では、OpenSearch内部でベクトルデータを扱うエンジンをS3 vectorに指定しています。
S3 Vectorは名前にS3とついていることからストレージサービスと考える方も多いかもしれませんが、本質的な部分は「ベクトルを扱うエンジン」というイメージが近いです。

PUT my-first-s3vector-index
{
  "settings": {
    "index": {
      "knn": true
    }
  },
  "mappings": {
    "properties": {
        "my_vector1": {
          "type": "knn_vector",
          "dimension": 2,
          "space_type": "l2",
          "method": {
            "engine": "s3vector"
          }
        },
        "price": {
          "type": "float"
        }
    }
  }
}  

②先ほどのクエリでS3 Vectorを指定できたので、今回はデータを実際に追加しています。

POST _bulk
{ "index": { "_index": "my-first-s3vector-index", "_id": "1" } }
{ "my_vector1": [2.5, 3.5], "price": 7.1 }
{ "index": { "_index": "my-first-s3vector-index", "_id": "3" } }
{ "my_vector1": [3.5, 4.5], "price": 12.9 }
{ "index": { "_index": "my-first-s3vector-index", "_id": "4" } }
{ "my_vector1": [5.5, 6.5], "price": 1.2 }
{ "index": { "_index": "my-first-s3vector-index", "_id": "5" } }
{ "my_vector1": [4.5, 5.5], "price": 3.7 }
{ "index": { "_index": "my-first-s3vector-index", "_id": "6" } }
{ "my_vector1": [1.5, 2.5], "price": 12.2 }

③このクエリでは実際にOpenSearchに対してベクトル検索を実行しています。
ちなみに、S3 Vectorで削減されるのはベクトルのアーカイブのコストで、今回のようにクエリを実行する際のコストはOpenSearchのコストが適用されています。

GET my-first-s3vector-index/_search
{
  "size": 2,
  "query": {
    "knn": {
      "my_vector1": {
        "vector": [2.5, 3.5],
        "k": 2
      }
    }
  }
}

レスポンスを確認したところ、クエリは正常に終了していることが確認できます。
5件中、検索にヒットしたデータが2件あることがわかります。

{
  "took": 331,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 5,
      "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "my-first-s3vector-index",
        "_id": "1",
        "_score": 1,
        "_source": {
          "my_vector1": [
            2.5,
            3.5
          ],
          "price": 7.1
        }
      },
      {
        "_index": "my-first-s3vector-index",
        "_id": "3",
        "_score": 0.33333334,
        "_source": {
          "my_vector1": [
            3.5,
            4.5
          ],
          "price": 12.9
        }
      }
    ]
  }
}

このように、Amazon OpneSearch Service上ではありますが、ベクトルデータをS3 Vectorの保存することで、コスト効率のいいデータセットの実現ができました。

パターン②S3 Vector→Amazon OpenSearch Service

S3 VectorからAmazon OpenSearch Serviceへのエクスポートはマネージメントコンソール上からワンクリックで実行できます。
①Amazon OpenSearch Serviceへの移行対象のベクトルインデックスを開き、右上の「OpenSearchにエクスポート」を選択します
image.png

②以下のような画面になるので、そのまま下にスクロールして、Exportを選択
image.png

image.png

上記のエクスポート押下後、ステータスが完了になることを確認します。
ステータスが完了になったら、S3 VectorのデータはAmazon OpenSearch Serviceにエクスポートできたはずです。
image.png

実際に確認してみます。
新しく取り込んだコレクションのOpenSearch ダッシュボード URLをクリックします。
その後、右上のDev Toolsをクリックすると、デフォルトでGETが実行できると思います。
こちら実施し、実際に取り込んだベクトルデータが確認できれば、正常にエクスポートできているかと思います。
image.png

性能の比較

さて、ここで二種類のベクトルデータができたわけですが、簡単に比較していきたいと思います。

指標 S3 Vector OpenSearch
コスト  約0.023USD/GB・月 インスタンスに依存(月数10ドル~) 
レスポンス速度  数100ms~数秒 数10ms~
スケーラビリティ  S3のためほぼ無制限 インスタンスサイズ依存
ベクトル更新頻度 再インデックスが必要  即時書込・削除が可能

使い分けのポイント

低コストでシンプルに始めたい。
→S3 Vector

高速・リアルタイムな応答を重視する
→OpenSearch

といった感じになるのかなと思います。手軽にサクッとRAGを試したいよ、というときはS3 Vectorでもいい気はしますね。

考察

「S3 Vector」は、単なるストレージではなく、ベクトルを扱うものなんだと再認識するとともに、多くの方に知ってほしいサービスです。
ベクトルの最適化も実際に試してみましたが、パターン②では、ワンクリックで進むだけで簡単にデータの移行が進み便利だなと思う一方、パターン①は中々面倒だなと思ってしまいました。確かにレスポンス上ではS3 Vectorをエンジンとしてベクトルデータを保存できているわけですから、コストの削減にはつながっていると思います。
ですがいかんせん見づらい....
このOpenSearchのデータをS3等にエクスポートする手順までは今回実施できなかったので、今後機会があれば試していきたいと思います。
とはいえ、OpenSearch上のデータのコストを大幅に削減できるオプションとしてはかなり有効ではあると思うので、頭に入れておいて損はないと思います!

10
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?