并行向AWS S3存储桶上传大量小文件比分块上传慢的问题排查
问题根因
- SDK配置未实际生效:如果你调整
maxSockets的代码执行时机晚于S3客户端实例的创建,或是你单独给S3实例传过配置覆盖了全局配置,你修改的maxSockets参数根本不会生效,底层还是用默认的50个socket上限,几百个请求排队在socket队列里,自然耗时随并行数上涨。 - Lambda资源配额限制:Lambda的CPU、网络调度能力和内存配额直接绑定,如果你的Lambda配置的内存低于512M,CPU性能不足以同时处理500个请求的签名、序列化、IO调度任务,会导致请求在Node.js事件循环阶段就出现排队,和S3的服务端能力、socket数都没有关系。
- S3.upload额外开销:
S3.upload接口是为大文件分块上传设计的,哪怕是小文件也会执行额外的文件大小判断、分块逻辑校验,并行量过高时这些CPU开销会叠加,拉长整体请求耗时。
解决方案
- 首先验证配置生效:调整配置执行时机,或者直接将agent配置传入S3构造函数,确保参数生效:
const aws = require('aws-sdk'); const https = require('https'); const s3 = new aws.S3({ httpOptions: { agent: new https.Agent({ maxSockets: 1000, keepAlive: true }) } });
不要将maxSockets设置到10万级别的夸张数值,单进程配置500-1000足够,过高反而会导致TCP端口耗尽、内核网络栈排队。
- 调整Lambda内存配额:优先将Lambda内存调整到1024M测试,CPU性能提升后,并发请求的处理排队问题会直接缓解,且内存提升带来的执行时间下降通常会抵消内存费用的上涨,总使用成本不会升高。
- 替换上传接口:500字节的小文件不需要使用分块上传能力,直接使用
S3.putObject接口,减少不必要的内部逻辑开销。 - 保留合理的批次并发控制:不需要盲目追求全并行,你之前测试得到的每批50个并发是最优阈值,可以直接保留该实现,在Node.js单进程处理能力和S3服务端能力之间取得平衡,总执行速度反而会比全并行更快。
内容的提问来源于stack exchange,提问作者kfirba
相关产品推荐
相关产品推荐

