首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >亚马逊DynamoDB需要很长时间才能获取最高延迟5-6秒的记录。

亚马逊DynamoDB需要很长时间才能获取最高延迟5-6秒的记录。
EN

Stack Overflow用户
提问于 2022-07-14 09:37:36
回答 2查看 537关注 0票数 0

pom.xml

代码语言:javascript
复制
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-bom</artifactId>
    <version>1.11.256</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-dynamodb</artifactId>
</dependency>

客户代码

代码语言:javascript
复制
public static AmazonDynamoDB getDynamoDBClient() {
        return AmazonDynamoDBClientBuilder.standard().withRegion("ap-southeast-1").build();
}

现在,我正在尝试执行一个记录很少的普通查询,但是获取结果需要很长时间。

这是它第一次在5-6秒内对多个请求获取记录,减少了一半。2-3秒仍然是很长的时间,因为只取几个项目。

已经使用不同的客户端配置(连接超时、请求超时、重试等)检查了dynamo DB的调优。但没有给出预期的结果。也检查了SDK 2 URLConnectionHTTPClient配置,但结果也是一样的。

一个可能的原因可能是dynamo客户端的凭据获取时间,但在java中没有任何凭据缓存引用。有人能建议可能的配置来改善这个延迟吗?

EN

回答 2

Stack Overflow用户

发布于 2022-07-14 13:17:57

您正在使用一个非常老的API,不再是最佳实践。要在Java中使用最佳实践,请使用AWS v2

AWSSDKforJava2.x是版本1.x代码库的主要重写版本。它构建在Java 8+之上,并添加了几个经常被请求的特性。这包括对非阻塞I/O的支持,以及在运行时插入不同的HTTP实现的能力。

v2的POM是:

代码语言:javascript
复制
 <dependency>
  <groupId>software.amazon.awssdk</groupId>
  <artifactId>bom</artifactId>
  <version>2.17.190</version>
  <type>pom</type>
  <scope>import</scope>
 </dependency>

要使用v2检索记录,您有三个选择。

  • 使用DynamoDbClient。
  • 使用增强的客户端(将Java对象映射到表)
  • 使用PartiQL (使用类似于SQL的语法)

我会向你展示所有的方法。所有的例子都可以在亚马逊Github回购公司中找到。

使用DynamoDbClient

守则是:

代码语言:javascript
复制
package com.example.dynamodb;

// snippet-start:[dynamodb.java2.get_item.import]
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
// snippet-end:[dynamodb.java2.get_item.import]


/**
 * Before running this Java V2 code example, set up your development environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 *
 * To get an item from an Amazon DynamoDB table using the AWS SDK for Java V2, its better practice to use the
 * Enhanced Client, see the EnhancedGetItem example.
 */
public class GetItem {

    public static void main(String[] args) {

        final String usage = "\n" +
                "Usage:\n" +
                "    <tableName> <key> <keyVal>\n\n" +
                "Where:\n" +
                "    tableName - The Amazon DynamoDB table from which an item is retrieved (for example, Music3). \n" +
                "    key - The key used in the Amazon DynamoDB table (for example, Artist). \n" +
                "    keyval - The key value that represents the item to get (for example, Famous Band).\n" ;

        if (args.length != 3) {
            System.out.println(usage);
            System.exit(1);
        }

        String tableName = "Customer" ; //args[0];
        String key = "id" ; //args[1];
        String keyVal = "id101" ; //args[2];
        System.out.format("Retrieving item \"%s\" from \"%s\"\n", keyVal, tableName);

        ProfileCredentialsProvider credentialsProvider = ProfileCredentialsProvider.create();
        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .credentialsProvider(credentialsProvider)
                .region(region)
                .build();

        getDynamoDBItem(ddb, tableName, key, keyVal);
        ddb.close();
    }

    // snippet-start:[dynamodb.java2.get_item.main]
    public static void getDynamoDBItem(DynamoDbClient ddb,String tableName,String key,String keyVal ) {

        HashMap<String,AttributeValue> keyToGet = new HashMap<>();
        keyToGet.put(key, AttributeValue.builder()
                .s(keyVal).build());

        GetItemRequest request = GetItemRequest.builder()
                .key(keyToGet)
                .tableName(tableName)
                .build();

        try {
            Map<String,AttributeValue> returnedItem = ddb.getItem(request).item();

            if (returnedItem != null) {
                Set<String> keys = returnedItem.keySet();
                System.out.println("Amazon DynamoDB table attributes: \n");

                for (String key1 : keys) {
                    System.out.format("%s: %s\n", key1, returnedItem.get(key1).toString());
                }
            } else {
                System.out.format("No item found with the key %s!\n", key);
            }
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
    // snippet-end:[dynamodb.java2.get_item.main]
}

增强客户端

守则是:

代码语言:javascript
复制
package com.example.dynamodb;

// snippet-start:[dynamodb.java2.mapping.getitem.import]
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Key;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
// snippet-end:[dynamodb.java2.mapping.getitem.import]

/*
 * Before running this code example, create an Amazon DynamoDB table named Customer with these columns:
 *   - id - the id of the record that is the key
 *   - custName - the customer name
 *   - email - the email value
 *   - registrationDate - an instant value when the item was added to the table
 *
 * Also, ensure that you have set up your development environment, including your credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class EnhancedGetItem {

    public static void main(String[] args) {

        ProfileCredentialsProvider credentialsProvider = ProfileCredentialsProvider.create();
        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .credentialsProvider(credentialsProvider)
                .region(region)
                .build();

        DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();

        getItem(enhancedClient);
        ddb.close();
    }

    // snippet-start:[dynamodb.java2.mapping.getitem.main]
    public static void getItem(DynamoDbEnhancedClient enhancedClient) {

        try {
            DynamoDbTable<Customer> table = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
            Key key = Key.builder()
                    .partitionValue("id120")
                    .build();

            // Get the item by using the key.
            Customer result = table.getItem(r->r.key(key));
            System.out.println("******* The description value is "+result.getCustName());

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
    // snippet-end:[dynamodb.java2.mapping.getitem.main]
}

PartiQL

代码是

代码语言:javascript
复制
public static void getItem(DynamoDbClient ddb) {

        String sqlStatement = "SELECT * FROM MoviesPartiQ where year=? and title=?";
        List<AttributeValue> parameters = new ArrayList<>();
        AttributeValue att1 = AttributeValue.builder()
                .n("2012")
                .build();

        AttributeValue att2 = AttributeValue.builder()
                .s("The Perks of Being a Wallflower")
                .build();

        parameters.add(att1);
        parameters.add(att2);

        try {
            ExecuteStatementResponse response = executeStatementRequest(ddb, sqlStatement, parameters);
            System.out.println("ExecuteStatement successful: "+ response.toString());

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }

所有这些方法都推荐在AWS V1上使用。如果您不熟悉V2 API --包括creds和设置您的环境,请参见:

开发者指南-AWSSDKforJava2.x

票数 0
EN

Stack Overflow用户

发布于 2022-07-15 07:34:08

这是它第一次在5-6秒内对多个请求获取记录,减少了一半。2-3秒仍然是很长的时间,因为只取几个项目。

这是预期的,即使在生产发电机,因为您第一次获取以下操作序列发生:-

  1. 查找来自路由表的请求数据所属的分区ID。
  2. 缓存分区的密钥。
  3. 然后引用用于获取数据的分区。

正如您在步骤2中看到的那样,在下一次请求发生时,从缓存中获取分区id,从而减少延迟。(一旦我有了它,就会分享它的来源)

有人能建议可能的配置来改善这个延迟吗?

此外,请不要使用本地发电机进行性能基准测试,因为它内部使用SQLite,即SQL存储。参考:- https://www.dbi-services.com/blog/aws-dynamodb-local/#:~:text=Yes%2C%20this%20NoSQL%20database%20is,Local%20engine%2C%20embedded%20in%20Java

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72978381

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档