如何提高DynamoDB请求的速度

时间:2014-01-29 02:11:57

标签: java amazon-web-services amazon-dynamodb

我一直在测试DynamoDB作为可扩展且稳定的吞吐量数据库的潜在选择,该数据库将非常频繁地命中并且需要非常快的响应时间(<50ms)。我看到以下代码的响应很慢(本地和EC2实例):

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();
    }
}

与DB的连接平均约为800 (ms),使用mapper的加载需要额外200 (ms)。根据{{​​3}},我们应该期望“平均服务端延迟......通常是一位数毫秒。”我不希望完整的往返HTTP请求增加那么多开销。即使在EC2实例上,这些预期数字也是如此吗?

2 个答案:

答案 0 :(得分:4)

我认为更好的测试是避免在启动JVM和加载类时产生的初始成本/延迟。类似的东西:

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");
    }
}

此外,您可以考虑启用AWS SDK for Java的默认指标,以查看Amazon CloudWatch中的细粒度时间分配。有关更多详细信息,请参阅:

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

希望这有帮助。

答案 1 :(得分:3)

Dynamo DB位于特定区域(它们尚不支持跨区域复制)。创建表时由您选择。除非您从同一区域调用API,否则它必然会很慢。

您似乎正在尝试从开发桌面调用Dynamo。您可以从“相同区域”中启动的EC2实例重新执行相同的测试。这将大大加快响应速度。这是一个更现实的测试,因为在部署生产系统时,它将与Dynamo位于同一区域。

同样,如果您真的需要非常快速的响应,请考虑在代码和Dynamo之间使用ElastiCache。在每次读取时,在返回结果之前存储在缓存中。下一次读取应该从缓存中读取(比如10分钟的到期时间)。对于“阅读量大”的应用程序,这是建议的路线。我已经看到使用这种方法可以获得更好的响应。