

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在 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 () 上的 S3 儲存貯體平行讀取物件AWS。模式示範如何使用 Python 使用 AWS Lambda 函數有效率地執行 I/O 繫結任務。

一家金融公司在互動式解決方案中使用此模式，以即時手動核准或拒絕相互關聯的金融交易。金融交易文件存放在與市場相關的 S3 儲存貯體中。運算子從 S3 儲存貯體中選取文件清單，分析解決方案計算的交易總值，並決定核准或拒絕選取的批次。

I/O 繫結任務支援多個執行緒。在此範例程式碼中，[並行.futures.ThreadPoolExecutor](https://docs.python.org/3.13/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor) 最多可與 30 個同時執行緒搭配使用，即使 Lambda 函數最多支援 1，024 個執行緒 （其中一個執行緒是您的主要程序）。此限制是因為太多執行緒會因為內容切換和運算資源的使用率而產生延遲問題。您也需要在 中增加集區連線上限，`botocore`以便所有執行緒可以同時執行 S3 物件下載。

範例程式碼在 S3 儲存貯體中使用一個 8.3 KB 物件搭配 JSON 資料。物件會多次讀取。Lambda 函數讀取物件後，JSON 資料會解碼為 Python 物件。在 2024 年 12 月，執行此範例後的結果為 2.3 秒內處理的 1，000 次讀取，以及 27 秒內處理的 10，000 次讀取，其使用 Lambda 函數設定為 2，304 MB 記憶體。 AWS Lambda 支援從 128 MB 到 10，240 MB (10 GB) 的記憶體組態，但將 Lambdamemory 增加到超過 2，304 MB 並有助於縮短執行此特定 I/O 繫結任務的時間。

[AWS Lambda Power Tuning](https://github.com/alexcasalboni/aws-lambda-power-tuning) 工具用於測試不同的 Lambda 記憶體組態，並驗證任務的最佳performance-to-cost比。如需測試結果，請參閱[其他資訊](#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 [每個分割字首每秒限制 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 （選用）

## Architecture
<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 電源調校）

**目標架構**

下圖顯示從 S3 儲存貯體平行讀取物件的 Lambda 函數。此圖表也有 Step Functions 工作流程，可供 AWS Lambda Power Tuning 工具微調 Lambda 函數記憶體。這種微調有助於在成本和效能之間取得良好的平衡。

![\[顯示 Lambda 函數、S3 儲存貯體和 AWS Step Functions 的圖表。\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/b46e9b16-9842-4291-adfa-3ef012b89aec/images/828696e2-6df7-4536-9205-951c99449f4e.png)


**自動化和擴展**

Lambda 函數會在需要時快速擴展。為了避免 Amazon S3 在高需求期間發生 503 緩慢下降錯誤，我們建議對擴展設定一些限制。

## 工具
<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 服務 透過命令列 shell 中的命令與 互動。在此模式中，第 2 AWS CLI 版用於上傳範例 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/) 是一種一般用途的電腦程式設計語言。Python 3.8 版中推出了[閒置工作者執行緒的重複使用](https://docs.python.org/3.8/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor)，此模式中的 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 管道或跨帳戶部署，請參閱[堆疊合成器](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>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 檢查 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>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 複製儲存庫。 | 若要複製最新版本的儲存庫，請執行下列命令：<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> | 雲端架構師 | 
| 安裝相依性。 | 若要安裝 Python 相依性，請執行 `pip`命令：<pre>pip install -r requirements.txt</pre> | 雲端架構師 | 
| 瀏覽程式碼。 | （選用） 從 S3 儲存貯體下載物件的範例程式碼位於 `resources/parallel.py`。基礎設施程式碼位於 `parallel_download` 資料夾中。 | 雲端架構師 | 

### 部署和測試應用程式
<a name="deploy-and-test-the-app"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 部署應用程式。 | 執行 `cdk deploy`。寫下 AWS CDK 輸出：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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>`<ParallelDownloadStack.SampleS3BucketName>` 將 取代為 AWS CDK 輸出中的對應值。 | 雲端架構師 | 
| 執行應用程式。 | 若要執行應用程式，請執行下列動作：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/run-parallel-reads-of-s3-objects-by-using-python-in-an-aws-lambda-function.html) | 雲端架構師 | 
| 新增下載次數。 | （選用） 若要執行 1，500 取得物件呼叫，請在 `Test` 參數的事件 JSON 中使用**下列 JSON**：<pre>{"repeat": 1500, "objectKey": "sample.json"}</pre> | 雲端架構師 | 

### 選用：執行 AWS Lambda 電源調校
<a name="optional-run-lamlong-power-tuning"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 執行 AWS Lambda Power Tuning 工具。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 從 S3 儲存貯體移除物件。 | 在您銷毀已部署的資源之前，請先從 S3 儲存貯體移除所有物件：<pre>aws s3 rm s3://<ParallelDownloadStack.SampleS3BucketName> \<br />--recursive</pre>請記得將 取代`<ParallelDownloadStack.SampleS3BucketName>`為 AWS CDK 輸出中的 值。 | 雲端架構師 | 
| 銷毀資源。 | 若要銷毀為此試驗建立的所有資源，請執行下列命令：<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 Power Tuning 分析函數](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/zh_tw/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/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/b46e9b16-9842-4291-adfa-3ef012b89aec/images/c75d4443-74d8-4b93-9b4d-b2640869381e.png)


最佳performance-to-cost比率是使用 2，304 MB 記憶體 Lambda 組態。

為了進行比較，2，500 個物件讀取的循序程序需要 47 秒。使用 2，304 MB Lambda 組態的平行程序需要 7 秒，減少 85%。

![\[圖表顯示從循序處理切換到平行處理的時間減少。\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/b46e9b16-9842-4291-adfa-3ef012b89aec/images/f3dcc44d-ac20-4b75-897d-1d71f0d59781.png)
