Nest js 通过我的 API 将文件下载到 s3 非常慢

Nest js Downloading file to s3 through my API is extremely slow

提问人:Mansouri Rayen 提问时间:10/17/2023 更新时间:10/29/2023 访问量:123

问:

我正在利用我的 Nest API 将文件上传到 S3,它运行顺利。但是,我在尝试通过我的 API 下载文件时遇到了速度变慢的问题。关于如何提高这一过程的速度,是否有任何建议?

我目前正在使用 Nest 框架的可流文件来完成此操作。下面是代码片段:

     async download(key: string): Promise<Readable> {
      const client = new S3Client({
        credentials: {
          accessKeyId: this.accessKeyId,
          secretAccessKey: this.secretAccessKey,
          
        },
        region: this.region,
        
      });
      const command = new GetObjectCommand({
        Bucket: this.bucket,
        Key: key,
      });
      try {
        const response = await client.send(command);
        const body = response.Body as Readable;
        // The Body object also has 'transformToByteArray' and 'transformToWebStream' methods.
        return body
      } catch (err) {
        throw new Error(err);
      }
  }

这是我的控制器

@Controller('')
export class Download {
  constructor(@Inject(STORAGE) private _storageService: StorageServiceInterface) {}

  @Get('v1/api/download/:filename*')
  async download(@Param('filename') filename: string) {
    const file: File = await this._storageService.download(filename);
    console.log("returning stream")
    return new StreamableFile(file.stream, {
      type: 'application/pdf',
    });
  }
}


 
文件 amazon-s3 下载 嵌套

评论

1赞 Ermiya Eskandary 10/28/2023
“遇到经济放缓”——您能详细介绍一下吗?它是否比通过控制台下载对象慢?你把它与什么进行比较?
0赞 Mansouri Rayen 10/29/2023
一个 5MB 的文件大约需要 50 秒才能下载,而从我的服务器下载它只需要大约 0.5 到 1 秒的时间。
1赞 lennart 10/30/2023
您的服务器是否位于 AWS 中?如果是这样,下载将永远不会离开AWS网络,当然速度非常快。您能否比较一下使用 aws cli 在本地下载文件和使用 api 以确保网络不是罪魁祸首的速度?
0赞 justdvl 11/1/2023
@lennart独立于 OP,我们的团队直接在服务器上测试了这一点,在 VPC 中,NestJS 的 S3 下载速度仍然比简单的 nodejs 函数慢得多。

答:

1赞 Lukas Liesis 10/29/2023 #1

通过 API 将文件从 S3 下载到客户端有什么意义?有预签名的 URL。这样:

  1. UI 调用您的 API 以获取预签名 URL 以在 S3 上反对
  2. UI 调用预签名 URL 直接从 S3 下载对象

可以在几个地方提高速度:

  1. 不要通过 API 流式传输数据,而是使用预签名 URL 直接从 S3 下载数据
  2. 记下 S3 存储桶位于哪个区域,也许它与用户位于世界的不同部分
  3. 您可以对 S3 使用加速模式,该模式会在 S3 之上添加类似 CDN 的内容。您的用户将使用最近的 aws 边缘站点将数据从 S3 流式传输给他们
  4. 如果文件是公有的,请考虑在边缘上的用户 (cloudfront) 旁边添加实际的 CDN 和预缓存数据

顺便说一句,您可以使用预签名 URL 直接上传和下载到 S3 或从 S3 下载,如果公共用户需要上传/下载,这是这样做的方法。

预签名 URL 示例:

https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/s3-example-presigned-urls.html

请考虑通读此官方性能指南。https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html

评论

0赞 justdvl 11/1/2023
谢谢,但问题是关于在服务器上下载的。这种用例是当服务器需要处理数据并缓存结果时。
0赞 Lukas Liesis 11/2/2023
@justdvl不确定设置,但希望您的意思不是您应该使用 CDN 的目的。无论如何,下载速度可能比 HTTP GET 调用更快。如果您的服务器是在 aws 中运行的 EC2 或 lambda,则它的角色应该有权访问对象,并且您将通过或使用预签名 url 来获取它。如果您想多次下载相同的内容,预签名会更快,因为它已经预先授权。此外,请确保区域匹配且对象靠近您的服务器,或者至少启用传输加速或设置 cdn。https://your-bucket.s3......