Amazon S3或Lambda是否默认缓存文件或数据?如何关闭?

时间:2018-08-04 08:34:02

标签: amazon-web-services amazon-s3 aws-lambda

这似乎很奇怪,因为据我所知,Amazon S3和Lambda 与默认情况下的缓存无关,但是在我看来,这是如此。

我正在尝试使用AWS Polly将文本转换为语音并将创建的mp3文件存储在S3存储桶中。我使用AWS Lambda启动Polly。

现在,我创建了一个AWS Lambda测试,该测试具有以下两个属性:ID和Text。 ID将是mp3文件的名称,文本将被转换。在所有步骤中,文本都是相同的:

  1. 最初,我对ID为my-post的测试很差,在该测试中,我多次为同一个ID启动Lambda。这导致一个大的音频(18MB)文件一遍又一遍地重复提供的文本(boo!)。
  2. 如果我再次使用相同的文本但使用新ID(例如:my-post-2)运行Lambda(仅运行一次),我会得到小的音频文件,仅读取一次文本(是!)。
  3. 然后我从S3中删除了这两个文件。
  4. 我再次运行ID为my-post-2的Lambda。像预期的那样,我又得到了一个小文件。
  5. 我再次使用ID 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

1 个答案:

答案 0 :(得分:3)

AWS lambda可以reuse existing execution container用于后续的lambda调用。重用容器可保持/tmp目录的内容不变。在许多情况下这是有利的,因为文件可以用作多个lambda调用共享的缓存。

但这可能会导致您遇到的问题。因为您以追加模式(open(output, "a"))打开文件,所以在重用容器中调用的lamba只是将新的 .mp3 文件追加到先前调用的文件中,从而使音频多次重复。 / p>

在lambda函数开始时删除所有现有的临时文件(不应重复使用)应该可以解决该问题。这还将解决磁盘空间有限(500 MB)的问题,因为在用几个不同的ID执行lambda之后,可能会/tmp充满文件而没有足够的空间来写入另一个文件。