从 S3 下载文件时,AWS Lambda 中出现“只读文件系统”错误

Posted

技术标签:

【中文标题】从 S3 下载文件时,AWS Lambda 中出现“只读文件系统”错误【英文标题】:Error "Read-only file system" in AWS Lambda when downloading a file from S3 【发布时间】:2017-01-15 22:41:19 【问题描述】:

当我将 file.csv 放入 S3 存储桶时,我的 lambda 函数出现以下错误。该文件并不大,我什至在打开文件进行读取之前添加了 60 秒的睡眠时间,但由于某种原因,该文件附加了额外的“.6CEdFe7C”。这是为什么呢?

[Errno 30] Read-only file system: u'/file.csv.6CEdFe7C': IOError
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 75, in lambda_handler
s3.download_file(bucket, key, filepath)
File "/var/runtime/boto3/s3/inject.py", line 104, in download_file
extra_args=ExtraArgs, callback=Callback)
File "/var/runtime/boto3/s3/transfer.py", line 670, in download_file
extra_args, callback)
File "/var/runtime/boto3/s3/transfer.py", line 685, in _download_file
self._get_object(bucket, key, filename, extra_args, callback)
File "/var/runtime/boto3/s3/transfer.py", line 709, in _get_object
extra_args, callback)
File "/var/runtime/boto3/s3/transfer.py", line 723, in _do_get_object
with self._osutil.open(filename, 'wb') as f:
File "/var/runtime/boto3/s3/transfer.py", line 332, in open
return open(filename, mode)
IOError: [Errno 30] Read-only file system: u'/file.csv.6CEdFe7C'

代码:

def lambda_handler(event, context):

    s3_response = 
    counter = 0
    event_records = event.get("Records", [])

    s3_items = []
    for event_record in event_records:
        if "s3" in event_record:
            bucket = event_record["s3"]["bucket"]["name"]
            key = event_record["s3"]["object"]["key"]
            filepath = '/' + key
            print(bucket)
            print(key)
            print(filepath)
            s3.download_file(bucket, key, filepath)

上面的结果是:

mytestbucket
file.csv
/file.csv
[Errno 30] Read-only file system: u'/file.csv.6CEdFe7C'

如果密钥/文件是“file.csv”,那么为什么 s3.download_file 方法会尝试下载“file.csv.6CEdFe7C”?我猜当函数被触发时,文件是 file.csv.xxxxx,但是当它到达第 75 行时,文件被重命名为 file.csv?

【问题讨论】:

转储不等于读取!所以你在临时文件夹(或内存)上的文件需要转储而不是self._osutil.open(filename, 'wb') as f:,只允许rbetc。所以需要在处理前处理源文件。 @user1530318,您介意将最佳答案标记为正确吗?好像没事。 【参考方案1】:

在 AWS Lambda 中似乎只有 /tmp 是可写的。

因此这会起作用:

filepath = '/tmp/' + key

参考资料:

https://aws.amazon.com/blogs/compute/choosing-between-aws-lambda-data-storage-options-in-web-apps https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html

【讨论】:

一个半小时后,我找到了你的答案……他们为什么不说清楚?谢谢! 我也想知道。因为这个原因,甚至很难用谷歌搜索!很高兴我能帮上忙,伙计。 @john AWS 有大量文档的问题! 在我类似的情况下(将 File 写入 user.dir:/<filename>),但使用 JAVA 和 3.8MB .zip 对象,此警告打印在之前我的 ["Read-only"] SDKClientException 已打印(但在使用 /tmp/ 解决方案后很高兴地解决了!可能是因为 S3ObjectInputStream 在无法获得 /<filename> 之前就死了):@987654331 @ 感谢将验证 '/tmp'【参考方案2】:

根据http://boto3.readthedocs.io/en/latest/guide/s3-example-download-file.html

示例展示了如何使用第一个参数作为云名称,第二个参数作为要下载的本地路径。

另一方面,amazaon docs 表示

因此,我们有 512 MB 用于创建文件。 这是我在 lambda aws 中为我准备的代码,对我来说就像魅力一样。

.download_file(Key=nombre_archivo,Filename='/tmp/'.format(nuevo_nombre))

【讨论】:

酷,这是你的代码,怎么样?如果您的答案解决了问题,请添加说明为什么它有效。如果没有,请删除它。 已更正,如果我需要设置更多信息,请告诉我 即使只是一个例子,也请不要将代码放在图像中。这样做时,请更正答案中的错别字。然而,总的来说,答案变得更好了。 :-D【参考方案3】:

我注意到,当我上传 lambda directly as a zip file 的代码时,我只能写入 /tmp 文件夹,但是当从 S3 上传代码时,我也能够写入 project root folder

【讨论】:

你有例子吗?

以上是关于从 S3 下载文件时,AWS Lambda 中出现“只读文件系统”错误的主要内容,如果未能解决你的问题,请参考以下文章

AWS lambda 函数从 S3 文件夹中删除文件

Zip 文件在使用节点和 AWS lambda 从 SFTP 服务器发布到 S3 后无法展开

从 Java AWS lambda API 响应中的字节数组返回图像

如何从 S3 加载泡菜文件以在 AWS Lambda 中使用?

如何使用 lambda 函数从 AWS s3 获取文本文件的内容?

AWS Lambda 中的 Amazon S3 waitFor()