amazon-web-services - Amazon S3 或 Lambda 是否默认缓存文件或数据?如何关闭它?
问题描述
这似乎很奇怪,因为据我所知 Amazon S3 和 Lambda默认情况下与缓存无关,但在我的情况下似乎如此。
我正在尝试使用 AWS Polly 将文本转换为语音并将创建的 mp3 文件存储在 S3 存储桶中。我使用 AWS Lambda 启动 Polly。
现在,我创建了一个 AWS Lambda 测试,它采用以下两个属性:ID 和文本。ID 将是 mp3 文件的名称,文本将被转换。文本在所有步骤中都是相同的:
- 最初,我使用 ID 运行了一个糟糕的测试,
my-post
其中我为同一个 ID 多次启动了 Lambda。这导致一个大的音频 (18MB) 文件一遍又一遍地重复提供的文本(嘘!)。 - 如果我使用相同的文本但新的 ID(例如:)再次运行 Lambda(仅一次)
my-post-2
,我会得到仅读取一次文本的小音频文件(耶!)。 - 然后我从 S3 中删除了这两个文件。
- 我用 ID 再次运行 Lambda
my-post-2
。正如预期的那样,我再次得到了小文件。 - 我用 ID 再次运行了 Lambda
my-post
。我又得到了大文件。
现在我陷入了这样一种状态,如果我使用原始 ID(显然是我想要使用的 ID)运行我的 Lambda,会生成一个巨大的音频文件,重复文本几次,但如果我使用另一个 ID,那么我会得到正常大小的文件,读取文本一次。
这是我的功能:
import boto3
import os
from contextlib import closing
from boto3.dynamodb.conditions import Key, Attr
def lambda_handler(event, context):
audiopostid = event["audiopostid"]
text = event["text"]
voice = event["voice"]
rest = text
textBlocks = []
while (len(rest) > 1100):
begin = 0
end = rest.find(".", 1000)
if (end == -1):
end = rest.find(" ", 1000)
textBlock = rest[begin:end]
rest = rest[end:]
textBlocks.append(textBlock)
textBlocks.append(rest)
polly = boto3.client('polly')
for textBlock in textBlocks:
response = polly.synthesize_speech(
OutputFormat='mp3',
Text = textBlock,
VoiceId = voice
)
if "AudioStream" in response:
with closing(response["AudioStream"]) as stream:
output = os.path.join("/tmp/", audiopostid)
with open(output, "a") as file:
file.write(stream.read())
s3 = boto3.client('s3')
s3.upload_file('/tmp/' + audiopostid,
os.environ['BUCKET_NAME'],
audiopostid + ".mp3")
s3.put_object_acl(ACL='public-read',
Bucket=os.environ['BUCKET_NAME'],
Key= audiopostid + ".mp3")
location = s3.get_bucket_location(Bucket=os.environ['BUCKET_NAME'])
region = location['LocationConstraint']
if region is None:
url_begining = "https://s3.amazonaws.com/"
else:
url_begining = "https://s3-" + str(region) + ".amazonaws.com/" \
url = url_begining \
+ str(os.environ['BUCKET_NAME']) \
+ "/" \
+ str(audiopostid) \
+ ".mp3"
return
解决方案
AWS lambda 可以为后续的 lambda 调用重用现有的执行容器。重用容器保持/tmp
目录内容完整。这在许多情况下都是有利的,因为文件可以用作多个 lambda 调用共享的缓存。
但这可能会在您的情况下导致问题。因为您以附加模式 ( open(output, "a")
) 打开文件,所以在重用容器中调用的 lamba 只是将新的.mp3文件附加到先前调用的文件中,从而使您的音频重复多次。
在 lambda 函数开始时删除所有现有的临时文件(不应重复使用)应该可以解决问题。这也将解决有限 (500 MB) 磁盘空间的问题,因为在使用几个不同ID
的 s 执行 lambda 之后,可能会留下/tmp
充满空间的文件,而没有足够的空间来写入另一个文件。
推荐阅读
- ag-grid - ag-grid 包之间的区别
- angular - AngularFire - 如何将firestore文档映射到valueChanges上的数组?
- javascript - javascript,从大对象数组中返回小对象数组
- express - 如何从 App Engine 服务器获取错误消息?
- node.js - AWS:CloudFormation 中的 Node.js Lambda 函数,用于将文件上传到 DeviceFarm URL
- laravel - 使用原始 SQL 查询插入以避免 SQL 注入?
- r - 检查差异是否小于机器精度的正确/标准方法是什么?
- c - 存储和打印结构数组无法按预期工作
- r - How to get rid of INCOMPLETE STRING error in ShinyApp R?
- java - 在Java中的排序矩阵中搜索