本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 Lambda 無伺服器處理檔案
檔案處理工作流程通常從到達 NFS 或 SMB 檔案共享的檔案開始:從分支辦公室掃描的文件、現場團隊上傳的影像、從聯絡中心擷取的音訊,或合作夥伴交付的資料檔案。
當 Amazon S3 存取點連接至 FSx for ONTAP 磁碟區時, AWS Lambda 函數會直接使用 Amazon S3 API 讀取和寫入檔案。檔案層級操作可以無伺服器方式針對使用者和應用程式透過 NFS 和 SMB 存取的相同資料進行處理。
本教學課程顯示三種常見的檔案處理模式。每個範例會透過存取點從磁碟區讀取檔案、使用 AWS 服務或程式庫處理檔案,並將結果寫入磁碟區。
| 範例 | Input | 處理 | Output |
|---|---|---|---|
| 範例 1:產生影像縮圖 | JPEG 影像 | Pillow (影像庫) | 調整大小縮圖 |
| 範例 2:從文件擷取文字 | PDF 文件 | Amazon Textract | 擷取的文字 (JSON) |
| 範例 3:轉錄音訊檔案 | MP3 音訊 | Amazon Transcribe | 文字記錄 (JSON) |
注意
本教學課程大約需要 40 到 60 分鐘才能完成。 AWS 服務 使用的 會針對您建立的資源產生費用。如果您立即完成所有步驟,包括清除區段,則美國東部 (維吉尼亞北部) 的預期成本低於 1 美元。 AWS 區域此預估不包含 FSx for ONTAP 磁碟區本身的持續費用。
先決條件
開始前,請確定您具有下列項目:
已連接 Amazon S3 存取點的 ONTAP 磁碟區的 FSx。如需建立存取點的說明,請參閱 建立存取點。
存取點的存取點別名。您可以在 Amazon FSx 主控台或執行 找到此項目
aws fsx describe-s3-access-point-attachments。AWS CLI 已安裝並設定 第 1 版或第 2 版。本教學課程中的
aws lambda invoke命令包含--cli-binary-format raw-in-base64-out選項,這是第 2 AWS CLI 版中的必要項目,因此原始 JSON 承載不會解譯為 base64。如果您使用 AWS CLI 版本 1,請省略該選項。發起人 (執行本教學課程的使用者或角色) 叫用 Lambda 函數 (
lambda:CreateFunction、lambda:InvokeFunction)、存取 Amazon S3 存取點 (s3:GetObject、s3:PutObject) 和傳遞 Lambda 執行角色 () 的 IAM 許可iam:PassRole。
注意
本教學課程使用預設 Lambda 組態,其中 函數會在 VPC 外部的受管網路中執行。在這種情況下,存取點必須具有網際網路原始伺服器,函數才能連接它。如果您將 Lambda 函數連接至 VPC,您可以改為在存取點上使用 VPC 網路原始伺服器;VPC 必須具有 Amazon S3 Gateway 或 Interface 端點。如需詳細資訊,請參閱設定 Amazon S3 存取點的網路存取。
步驟 1:上傳範例檔案
下載下列範例檔案,並透過存取點將其上傳至 FSx for ONTAP 磁碟區。在本教學課程中將 取代為您的存取點別名。my-ap-alias-ext-s3alias
範例映像:下載 NASA 藍色 Marble 映像
(公有網域,2.4 MB),並將其儲存為 。 sample-image.jpg範例音訊:從 Amazon Transcribe 入門教學課程 (410 KB) 下載範例音訊檔案
,並將其儲存為 sample-audio.mp3。
透過存取點將範例檔案上傳至 FSx for ONTAP 磁碟區。
$aws s3 cp sample-image.jpg s3://my-ap-alias-ext-s3alias/samples/images/sample-image.jpg aws s3 cp sample-audio.mp3 s3://my-ap-alias-ext-s3alias/samples/audio/sample-audio.mp3
注意
範例影像是 NASA 藍色 Marble 相片 (公有網域,2.4 MB)。範例音訊來自 Amazon Transcribe 入門教學課程 (410 KB)。範例 PDF 會在 中產生範例 2:從文件擷取文字。
步驟 2:建立 Lambda 執行角色
Lambda 函數會擔任執行角色來與其他 互動 AWS 服務。在本教學課程中,連接 CloudWatch Logs 日誌記錄的 AWS受管AWSLambdaBasicExecutionRole政策,然後新增內嵌政策,將存取權授予 Amazon S3 存取點,以及範例使用的 Textract 和 Transcribe APIs。
將 、 region和 取代account-id為您的值。access-point-name
將下列信任政策儲存為
trust-policy.json。{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole" } ] }將下列內嵌許可政策儲存為
permissions-policy.json。它會將存取權授予存取點,以及範例使用的其他服務。{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"], "Resource": [ "arn:aws:s3:region:account-id:accesspoint/access-point-name", "arn:aws:s3:region:account-id:accesspoint/access-point-name/object/*" ] }, { "Effect": "Allow", "Action": ["textract:DetectDocumentText"], "Resource": "*" }, { "Effect": "Allow", "Action": [ "transcribe:StartTranscriptionJob", "transcribe:GetTranscriptionJob" ], "Resource": "*" } ] }建立角色、連接受管記錄政策,以及連接內嵌政策。
$aws iam create-role \ --role-namefsxn-lambda-file-processor\ --assume-role-policy-document file://trust-policy.json aws iam attach-role-policy \ --role-namefsxn-lambda-file-processor\ --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole aws iam put-role-policy \ --role-namefsxn-lambda-file-processor\ --policy-name fsxn-access-point-policy \ --policy-document file://permissions-policy.json
整合到您的工作流程
本教學課程中的範例使用手動調用與測試事件。在生產環境中,您可以使用下列方法自動觸發這些函數:
Amazon EventBridge 排程。依週期性排程執行函數 (例如,每小時或每天) 來處理新檔案。函數可以透過存取點列出檔案,並處理任何尚未處理的檔案。如需詳細資訊,請參閱《Amazon EventBridge 使用者指南》中的使用 EventBridge 排程 Lambda 函數。 EventBridge
Amazon API Gateway。將函數公開為 HTTP API,以便使用者或應用程式可以隨需請求處理特定檔案。如需詳細資訊,請參閱《Amazon API Gateway API Gateway 開發人員指南》中的使用 Lambda 整合建置 API Gateway REST API。
Step Functions。協調結合多個 Lambda 函數的多步驟檔案處理管道。例如,從文件中擷取文字、翻譯文字,然後將結果寫回磁碟區的工作流程。如需詳細資訊,請參閱《 AWS Step Functions 開發人員指南》中的使用 Step Functions 呼叫 Lambda。
範例 1:產生影像縮圖
此範例會從 FSx for ONTAP 磁碟區讀取 JPEG 影像,使用 Pillow 影像程式庫將其調整為 200 像素的縮圖大小,並將縮圖寫回磁碟區。
Lambda 函式程式碼
將下列程式碼儲存為 lambda_function.py。
import boto3 from io import BytesIO from PIL import Image s3 = boto3.client('s3') def lambda_handler(event, context): bucket = event['access_point_alias'] key = event['key'] # Read the image from FSx through the access point response = s3.get_object(Bucket=bucket, Key=key) image_data = response['Body'].read() # Resize to thumbnail img = Image.open(BytesIO(image_data)) img.thumbnail((200, 200)) # Write the thumbnail back to FSx buffer = BytesIO() img.save(buffer, format='JPEG', quality=85) buffer.seek(0) thumbnail_key = key.rsplit('.', 1)[0] + '_thumbnail.jpg' s3.put_object( Bucket=bucket, Key=thumbnail_key, Body=buffer.getvalue(), ContentType='image/jpeg' ) return { 'original_size': len(image_data), 'thumbnail_size': len(buffer.getvalue()), 'thumbnail_key': thumbnail_key }
建立和叫用 函數
此函數需要 Pillow 程式庫。建立部署套件,其中包含為 Lambda Linux 執行時間建置的 Pillow。
$# Create a deployment package with Pillow for Lambda (Linux) mkdir package && pip install Pillow -t package/ \ --platform manylinux2014_x86_64 --only-binary=:all: cd package && zip -r ../thumbnail-function.zip . cd .. && zip thumbnail-function.zip lambda_function.py # Create the function aws lambda create-function \ --function-namefsxn-thumbnail-generator\ --runtime python3.12 \ --handler lambda_function.lambda_handler \ --role arn:aws:iam::account-id:role/fsxn-lambda-file-processor\ --zip-file fileb://thumbnail-function.zip \ --timeout 30 \ --memory-size 256 # Invoke with a test event aws lambda invoke \ --function-namefsxn-thumbnail-generator\ --cli-binary-format raw-in-base64-out \ --payload '{"access_point_alias": "my-ap-alias-ext-s3alias", "key": "samples/images/sample-image.jpg"}' \ response.json cat response.json
驗證結果
$aws s3 ls s3://my-ap-alias-ext-s3alias/samples/images/2024-01-23 12:19:32 2566770 sample-image.jpg 2024-01-23 12:25:49 7065 sample-image_thumbnail.jpg
原始 2.4 MB 影像 (5400 × 2700 像素) 已調整為 7 KB 縮圖 (200 × 100 像素)。
範例 2:從文件擷取文字
此範例會從 FSx for ONTAP 磁碟區讀取 PDF 文件,將其傳送至 Amazon Textract 以擷取文字,並將擷取的文字作為 JSON 檔案寫入磁碟區。
建立和上傳範例 PDF
在此範例中,您需要 FSx for ONTAP 磁碟區的 PDF 文件。下列 Python 指令碼會產生簡單的發票 PDF,並透過存取點上傳。在本機電腦上執行此指令碼 (不在 Lambda 中)。
$pip install fpdf2 boto3
# create_invoice.py — run locally to generate and upload a sample PDF from fpdf import FPDF import boto3 pdf = FPDF() pdf.add_page() pdf.set_font("Helvetica", "B", 24) pdf.cell(0, 15, "INVOICE", new_x="LMARGIN", new_y="NEXT", align="C") pdf.set_font("Helvetica", "", 12) pdf.cell(0, 8, "Invoice Number: INV-2024-00142", new_x="LMARGIN", new_y="NEXT") pdf.cell(0, 8, "Date: January 15, 2024", new_x="LMARGIN", new_y="NEXT") pdf.cell(0, 8, "Customer: Example Corp", new_x="LMARGIN", new_y="NEXT") pdf.ln(5) pdf.set_font("Helvetica", "B", 12) pdf.cell(80, 8, "Description", border=1) pdf.cell(30, 8, "Qty", border=1, align="C") pdf.cell(40, 8, "Unit Price", border=1, align="R") pdf.cell(40, 8, "Amount", border=1, align="R") pdf.ln() pdf.set_font("Helvetica", "", 12) for desc, qty, price, amt in [ ("Cloud Storage Service", "1", "$2,400.00", "$2,400.00"), ("Data Transfer (TB)", "5", "$90.00", "$450.00"), ("Technical Support", "1", "$500.00", "$500.00"), ]: pdf.cell(80, 8, desc, border=1) pdf.cell(30, 8, qty, border=1, align="C") pdf.cell(40, 8, price, border=1, align="R") pdf.cell(40, 8, amt, border=1, align="R") pdf.ln() s3 = boto3.client('s3') s3.put_object( Bucket='my-ap-alias-ext-s3alias', Key='samples/documents/invoice.pdf', Body=pdf.output(), ContentType='application/pdf' ) print("Uploaded invoice.pdf")
$python3 create_invoice.py
Lambda 函式程式碼
將下列程式碼儲存為 lambda_function.py。
import boto3 import json s3 = boto3.client('s3') textract = boto3.client('textract') def lambda_handler(event, context): bucket = event['access_point_alias'] key = event['key'] # Read the PDF from FSx through the access point response = s3.get_object(Bucket=bucket, Key=key) document_bytes = response['Body'].read() # Extract text with Textract textract_response = textract.detect_document_text( Document={'Bytes': document_bytes} ) lines = [ block['Text'] for block in textract_response['Blocks'] if block['BlockType'] == 'LINE' ] # Write extracted text as JSON back to FSx result = { 'source_file': key, 'total_lines': len(lines), 'extracted_text': lines } output_key = key.rsplit('.', 1)[0] + '_extracted.json' s3.put_object( Bucket=bucket, Key=output_key, Body=json.dumps(result, indent=2), ContentType='application/json' ) return { 'lines_extracted': len(lines), 'output_key': output_key }
建立和叫用 函數
$zip textract-function.zip lambda_function.py aws lambda create-function \ --function-namefsxn-text-extractor\ --runtime python3.12 \ --handler lambda_function.lambda_handler \ --role arn:aws:iam::account-id:role/fsxn-lambda-file-processor\ --zip-file fileb://textract-function.zip \ --timeout 30 \ --memory-size 256 aws lambda invoke \ --function-namefsxn-text-extractor\ --cli-binary-format raw-in-base64-out \ --payload '{"access_point_alias": "my-ap-alias-ext-s3alias", "key": "samples/documents/invoice.pdf"}' \ response.json cat response.json
輸出範例:
{"lines_extracted": 22, "output_key": "samples/documents/invoice_extracted.json"}
範例 3:轉錄音訊檔案
此範例會針對儲存在 FSx for ONTAP 磁碟區的音訊檔案啟動 Amazon Transcribe 任務。Amazon Transcribe 會使用媒體檔案 URI 中的存取點別名,直接從存取點讀取音訊檔案。當任務完成時, 函數會將文字記錄寫回磁碟區。
Lambda 函式程式碼
將下列程式碼儲存為 lambda_function.py。
import boto3 import json import time import urllib.request s3 = boto3.client('s3') transcribe = boto3.client('transcribe') def lambda_handler(event, context): bucket = event['access_point_alias'] key = event['key'] media_format = key.rsplit('.', 1)[-1] # mp3, wav, etc. # Start a Transcribe job pointing to the file on FSx job_name = f"fsxn-{int(time.time())}" transcribe.start_transcription_job( TranscriptionJobName=job_name, Media={'MediaFileUri': f's3://{bucket}/{key}'}, MediaFormat=media_format, LanguageCode='en-US' ) # Wait for the job to complete while True: status = transcribe.get_transcription_job( TranscriptionJobName=job_name ) state = status['TranscriptionJob']['TranscriptionJobStatus'] if state in ('COMPLETED', 'FAILED'): break time.sleep(5) if state == 'FAILED': raise Exception( status['TranscriptionJob'].get('FailureReason', 'Unknown error') ) # Download the transcript transcript_uri = status['TranscriptionJob']['Transcript']['TranscriptFileUri'] with urllib.request.urlopen(transcript_uri) as resp: transcript_data = json.loads(resp.read()) transcript_text = transcript_data['results']['transcripts'][0]['transcript'] # Write the transcript back to FSx result = { 'source_file': key, 'job_name': job_name, 'transcript': transcript_text } output_key = key.rsplit('.', 1)[0] + '_transcript.json' s3.put_object( Bucket=bucket, Key=output_key, Body=json.dumps(result, indent=2), ContentType='application/json' ) return { 'transcript_length': len(transcript_text), 'output_key': output_key }
建立和叫用 函數
$zip transcribe-function.zip lambda_function.py aws lambda create-function \ --function-namefsxn-audio-transcriber\ --runtime python3.12 \ --handler lambda_function.lambda_handler \ --role arn:aws:iam::account-id:role/fsxn-lambda-file-processor\ --zip-file fileb://transcribe-function.zip \ --timeout 120 aws lambda invoke \ --function-namefsxn-audio-transcriber\ --cli-binary-format raw-in-base64-out \ --payload '{"access_point_alias": "my-ap-alias-ext-s3alias", "key": "samples/audio/sample-audio.mp3"}' \ --cli-read-timeout 180 \ response.json cat response.json
注意
Transcribe 任務通常需要 15 到 45 秒才能完成。函數的逾時設定為 120 秒以允許此操作。
考量事項
預設組態所需的網際網路原始伺服器。根據預設,Lambda 會從 VPC 外部的受管基礎設施存取 Amazon S3,這需要網際網路來源存取點。如果您將 Lambda 函數連接至 VPC,則可以改用 VPC 來源存取點。如需詳細資訊,請參閱先決條件。
檔案大小限制。Lambda 函數的記憶體上限為 10 GB,執行時間上限為 15 分鐘。對於大型檔案,請考慮使用範圍讀取 (
GetObject搭配Range標頭) 或串流回應。Textract 限制。同步
DetectDocumentTextAPI 接受最多 10 MB 和 1 頁的文件。對於多頁文件,請使用非同步StartDocumentTextDetectionAPI。轉錄直接從存取點讀取。Amazon Transcribe 接受
MediaFileUri參數 () 中的存取點別名s3://。Lambda 函數不需要下載和重新上傳音訊檔案。ap-alias/key檔案系統使用者許可。與存取點相關聯的檔案系統使用者必須具有輸入檔案的讀取許可,以及輸出目錄的寫入許可。
清除
若要避免持續收費,請刪除您在本教學課程中建立的資源。
$# Delete Lambda functions aws lambda delete-function --function-namefsxn-thumbnail-generatoraws lambda delete-function --function-namefsxn-text-extractoraws lambda delete-function --function-namefsxn-audio-transcriber# Delete the IAM role and policies aws iam delete-role-policy \ --role-namefsxn-lambda-file-processor\ --policy-name fsxn-access-point-policy aws iam detach-role-policy \ --role-namefsxn-lambda-file-processor\ --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole aws iam delete-role --role-namefsxn-lambda-file-processor# Delete sample files from your FSx volume aws s3 rm s3://my-ap-alias-ext-s3alias/samples/ --recursive