首页 > 解决方案 > Amazon S3 或 Lambda 是否默认缓存文件或数据?如何关闭它?

问题描述

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

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

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

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

标签: amazon-web-servicesamazon-s3aws-lambda

解决方案


AWS lambda 可以为后续的 lambda 调用重用现有的执行容器。重用容器保持/tmp目录内容完整。这在许多情况下都是有利的,因为文件可以用作多个 lambda 调用共享的缓存。

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

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


推荐阅读