Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slow S3 client initialisation in AWS Lambda

I'm currently working on an AWS Lambda function written in Java. It needs to fetch objects from S3 and I have therefore set up an IAM role and am building an S3 client in the Lambda's handler:

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;

public class Example implements RequestHandler<Void, Void> {

    @Override
    public Void handleRequest(Void nothing, Context ctx) {
        long start = System.currentTimeMillis();
        AmazonS3 amazonS3 = AmazonS3ClientBuilder.defaultClient();
        ctx.getLogger().log("Creating S3 client took " + (System.currentTimeMillis() - start) + "ms");
        ...
        return null;
    }
}

Nevertheless, using the AmazonS3ClientBuilder is very slow, the log statement prints out the following timings when allocating 192MB to the function:

Creating S3 client took 13541ms
Creating S3 client took 16482ms
Creating S3 client took 13617ms
Creating S3 client took 16380ms

Even when bumping memory right up to 3008MB to get maximum processing power (as AWS allocates CPU power proportional to the memory for Lambdas), it still takes between 1 and 2 seconds to get the client:

Creating S3 client took 1413ms
Creating S3 client took 1170ms
Creating S3 client took 1528ms
Creating S3 client took 1394ms

These timings were recorded in cold start scenarios and I am caching the AmazonS3 instance for subsequent requests, but it seems pretty extreme that just building an S3 client can take over 16 seconds on a non warm Lambda.

Am I misusing the AmazonS3ClientBuilder, possibly by not overriding some default values, leading to poor performance? How can client initialisation be sped up?

like image 975
Pyves Avatar asked Apr 28 '18 17:04

Pyves


People also ask

Why is AWS Lambda so slow?

Without the CPU contention that often affects serverful applications, the primary cause for slow Lambda response time is elevated latency from services that your functions integrate with. In my previous post, we discussed different ways you can track the latency to these external services.

Can S3 directly trigger Lambda?

Amazon S3 can send an event to a Lambda function when an object is created or deleted. You configure notification settings on a bucket, and grant Amazon S3 permission to invoke a function on the function's resource-based permissions policy.


1 Answers

The AWS SDK for Java 2.0 was released in November. It's basically a rewrite of version 1.x and it seems to have improved performance quite a bit. Migrating the code from the question to use the new SDK would give us something similar to the following:

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import software.amazon.awssdk.services.s3.S3Client;

public class Example implements RequestHandler<Void, Void> {

    @Override
    public Void handleRequest(Void nothing, Context ctx) {
        long start = System.currentTimeMillis();
        S3Client s3Client= S3Client.create();
        ctx.getLogger().log("Creating S3 client took " + (System.currentTimeMillis() - start) + "ms");
        ...
        return null;
    }
}

When allocating 192MB to the function:

Creating S3 client took 9380ms
Creating S3 client took 9719ms
Creating S3 client took 10098ms
Creating S3 client took 9519ms

When allocating 3008MB to the function:

Creating S3 client took 884ms
Creating S3 client took 873ms
Creating S3 client took 886ms
Creating S3 client took 877ms

Based on these rough figures, S3 client creation time in cold start scenarios has decreased by over a third when using version 2 of the SDK.

like image 146
Pyves Avatar answered Oct 03 '22 01:10

Pyves