检索文件并通过 Lambda 将 .zip 上传到 s3

问题描述 投票:0回答:1

我想根据传入的请求过滤 AWS S3 中的文件,再次将它们压缩并上传到 s3 并快速获取预签名的 url。

我有以下 lambda 函数:

import { S3Client, ListObjectsV2Command, GetObjectCommand } from '@aws-sdk/client-s3';
import { Upload } from '@aws-sdk/lib-storage';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import archiver from 'archiver';
import { PassThrough } from 'stream';

export const handler = async (event) => {
  const bucketName = 'BUCKETNAME';
  const folderNames = ['MyFolder/']; 
  const targetZipKey = 'target.zip';

  try {
   
    const s3 = new S3Client({ region: 'us-east-2', });
    

    const archive = archiver('zip', { zlib: { level: 1 } });
    const passThroughStream = new PassThrough();
    archive.pipe(passThroughStream);

    const filePromises = [];
    console.log('files - start')
    for (const folderName of folderNames) {
      const listCommand = new ListObjectsV2Command({ Bucket: bucketName, Prefix: folderName });
      const { Contents } = await s3.send(listCommand);

      for (const file of Contents) {
        if (file.Key && !file.Key.endsWith('/')) {
          filePromises.push(
            s3.send(new GetObjectCommand({ Bucket: bucketName, Key: file.Key })).then((res) => {
              archive.append(res.Body, { name: file.Key.split('/').pop() });
            })
          );
        }
      }
    }
    console.log('files - finish')

    console.log('archive - start')
    await Promise.all(filePromises);
    console.log('archive - finish')

    archive.finalize();

    console.log('upload - start')
    const uploader = new Upload({
      client: s3,
      partSize: 10 * 1024 * 1024,
      queueSize: 10,
      params: {
        Bucket: bucketName,
        Key: targetZipKey,
        Body: passThroughStream,
      }
    });

    await uploader.done();
    console.log('upload - finish')

    const command = new GetObjectCommand({ Bucket: bucketName, Key: "Target.zip" });
    const signedUrl = await getSignedUrl(s3, command, { expiresIn: 18000 });

    return {
      statusCode: 200,
      body: signedUrl
    };
  } catch (error) {
    console.error(`An error occurred: ${error}`);
    return {
      statusCode: 500,
      body: `An error occurred: ${error.message}`,
    };
  }
};

我编写的代码工作正常,但在aws中上传过程需要太长时间。例如,对于200mb的文件,需要15秒的上传时间。

日志:

aws upload logs

但是,我向 lambda 添加了 vpc 和子网。我不能做得更快吗?我觉得这些时间对于 aws 来说太高了。

vpc and subnet config

amazon-web-services amazon-s3 aws-lambda amazon-vpc amazon-efs
1个回答
0
投票

增加 Lambda 函数的RAM 和 CPU 大小可能会有所帮助。

但是,我向 lambda 添加了 vpc 和子网。我不能做得更快吗?

我不明白 VPC 配置与函数运行时间有何关系。

但是我确实注意到您用

amazon-efs
标记了这个问题,尽管我没有看到您在问题本身中提到它。如果您在此过程中将文件写入 EFS,这将“极大地”减慢您的功能。 EFS 非常慢。如果您关心磁盘 I/O 进程的速度,则应该只写入 Lambda 函数的临时存储

© www.soinside.com 2019 - 2024. All rights reserved.