我们最近将 aws-lambda java 运行时从 java-11 更新到了 java-17(更新只是运行时环境的切换,因此它仍然运行使用 java-11 编译的代码)。这导致我们处理大文件的 lambda 之一开始超时。
lambda 从 S3 读取大约 1GB 的 json 文件,在进行模式验证时将其转换为 XML,并将其写回 S3,最终大小约为 1.5GB,所有这些都是使用 io 流完成的(因此我们不会将完整文件保留在内存中)。
我尝试隔离该问题,并编写了一个最小函数,该函数仅从 S3 读取源文件,不执行任何其他操作,我的测试表明 java-17 至少需要两倍的时间来读取热运行。
我们使用的是 aws-sdk v1 (1.12.512),lambda 很简单,没有 snapstart,尝试了不同的内存配置。我已经尝试过x86_64和arm64。在所有情况下,我 java-11 的运行速度大约是 java-17 的两倍。
我使用的代码测试代码是:
package lambda;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.S3Object;
import java.io.IOException;
import java.io.InputStream;
import java.time.Duration;
import java.util.Map;
import static java.lang.System.getenv;
public class Handler implements RequestHandler<Map<String, String>, String> {
static final AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(Regions.EU_WEST_1).build();
@Override
public String handleRequest(Map<String, String> input, Context context) {
long start = System.currentTimeMillis();
long bytesRead = 0;
try (S3Object s3o = s3.getObject(getenv("BUCKET"), getenv("KEY"))) {
InputStream is = s3o.getObjectContent();
byte[] buffer = new byte[1024 * 1024];
int read;
while ((read = is.read(buffer)) != -1) {
bytesRead += read;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
Duration d = Duration.ofMillis(System.currentTimeMillis() - start);
String msg = String.format("Read %d bytes from S3 in %s %d bytes/sec", bytesRead, d, bytesRead / d.getSeconds());
context.getLogger().log(msg);
return msg;
}
}
日志的示例输出(这些是热调用):
Java-17:
START RequestId: 76d41820-40ef-4afb-8f8e-8c65de7eb6fc Version: $LATEST
Read 946586484 bytes from S3 in PT40.242S 23664662 bytes/sec
END RequestId: 76d41820-40ef-4afb-8f8e-8c65de7eb6fc
REPORT RequestId: 76d41820-40ef-4afb-8f8e-8c65de7eb6fc Duration: 40245.11 ms Billed Duration: 40246 ms Memory Size: 2048 MB Max Memory Used: 141 MB
Java-11:
START RequestId: bb994f7a-5e31-4a1d-a656-7e8b2fa0c377 Version: $LATEST
Read 946586484 bytes from S3 in PT21.095S 45075546 bytes/sec
END RequestId: bb994f7a-5e31-4a1d-a656-7e8b2fa0c377
REPORT RequestId: bb994f7a-5e31-4a1d-a656-7e8b2fa0c377 Duration: 21096.62 ms Billed Duration: 21097 ms Memory Size: 2048 MB Max Memory Used: 174 MB
是否有其他人在 java-17 上遇到类似的性能下降以及有关如何修复/优化此问题的任何提示?
我确实尝试用谷歌搜索这个,大部分发现博客文章都说 java-17 的性能优于 java-11。