这似乎很奇怪,因为据我所知,Amazon S3和Lambda 与默认情况下的缓存无关,但是在我看来,这是如此。
我正在尝试使用AWS Polly将文本转换为语音并将创建的mp3文件存储在S3存储桶中。我使用AWS Lambda启动Polly。
现在,我创建了一个AWS Lambda测试,该测试具有以下两个属性:ID和Text。 ID将是mp3文件的名称,文本将被转换。在所有步骤中,文本都是相同的:
my-post
的测试很差,在该测试中,我多次为同一个ID启动Lambda。这导致一个大的音频(18MB)文件一遍又一遍地重复提供的文本(boo!)。my-post-2
)运行Lambda(仅运行一次),我会得到小的音频文件,仅读取一次文本(是!)。my-post-2
的Lambda。像预期的那样,我又得到了一个小文件。my-post
运行Lambda。我又得到了大文件。现在,我处于这样一种状态:如果我使用原始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
答案 0 :(得分:3)
AWS lambda可以reuse existing execution container用于后续的lambda调用。重用容器可保持/tmp
目录的内容不变。在许多情况下这是有利的,因为文件可以用作多个lambda调用共享的缓存。
但这可能会导致您遇到的问题。因为您以追加模式(open(output, "a")
)打开文件,所以在重用容器中调用的lamba只是将新的 .mp3 文件追加到先前调用的文件中,从而使音频多次重复。 / p>
在lambda函数开始时删除所有现有的临时文件(不应重复使用)应该可以解决该问题。这还将解决磁盘空间有限(500 MB)的问题,因为在用几个不同的ID
执行lambda之后,可能会/tmp
充满文件而没有足够的空间来写入另一个文件。