【发布时间】:2019-01-10 15:27:18
【问题描述】:
写入临时文件的数据是否会影响 AWS lambda 中的内存使用?在 lambda 函数中,我将文件流式传输到临时文件。在 lambda 日志中,我看到使用的最大内存大于下载的文件。奇怪的是,如果 lambda 被快速连续调用多次,下载较小文件的调用仍会报告下载较大文件的调用所使用的最大内存。我将并发限制设置为 2。
当我在本地运行代码时,我的内存使用量符合预期,约为 20MB。在 lambda 上,它是 180MB,大约是流式传输文件的大小。该代码只是使用 python 请求库来流式传输文件下载,到 shutil.copyfileobj() 以写入 tempfile.TemporaryFile(),然后将其通过管道传输到 postgres“从标准输入复制”。
这使得 /tmp 存储似乎计入内存使用,但没有发现任何提及这一点。 lambda 文档中唯一提到 /tmp 是有 512mb 的限制。
示例代码:
import sys
import json
import os
import io
import re
import traceback
import shutil
import tempfile
import boto3
import psycopg2
import requests
def handler(event, context):
try:
import_data(event["report_id"])
except Exception as e:
notify_failed(e, event)
raise
def import_data(report_id):
token = get_token()
conn = psycopg2.connect(POSTGRES_DSN, connect_timeout=30)
cur = conn.cursor()
metadata = load_metadata(report_id, token)
table = ensure_table(metadata, cur, REPLACE_TABLE)
conn.commit()
print(f"report {report_id}: downloading")
with download_report(report_id, token) as f:
print(f"report {report_id}: importing data")
with conn, cur:
cur.copy_expert(f"COPY {table} FROM STDIN WITH CSV HEADER", f)
print(f"report {report_id}: data import complete")
conn.close()
def download_report(report_id, token):
url = f"https://some_url"
params = {"includeHeader": True}
headers = {"authorization": f"Bearer {token['access_token']}"}
with requests.get(url, params=params, headers=headers, stream=True) as r:
r.raise_for_status()
tmp = tempfile.TemporaryFile()
print("streaming contents to temporary file")
shutil.copyfileobj(r.raw, tmp)
tmp.seek(0)
return tmp
if __name__ == "__main__":
if len(sys.argv) > 1:
handler({"report_id": sys.argv[1]}, None)
更新: 在将代码更改为不使用临时文件而只是将下载直接流式传输到 postgres 复制命令后,内存使用量得到了修复。让我觉得 /tmp 目录对记录的内存使用有影响。
【问题讨论】:
标签: python amazon-web-services aws-lambda