现有文件的aws lambda s3事件

时间:2016-05-14 14:13:55

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

我正在考虑转移到lambdas,花了一些时间阅读文档和各种用户体验的博客后,我仍在努力解决一个简单的问题。有没有建议/正确的方法将lambda用于现有的s3文件?

我有一个s3存储桶,其中包含跨越几年的存档数据。这些数据的大小相当大(数百GB)。每个文件都是一个简单的txt文件。文件中的每一行代表一个事件,它只是一个逗号分隔的字符串。

我的最终目标是使用这些文件,逐行解析每一个文件应用一些转换,创建批量行并将它们发送到外部服务。从我到目前为止所读到的内容来看,如果我写了一个正确的lambda,这将由s3事件触发(例如上传一个新文件)。

有没有办法将lambda应用到我的存储桶的所有现有内容?

谢谢

4 个答案:

答案 0 :(得分:1)

对于现有资源,您需要编写一个脚本来获取所有资源的列表,并以某种方式将每个项目发送到Lambda函数。我可能会考虑将每个现有S3对象的位置发送到Kenesis流,并配置Lambda函数从该流中提取记录并处理它们。

答案 1 :(得分:0)

尝试复制存储桶内容并使用lambda捕获创建事件。

副本:

s3cmd sync s3://from/this/bucket/ s3://to/this/bucket

更大的水桶:

https://github.com/paultuckey/s3_bucket_to_bucket_copy_py

答案 2 :(得分:0)

尝试使用s3cmd。

s3cmd modify --recursive --add-header="touched:touched" s3://path/to/s3/bucket-or-folder

这将修改元数据并为lambda调用事件

答案 3 :(得分:0)

我遇到了一个类似的问题,我对现有的 Lambda 函数进行了最少的改动就解决了这个问题。该解决方案涉及创建 API 网关触发器(除了 S3 触发器)——API 网关触发器用于处理 S3 中的历史文件,常规 S3 触发器将在新文件上传到我的 S3 存储桶时处理我的文件。

最初 - 我开始构建我的函数以期望 S3 事件作为触发器。回想一下,S3 事件有这个 structure - 所以我会寻找 S3 存储桶名称和键来处理 - 像这样:

    for record in event['Records']:
        bucket = record['s3']['bucket']['name']
        key = unquote_plus(record['s3']['object']['key'], encoding='utf-8')

        temp_dir = tempfile.TemporaryDirectory()
        video_filename = os.path.basename(key)
        local_video_filename = os.path.join(temp_dir.name, video_filename)
        s3_client.download_file(bucket, key, local_video_filename)

但是当您发送 API 网关触发器时,请求/事件中没有“记录”对象。您可以在 API Gateway Trigger 中使用查询参数 - 因此需要对上述代码片段进行修改:

    if 'Records' in event:
        # this means we are working off of an S3 event
        records_to_process = event['Records']
    else:
        # this is for ad-hoc posts via API Gateway trigger for Lambda
        records_to_process = [{
        "s3":{"bucket": {"name":  event["queryStringParameters"]["bucket"]},
              "object":{"key": event["queryStringParameters"]["file"]}}
    }]

    for record in records_to_process:
        # below lines of code s same as the earlier snippet of code
        bucket = record['s3']['bucket']['name']
        key = unquote_plus(record['s3']['object']['key'], encoding='utf-8')

        temp_dir = tempfile.TemporaryDirectory()
        video_filename = os.path.basename(key)
        local_video_filename = os.path.join(temp_dir.name, video_filename)
        s3_client.download_file(bucket, key, local_video_filename)

Postman result of sending the post request