Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to improve speed of DynamoDB requests

I've been testing out DynamoDB as a potential option for a scalable and steady throughput database for a site that will be hit pretty frequently and requires a very fast response time (< 50ms). I'm seeing pretty slow responses (both locally and on an EC2 instance) for the following code:

public static void main(String[] args) {
    try {
        AWSCredentials credentials = new PropertiesCredentials(new File("aws_credentials.properties"));
        long start = System.currentTimeMillis();
        AmazonDynamoDBClient client = new AmazonDynamoDBClient(credentials);
        System.out.println((System.currentTimeMillis() - start) + " (ms) to connect");
        DynamoDBMapper mapper = new DynamoDBMapper(client);
        start = System.currentTimeMillis();
        Model model = mapper.load(Model.class, "hashkey1", "rangekey1");
        System.out.println((System.currentTimeMillis() - start) + " (ms) to load Model");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

The connection to the DB alone takes about 800 (ms) on average and the loading using the mapper takes an additional 200 (ms). According to Amazon's page about DynamoDB we should expect "Average service-side latencies...typically single-digit milliseconds." I wouldn't expect the full round-trip HTTP request to add that much overhead. Are these expected numbers even on an EC2 instance?

like image 622
Marc Baumbach Avatar asked Nov 18 '25 15:11

Marc Baumbach


1 Answers

I think a better test would be to avoid the initial costs/latency incurred in starting up the JVM and loading the classes. Something like:

public class TestDynamoDBMain {
    public static void main(String[] args) {
        try {
            AWSCredentials credentials = new PropertiesCredentials(new File("aws_credentials.properties"));
            AmazonDynamoDBClient client = new AmazonDynamoDBClient(credentials);
            DynamoDBMapper mapper = new DynamoDBMapper(client);
            // Warm up
            for (int i=0; i < 10; i++) {
                testrun(mapper, false);
            }
            // Time it
            for (int i=0; i < 10; i++) {
                testrun(mapper, true);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }    
    }

    private static void testrun(DynamoDBMapper mapper, boolean timed) {
        long start = System.nanoTime();
        Model model = mapper.load(Model.class, "hashkey1", "rangekey1");
        if (timed)
            System.out.println(
                TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)
                + " (ms) to load Model");
    }
}

Furthermore, you may consider enabling the default metrics of the AWS SDK for Java to see the fine grain time allocation in Amazon CloudWatch. For more details, see:

http://java.awsblog.com/post/Tx1O0S3I51OTZWT/Taste-of-JMX-Using-the-AWS-SDK-for-Java

Hope this helps.

like image 68
Hanson Char Avatar answered Nov 20 '25 06:11

Hanson Char



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!