Bil*_*ers 7 java amazon-s3 limit amazon-web-services aws-sdk
我有一个使用通过 SQS 触发的 AWS Java SDK 的 Lambda。SQS 消息至少包含一个 S3 存储桶/密钥组合。Lambda 读取充满 tomcat 日志事件的指定文件并按会话 ID 对它们进行排序,然后将每个会话的事件写入另一个公共 S3 存储桶。
从源存储桶读取从未达到任何服务限制,因此那里没有问题。
写入单个目标存储桶会导致数千个 503 Slow Down 异常。为了解决这个问题,我正在写入目标存储桶中 >= 20k 的非常随机的分区,但我仍然收到这些错误。
我最近的测试表明,在任何特定的时刻,lambda 只将大约 1,800 个文件写入存储桶,并且这些写入均匀分布在许多分区上。
由于 AWS 文档指出每个分区每秒可以进行 3,500 次同时写入操作,因此应该没有理由获得 503 Slow Down 异常。因为这些写入发生在多达 1,000 个并发运行的 lambda 表达式中,所以我没有实现任何指数退避策略的好方法,但我真的不需要这样做。S3 会发出这些异常并且应用程序实际上依赖于最大并发处理是没有意义的。
因此,长话短说,在 200 多个不同的 AWS S3 客户端和约 30,000 个分区上每秒写入约 1,800 个小文件的 200 多个并发 lambda 引发了数千个 S3 慢速异常。我怎样才能摆脱它们?
我尝试了几种不同的分区计数,从 5,000 到 32,000,以尝试分配写入。没变。
分区示例:80e49ec0903f1e8fa1a8/a5468f4a8a184cd13696/cf4d516ca85abafb7b26/
protected PutObjectResult saveFile(AmazonS3 s3, String bucket, String partition, List<Packet> packets) {
//noinspection deprecation
System.setProperty(SDKGlobalConfiguration.ENABLE_S3_SIGV4_SYSTEM_PROPERTY, "true");
String fileName = Utils.getIntermediateName(partition);
byte[] content = packets.stream().map(Packet::getMessage).map(Utils::preparePacket)
.filter(Objects::nonNull).collect(ByteArrayOutputStream::new, (baos, bytes) -> {
try {
baos.write(bytes);
} catch (IOException e1) {
log("Could not write to a stream: " + e1.toString());
}
}, (baos1, baos2) -> baos1.write(baos2.toByteArray(), 0, baos2.size())).toByteArray();
PutObjectResult result = null;
try (InputStream stream = new ByteArrayInputStream(content)) {
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(content.length);
PutObjectRequest request = new PutObjectRequest(bucket, fileName, stream, metadata);
request.setCannedAcl(CannedAccessControlList.BucketOwnerFullControl);
result = s3.putObject(request);
} catch (Exception e) {
log("In saveFile: " + e.toString());
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
预期的结果是我没有收到 503 慢速异常,低于记录的每个分区 3,500 次写入的限制。
实际结果是我收到了数千个 503 Slow Down 异常。
归档时间: |
|
查看次数: |
442 次 |
最近记录: |