

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# AWS Lambda 関数で Python を使用して S3 オブジェクトの並列読み取りを実行する
<a name="run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function"></a>

*Eduardo Bortoluzzi、Amazon Web Services*

## 概要
<a name="run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function-summary"></a>

このパターンを使用して、Amazon Simple Storage Service (Amazon S3) バケットからドキュメントのリストをリアルタイムで取得して要約できます。このパターンは、Amazon Web Services (AWS) の S3 バケットからオブジェクトを並列に読み取るためのサンプルコードを提供します。このパターンは、Python を使用して AWS Lambda 関数で I/O バインドタスクを効率的に実行する方法を示しています。

ある金融会社は、このパターンをインタラクティブなソリューションで使用して、相関する金融取引をリアルタイムで手動で承認または拒否しました。金融取引ドキュメントを市場に関連する S3 バケットに保存しました。オペレーターは S3 バケットからドキュメントのリストを選択し、ソリューションが計算した取引の合計値を分析して、選択したバッチを承認または拒否することを決定しました。

I/O にバインドされたタスクは複数のスレッドをサポートします。このサンプルコードでは、Lambda 関数が最大 1,024 スレッドをサポートしている場合でも、[concurrent.futures.ThreadPoolExecutor](https://docs.python.org/3.13/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor) は最大 30 の同時スレッドで使用されます (これらのスレッドの 1 つがメインプロセスです)。この制限があるのは、スレッドが多すぎると、コンテキストの切り替えとコンピューティングリソースの使用率が原因でレイテンシーの問題が発生するためです。また、すべてのスレッドが S3 オブジェクトのダウンロードを同時に実行できるように、`botocore` でプールの最大接続数を増やす必要があります。

サンプルコードは、S3 バケット内で JSON データとともに 8.3 KB オブジェクトを 1 つ使用します。オブジェクトは複数回読み込まれます。Lambda 関数がオブジェクトを読み取ると、JSON データは Python オブジェクトにデコードされます。2024 年 12 月、この例を実行した後の結果は、2,304 MB のメモリで設定された Lambda 関数を使用して 2.3 秒で 1,000 回の読み込みを処理し、27 秒で 10,000 回の読み込みを処理しました。 は、128 MB から 10,240 MB (10 GB) のメモリ設定 AWS Lambda をサポートしますが、Lambdamemory を 2,304 MB を超えて増やすと、この特定の I/O バウンドタスクの実行時間を短縮することはできませんでした。

[AWS Lambda Power Tuning](https://github.com/alexcasalboni/aws-lambda-power-tuning) ツールを使用して、さまざまな Lambda メモリ設定をテストし、タスクの最適な費用対効果の比率を検証しました。詳細については、「[追加リソース](#run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function-additional)」のセクションを参照してください。

## 前提条件と制限事項
<a name="run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function-prereqs"></a>

**前提条件**
+ アクティブな AWS アカウント
+ Python 開発の習熟度

**制限事項**
+ Lambda 関数は、最大 [1,024 の実行プロセスまたはスレッド](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html#function-configuration-deployment-and-execution)を持つことができます。
+ 新しい AWS アカウント の Lambda メモリ制限は 3,008 MB です。それに応じて AWS Lambda Power Tuning ツールを調整します。詳細については、「[トラブルシューティング](#run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function-troubleshooting)」セクションを参照してください。
+ Amazon S3 には、[パーティション化されたプレフィックスごとに 1 秒あたり 5,500 件の GET/HEAD リクエスト](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html)の制限があります。

**製品バージョン**
+ Python 3.9 以降
+ AWS Cloud Development Kit (AWS CDK) v2
+ AWS Command Line Interface (AWS CLI) バージョン 2
+ AWS Lambda Power Tuning 4.3.6 (オプション)

## アーキテクチャ
<a name="run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function-architecture"></a>

**ターゲットテクノロジースタック**
+ AWS Lambda
+ Amazon S3
+ AWS Step Functions ( AWS Lambda Power Tuning がデプロイされている場合)

**ターゲットアーキテクチャ**

次の図は、S3 バケットからオブジェクトを並行して読み取る Lambda 関数を示しています。この図には、Lambda 関数メモリを微調整するための AWS Lambda Power Tuning ツール用の Step Functions ワークフローもあります。このファインチューニングは、コストとパフォーマンスのバランスをとるのに役立ちます。

![\[Lambda 関数、S3 バケット、AWS Step Functions を示す図。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/b46e9b16-9842-4291-adfa-3ef012b89aec/images/828696e2-6df7-4536-9205-951c99449f4e.png)


**自動化とスケール**

Lambda 関数は、必要に応じて迅速にスケールします。需要が高いときに Amazon S3 から 503 Slow Down エラーを受信しないように、スケーリングにいくつかの制限を設定することをお勧めします。

## ツール
<a name="run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function-tools"></a>

**AWS サービス**
+ [AWS Cloud Development Kit (AWS CDK) v2](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) は、コードで AWS クラウド インフラストラクチャを定義してプロビジョニングするのに役立つソフトウェア開発フレームワークです。デプロイするインフラストラクチャの例が作成されました AWS CDK。
+ [AWS Command Line InterfaceAWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) は、コマンドラインシェルのコマンド AWS のサービス を使用して を操作するのに役立つオープンソースツールです。このパターンでは、 AWS CLI バージョン 2 を使用してサンプル JSON ファイルをアップロードします。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) は、サーバーのプロビジョニングや管理を行うことなくコードを実行できるコンピューティングサービスです。必要に応じてコードを実行し、自動的にスケーリングするため、課金は実際に使用したコンピューティング時間に対してのみ発生します。
+ [Amazon Simple Storage Service Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html) は、どのようなデータ量であっても、データを保存、保護、取得することを支援するクラウドベースのオブジェクトストレージサービスです。
+ [AWS Step Functions](https://docs.aws.amazon.com/step-functions/latest/dg/welcome.html) は、 AWS Lambda 関数と他の AWS のサービスを組み合わせてビジネスクリティカルなアプリケーションを構築するのに役立つサーバーレスオーケストレーションサービスです。

**その他のツール**
+ 「[Python](https://www.python.org/)」は汎用のコンピュータープログラミング言語です。[アイドルワーカースレッドの再利用](https://docs.python.org/3.8/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor)は Python バージョン 3.8 で導入され、このパターンの Lambda 関数コードは Python バージョン 3.9 以降用に作成されました。

**コードリポジトリ**

このパターンのコードは、「[aws-lambda-parallel-download](https://github.com/aws-samples/aws-lambda-parallel-download)」GitHub リポジトリで利用できます。

## ベストプラクティス
<a name="run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function-best-practices"></a>
+ この AWS CDK コンストラクトは、インフラストラクチャをデプロイするための AWS アカウントユーザーのアクセス許可に依存します。 AWS CDK Pipelines またはクロスアカウントデプロイを使用する場合は、[「スタックシンセサイザー](https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html#bootstrapping-synthesizers)」を参照してください。
+ このサンプルアプリケーションでは、S3 バケットでアクセスログが有効になっていません。本番コードでアクセスログを有効にするのがベストプラクティスです。

## エピック
<a name="run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function-epics"></a>

### 開発環境を準備する
<a name="prepare-the-development-environment"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Python がインストールされているバージョンを確認します。 | このコードは Python 3.9 と Python 3.13 で特別にテストされており、これらのリリース間のすべてのバージョンで動作するはずです。Python のバージョンを確認するには、ターミナルで `python3 -V` を実行し、必要に応じて新しいバージョンをインストールします。必要なモジュールがインストールされていることを確認するには、`python3 -c "import pip, venv"` を実行します。エラーメッセージが表示されない場合は、モジュールが正しくインストールされ、このサンプルを実行する準備ができていることを意味します。 | クラウドアーキテクト | 
| をインストールします AWS CDK。 | まだインストール AWS CDK されていない場合は、[「 の開始方法 AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html)」の手順に従ってください。インストールされている AWS CDK バージョンが 2.0 以降であることを確認するには、 を実行します`cdk –version`。 | クラウドアーキテクト | 
|  環境 をブートストラップします。 | まだブートストラップされていない場合、環境をブートストラップするには、「[AWS CDKで使用する環境をブートストラップする](https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping-env.html)」の手順に従ってください。 | クラウドアーキテクト | 

### サンプルリポジトリのクローンを作成する
<a name="clone-the-example-repository"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| リポジトリのクローン作成 | 最新バージョンのリポジトリのクローンを作成するには、次のコマンドを実行します。<pre>git clone --depth 1 --branch v1.2.0 \<br />git@github.com:aws-samples/aws-lambda-parallel-download.git</pre> | クラウドアーキテクト | 
| 作業ディレクトリをクローニングされたリポジトリに変更します。 | 次のコマンドを実行します。<pre>cd aws-lambda-parallel-download</pre> | クラウドアーキテクト | 
| Python 仮想環境を作成します。 | Python 仮想環境を作成するには、次のコマンドを実行します。<pre>python3 -m venv .venv</pre> | クラウドアーキテクト | 
| 仮想環境をアクティブ化します。 | 仮想環境を有効にするには、次のコマンドを実行します。<pre>source .venv/bin/activate</pre> | クラウドアーキテクト | 
| SDK の依存関係をインストールします。 | Python 依存関係をインストールするには、`pip` コマンドを実行します。<pre>pip install -r requirements.txt</pre> | クラウドアーキテクト | 
| コードを参照します。 | (オプション) S3 バケットからオブジェクトをダウンロードするサンプルコードは、`resources/parallel.py` にあります。インフラストラクチャコードは `parallel_download` フォルダにあります。 | クラウドアーキテクト | 

### アプリをデプロイしてテストする
<a name="deploy-and-test-the-app"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| アプリケーションをデプロイします。 | `cdk deploy` を実行します。 AWS CDK 出力を書き留めます。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function.html) | クラウドアーキテクト | 
| サンプル JSON ファイルをアップロードします。 | リポジトリには、約 9 KB のサンプル JSON ファイルが含まれています。作成したスタックの S3 バケットにファイルをアップロードするには、次のコマンドを実行します。<pre>aws s3 cp sample.json s3://<ParallelDownloadStack.SampleS3BucketName></pre>を AWS CDK 出力の対応する値`<ParallelDownloadStack.SampleS3BucketName>`に置き換えます。 | クラウドアーキテクト | 
| アプリを実行します。 | アプリを実行するには、次の手順を実行します。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function.html) | クラウドアーキテクト | 
| ダウンロード数を追加します。 | (オプション) 1,500 の GET オブジェクト呼び出しを実行するには、`Test` パラメータの**イベント JSON** で次の JSON を使用します。<pre>{"repeat": 1500, "objectKey": "sample.json"}</pre> | クラウドアーキテクト | 

### オプション: AWS Lambda 電源調整を実行する
<a name="optional-run-lamlong-power-tuning"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
|  AWS Lambda Power Tuning ツールを実行します。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function.html)実行の最後に、**[実行の入力と出力]** タブに結果が表示されます。 | クラウドアーキテクト | 
|  AWS Lambda パワーチューニングの結果をグラフで表示します。 | **[実行の入力と出力]** タブで、`visualization` プロパティリンクをコピーし、新しいブラウザタブに貼り付けます。 | クラウドアーキテクト | 

### クリーンアップ
<a name="clean-up"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| S3 バケットからオブジェクトを削除します。 | デプロイされたリソースを破棄する前に、S3 バケットからすべてのオブジェクトを削除します。<pre>aws s3 rm s3://<ParallelDownloadStack.SampleS3BucketName> \<br />--recursive</pre>を AWS CDK 出力の値`<ParallelDownloadStack.SampleS3BucketName>`に置き換えることを忘れないでください。 | クラウドアーキテクト | 
| リソースを破棄します。 | このパイロット用に作成されたすべてのリソースを破棄するには、次のコマンドを実行します。<pre>cdk destroy</pre> | クラウドアーキテクト | 

## トラブルシューティング
<a name="run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function-troubleshooting"></a>


| 問題 | ソリューション | 
| --- | --- | 
| `'MemorySize' value failed to satisfy constraint: Member must have value less than or equal to 3008` | 新しいアカウントでは、Lambda 関数で 3,008 MB 以上を設定できない場合があります。 AWS Lambda Power Tuning を使用してテストするには、Step Functions の実行を開始するときに、入力 JSON に次のプロパティを追加します。<pre>"powerValues": [<br />    512,<br />    1024,<br />    1536,<br />    2048,<br />    2560,<br />    3008<br />  ]</pre> | 

## 関連リソース
<a name="run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function-resources"></a>
+ [Python – concurrent.futures.ThreadPoolExecutor](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor)
+ [Lambda クォータ — 関数の設定、デプロイ、実行](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html#function-configuration-deployment-and-execution)
+ [Python AWS CDK での の使用](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-python.html)
+ [AWS Lambda パワーチューニングによる関数のプロファイリング](https://docs.aws.amazon.com/lambda/latest/operatorguide/profile-functions.html)

## 追加情報
<a name="run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function-additional"></a>

**Code**

次のコードスニペットは、並列 I/O 処理を実行します。

```
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
  for result in executor.map(a_function, (the_arguments)):
    ...
```

`ThreadPoolExecutor` は、スレッドが利用可能になると再利用します。

**テストと結果**

これらのテストは 2024 年 12 月に実施されました。

最初のテストでは 2,500 のオブジェクト読み取りが処理され、次のような結果になりました。

![\[メモリの増加に伴う呼び出し時間の短縮と呼び出しコストの増加。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/b46e9b16-9842-4291-adfa-3ef012b89aec/images/f6743412-1e52-4c4c-a51c-ac0f75b3b998.png)


3,009 MB から、処理時間レベルはメモリが増えてもほぼ同じままでしたが、メモリサイズの増加に伴ってコストが増加しました。

別のテストでは、256 MB の倍数の値を使用し、10,000 のオブジェクト読み取りを処理して、1,536 MB から 3,072 MB のメモリの範囲を調査しました。その結果は次のとおりです。

![\[呼び出し時間の短縮と呼び出しコストの増加の差が減少しました。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/b46e9b16-9842-4291-adfa-3ef012b89aec/images/c75d4443-74d8-4b93-9b4d-b2640869381e.png)


最高の費用対効果の比率は、2,304 MB のメモリ Lambda 設定でした。

比較として、2,500 のオブジェクト読み取りのシーケンシャルプロセスには 47 秒かかりました。2,304 MB の Lambda 設定を使用した並列処理には 7 秒かかり、85% 短縮されました。

![\[シーケンシャル処理から並列処理に切り替えるときの時間の短縮を示すグラフ。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/b46e9b16-9842-4291-adfa-3ef012b89aec/images/f3dcc44d-ac20-4b75-897d-1d71f0d59781.png)
