Amazon Web Services ブログ

Amazon S3 Select を使用して、サーバーまたはデータベースなしでデータをクエリする

AWS のソリューションアーキテクトとして、すべてのタイプの顧客とユースケースをサポートしてきました。私たちは定期的に同じフィードバックを受け取っています。システムとインフラストラクチャをデプロイして管理する代わりに、顧客は複雑さと管理オーバーヘッドを削減して、コアビジネスに集中したいと考えています。大量のデータから必要なものを効率的に検索することは難しいため、複雑さとオーバーヘッドが生じます。

この記事では、構造化クエリ言語 (SQL) クエリを使用して、コンマ区切り値 (CSV) ファイルとして Amazon Simple Storage Service (Amazon S3) にロードされたデータを検索します。以前は、データをクエリするにはデータベースにロードする必要がありました。データベースのデプロイに加えて、顧客は検索を有効にするためにアプリケーションとウェブサイトをデプロイする必要があります。データベースと関連リソースをデプロイする代わりに、S3 Select と呼ばれる S3 機能を利用して、完全にサーバーレスな電話帳検索ツールを作成します。

最初に、シンプルな電話帳の .csv ファイルから結果を返す SQL クエリの基本的な実行を示します。このソリューションをもう少し詳しく調べるために、完全なサーバーレス電話帳検索アプリケーションの作成に必要なすべてのコンポーネントを含め、サンプルの電話帳検索ツールを AWS Examples GitHub ページで作成します。

顧客は Amazon S3 を使用して、ストレージのプロビジョニングやインフラストラクチャの管理を行うことなく、あらゆる量のデータを保存して保護します。Amazon S3 Select と Amazon S3 Glacier Select を使用すると、S3 と Amazon S3 Glacier に保存されているデータに対して構造化クエリ言語 SQL クエリを直接実行できます。S3 Select を使用すると、データを簡単に S3 に保存し、SQL ステートメントを使用して S3 オブジェクトのコンテンツをフィルタリングし、必要なデータのみを取得するクエリを実行できます。データのサブセットのみを取得することで、顧客は Amazon S3 が転送するデータ量を削減し、このデータを取得するコストとレイテンシーを削減します。コストと複雑さを削減することで、AWS の顧客はより迅速に移行し、ビジネスと顧客に価値を提供するために必要な時間を短縮できます。

S3 Select は、CSV、JSON、または Apache Parquet 形式で保存されたオブジェクトで機能します。S3 Select は、GZIP または BZIP2 を使用した CSV および JSON オブジェクト、サーバー側暗号化オブジェクトの圧縮もサポートしています。AWS SDK、SELECT Object Content REST API、AWS コマンドラインインターフェイス (AWS CLI)、または AWS マネジメントコンソールを使用して SQL クエリを実行できます。

注目の AWS サービス

シンプルな電話帳アプリケーションは、次の AWS サービスを利用します。

  • Amazon S3 は、業界をリードするスケーラビリティ、データの可用性、セキュリティ、およびパフォーマンスを提供するオブジェクトストレージサービスです。
  • S3 Select は、単純な SQL 式を使用して、アプリケーションが S3 オブジェクトからデータのサブセットのみを取得できるようにします。

S3 と S3 Select に加えて、Amazon S3 Select – Phonebook Search GitHub サンプルプロジェクトには次のサービスが含まれています。

  • Amazon API Gateway は、開発者があらゆる規模の API を簡単に作成、公開、保守、監視、保護できるようにするフルマネージド型サービスです。Amazon API Gateway はサーバーレスアプリケーションの一般的なコンポーネントであり、AWS Lambda との相互作用に使用されます。
  • AWS Lambda は、サーバーをプロビジョニングまたは管理せずにコードを実行できます。サンプルプロジェクトの S3 Select クエリは、AWS Lambda で実行されます。
  • AWS CloudFormation は、クラウド環境で AWS およびサードパーティーのアプリケーションリソースをモデル化してプロビジョニングするための共通言語を提供します。サンプルアプリに CloudFormation を使用して、最小限の労力でサンプルプロジェクトに必要なリソースのデプロイメントを調整します。

サンプルコード

このプロジェクトのサンプルコードは AWS Samples GitHub リポジトリにあります。詳細の概要は以下に示します。

開始方法

S3 Select は S3 バケットに保存されたデータを使用して S3 で直接実行されるため、開始する必要があるのは AWS アカウントと S3 バケットのみです。

既存の AWS アカウントにサインインするか、新しい AWS アカウントを作成します。サインインしたら、S3 Select でのテストに使用する S3 バケットを作成します。

テストに使用するデータは、ユーザーの名前、電話番号、市区町村、職業を含む単純な CSV ファイルです。CSV ファイルの未加工データは以下にある GitHub から利用可能です。ファイルをダウンロードして編集することもできます。

Name,PhoneNumber,City,Occupation
Sam,(949) 555-6701,Irvine,Solutions Architect
Vinod,(949) 555-6702,Los Angeles,Solutions Architect
Jeff,(949) 555-6703,Seattle,AWS Evangelist
Jane,(949) 555-6704,Chicago,Developer
Sean,(949) 555-6705,Chicago,Developer
Mary,(949) 555-6706,Chicago,Developer
Kate,(949) 555-6707,Chicago,Developer

sample_data.csv ファイルを新しい S3 バケットにアップロードします。

すばやくテストするために、次の Python を実行します。これは、「s3select-demo」という名前の S3 バケットにある「sample_data.csv」オブジェクトをクエリします。 作成したバケットの名前を反映するように、バケット名を変更する必要があります。

この簡単なテストをセットアップするには、EC2 インスタンス Amazon Linux 2 を実行する t3.micro をデプロイし、pip コマンドを使用して boto3 をインストールします。適切なアクセス許可で IAM ロールを使用してください。

S3 Select クエリを実行するための EC2 インスタンスの設定

インスタンスが実行されたら、ec2-user としてログインし、次のコマンドを実行して環境をセットアップします。

sudo yum update -y
sudo yum install python3 -y
python3 -m venv ~/s3select_example/env
source ~/s3select_example/env/bin/activate
pip install pip --upgrade
pip install boto3
wget https://raw.githubusercontent.com/aws-samples/s3-select-phonebook-search/master/src/samples/jane.py
wget https://raw.githubusercontent.com/aws-samples/s3-select-phonebook-search/master/src/samples/jane-gzip.py

上記の手順では、python3 環境を作成し、次の内容から jane.py という Python ファイルをダウンロードします。このファイルを使用すると、名前が Jane であるユーザーを検索できます。S3 バケットに一致するように、現在の S3 バケット名を置き換える必要があります。

import boto3

s3 = boto3.client('s3')

resp = s3.select_object_content(
    Bucket='s3select-demo',
    Key='sample_data.csv',
    ExpressionType='SQL',
    Expression="SELECT * FROM s3object s where s.\"Name\" = 'Jane'",
    InputSerialization = {'CSV': {"FileHeaderInfo": "Use"}, 'CompressionType': 'NONE'},
    OutputSerialization = {'CSV': {}},
)

for event in resp['Payload']:
    if 'Records' in event:
        records = event['Records']['Payload'].decode('utf-8')
        print(records)
    elif 'Stats' in event:
        statsDetails = event['Stats']['Details']
        print("Stats details bytesScanned: ")
        print(statsDetails['BytesScanned'])
        print("Stats details bytesProcessed: ")
        print(statsDetails['BytesProcessed'])
        print("Stats details bytesReturned: ")
        print(statsDetails['BytesReturned'])

OutputSerialization フィールドは CSV に設定されているため、「Jane」に一致する結果が CSV として出力されます。ユースケースに適している場合、JSON に設定できます。

S3 Select クエリの実行

jane.py ファイルの S3 バケット名を、作成した S3 バケット名と一致するように変更した後、次のコマンドを使用してクエリを実行します。

python jane.py

以下の出力が得られます。

Jane,(949) 555-6704,Chicago,Developer

Stats details bytesScanned:
326
Stats details bytesProcessed:
326
Stats details BytesReturned:
38

ユーザーが Jane の一致結果と、S3 Select がスキャン、処理し、返したデータを表示するために追加したオプションの詳細も表示されます。この場合、sample_data.csv は 326 バイトです。S3 Select はファイル全体をスキャンし、38 バイトのみを返します。

圧縮データを使用する S3 Select

同じテストをもう一度実行してみましょう。今回は、sample_data.csv.gz として保存された電話帳の GZIP バージョンを圧縮してアップロードした後です。このファイルは、GitHub からダウンロード可能です。

Python コードの変更とは、キーを gzip オブジェクトに変更し、InputSerialization CompressionType を [なし] から [GZIP] に変更することです。Python スクリプトの新しいバージョンは jane-gzip.py として保存され、AWS Samples GitHub ページでも利用できます。

オブジェクトキー名を変更して、gzip ファイルを指定しました。

Key='sample_data.csv.gz',

また、InputSerialization 行を変更して、CompressionType を GZIP に変更しました。

InputSerialization = {'CSV': {"FileHeaderInfo": "Use"}, 'CompressionType': 'GZIP'},

jane-gzip.py の全体ファイルは以下にあります。S3 バケットの名前と一致するように、現在の S3 バケット名を置き換える必要があります。

import boto3

s3 = boto3.client('s3')

resp = s3.select_object_content(
    Bucket='s3select-demo',
    Key='sample_data.csv.gz',
    ExpressionType='SQL',
    Expression="SELECT * FROM s3object s where s.\"Name\" = 'Jane'",
    InputSerialization = {'CSV': {"FileHeaderInfo": "Use"}, 'CompressionType': 'GZIP'},
    OutputSerialization = {'CSV': {}},
)

for event in resp['Payload']:
    if 'Records' in event:
        records = event['Records']['Payload'].decode('utf-8')
        print(records)
    elif 'Stats' in event:
        statsDetails = event['Stats']['Details']
        print("Stats details bytesScanned: ")
        print(statsDetails['BytesScanned'])
        print("Stats details bytesProcessed: ")
        print(statsDetails['BytesProcessed'])
        print("Stats details bytesReturned: ")
        print(statsDetails['BytesReturned'])

次のコマンドは、gzip ファイルで S3 Select クエリを実行します。

python jane-gzip.py

以下の出力が得られます。

Jane,(949) 555-6704,Chicago,Developer

Stats details bytesScanned:
199
Stats details bytesProcessed:
326
Stats details bytesReturned:
38

圧縮データと非圧縮データの結果比較

gzip で圧縮すると、S3 のスペースを節約でき、データプロセスの量が削減されます。このテスト用の小さな csv ファイルの場合、圧縮すると 39% のスペースが節約されます。

次の表は、2 つのファイル、sample_data.csv と sample_data.csv.gz の間で S3 Select を実行するという違いを示しています。

ファイルサイズ (バイト) スキャンされたバイト数 処理されたバイト数 返されたバイト数
未圧縮 326 326 326 38 該当なし
圧縮 199 199 326 38 ~39% 縮小

データ圧縮を利用して、最大 1,000,000 行で構成される 133,975,755 バイトの CSV ファイル (〜128 MB) のように、大きなファイルでより興味深い結果を得られます。このようなファイルのテストでは、GZIP 圧縮でファイルサイズが最大 60% 削減され、50,308,104 バイト (~50.3 MB) になりました。

ファイルサイズ (バイト) スキャンされたバイト数 処理されたバイト数 返されたバイト数
未圧縮 133,975,755 133,975,755 133,975,755 6 該当なし
圧縮 50,308,104 50,308,104 133,975,755 6 ~60% 縮小

S3 Glacier Select を使用したアーカイブのクエリ

S3 Glacier アーカイブオブジェクトに SQL クエリを提供すると、S3 Glacier Select はクエリを所定の場所で実行し、出力結果を Amazon S3 に書き込みます。S3 Glacier Select を使用すると、S3 Standard など、よりホットな層にデータを復元することなく、S3 Glacier に保存されているデータに対してクエリとカスタム分析を実行できます。

選択クエリを実行すると、S3 Glacier は 3 つのデータアクセス層 (優先標準一括) を提供します。これらの層はすべて異なるデータアクセス時間とコストを提供します。これにより、データをどれだけ早く利用できるかに応じて、いずれかを選択できます。最大サイズのアーカイブ (250 MB 以上) を除くすべての場合、優先層を使用してアクセスされるデータは、通常 1〜5 分以内に利用可能になります。標準層は 3〜5 時間以内に終了します。一括取得は 5〜12 時間以内に終了します。

まとめ

この記事では、S3 Select が Amazon S3 または Amazon S3 Glacier に保存されたデータに対して SQL クエリを直接かつ簡単に実行する方法を示しました。S3 Select は S3 に保存されたデータに対して実行できます。顧客はこの機能を使用して S3 にアップロードされたデータをプログラムで、または AWS Transfer for SFTP (AWS SFTP) などのサービスから処理できます。たとえば、顧客は AWS SFTP を使用してデータを S3 に直接アップロードし、S3 Select を使用してデータをクエリできます。この作業は、S3 イベント通知で新しい CSV オブジェクトが S3 にアップロードされた後、AWS Lambda の実行によって自動的にトリガーできます。S3 Select を使用してデータを検索すると、他の方法でデータをコーミングする際に費やす時間とお金を節約できる可能性があります。

S3 Select をさらに実践で利用するには、AWS Samples GitHub リポジトリにアクセスすることをお勧めします。簡単な電話帳アプリケーションのサンプルコードを見つけられたので、S3 Select を使ってより多くの時間を得ることができます。GitHub リポジトリは、Amazon API Gateway によって開始される AWS Lambda にコマンドをオフロードします。

クリーンアップ

サンプルでは、S3 バケットを作成し、.csv ファイル (sample_data.csv) をアップロードし、t3.micro EC2 インスタンスを使用してデータをクエリしました。環境をクリーンアップするには、EC2 インスタンスをシャットダウンして終了し、S3 バケットから sample_data.csv ファイルを削除します。テストに使用した S3 バケットを削除することもできます。これらの手順により、このサンプルのアカウントに対する今後のコストが発生しないことが保証されます。

その他のリソース