DynamoDB在本地计算机上的保存操作非常慢

时间:2018-08-15 12:16:42

标签: java amazon-dynamodb

我正在尝试在本地计算机上使用DynamoDB。 在我使用MongoDB之前,与之相比DynamoDB的性能非常差。 保存到表需要很长时间,对于100条记录大约需要13秒。 记录很小,下面是示例。 这是我完整的示例和用于运行它的代码:

public class dynamoTry {
    private AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
            .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-east-2"))
            .build();
    private DynamoDB dynamoDB = new DynamoDB(client);
    private DynamoDBMapper mapper = new DynamoDBMapper(client);

    public static void main(String[] args) {
        dynamoTry dt = new dynamoTry ();
        dt .deleteTable();
        dt .buildGrid();

        dt .demoFill();
        dt .scanTable();    
    }

    public void buildGrid() {
        System.out.println("Attempting to create table; please wait...");

        String tableName = "Grid";

        List<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>();
        attributeDefinitions.add(new AttributeDefinition().withAttributeName("name").withAttributeType(ScalarAttributeType.S));
        attributeDefinitions.add(new AttributeDefinition().withAttributeName("country").withAttributeType(ScalarAttributeType.S));

        List<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>();
        keySchema.add(new KeySchemaElement().withAttributeName("name").withKeyType(KeyType.HASH));
        keySchema.add(new KeySchemaElement().withAttributeName("country").withKeyType(KeyType.RANGE));

        CreateTableRequest request = new CreateTableRequest().withTableName(tableName).withKeySchema(keySchema)
                .withAttributeDefinitions(attributeDefinitions).withProvisionedThroughput(
                    new ProvisionedThroughput().withReadCapacityUnits(500L).withWriteCapacityUnits(500L));

        Table table = dynamoDB.createTable(request);

        try {
            table.waitForActive();
            System.out.println("Success.");
        } catch (InterruptedException e) {e.printStackTrace();}

    }

    public void demoFill() {
        final List<GridPoint> gpl = new ArrayList<GridPoint>();
        int count = 0;

        while (count < 100) {
            final String point = "point" + count;

            gpl.add(makeGP(point, count, "continent", "country", new HashSet<Double>(Arrays.asList(22.23435, 37.89746))));

            count++;
        }

        long startTime = System.nanoTime();
        addBatch(gpl);
        long endTime = System.nanoTime();
        long duration = (endTime - startTime)/1000000; 
        System.out.println(duration + " [ms]");
    }

    public void addBatch(List<GridPoint> gpl) {
        mapper.batchSave(gpl);
    }

    public GridPoint makeGP(String name, int sqNum, String continent, String country, HashSet<Double> cords) {
        GridPoint item = new GridPoint();
        item.setName(name);
        item.setSqNum(sqNum);
        item.setContinent(continent);
        item.setCountry(country);
        item.setCoordinates(cords);

        return item;
    }

    public void scanTable() {
        Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
        eav.put(":val", new AttributeValue().withN("0"));
        DynamoDBScanExpression scanExpression = new DynamoDBScanExpression().withFilterExpression("sqNum >= :val").withExpressionAttributeValues(eav);
        List<GridPoint> scanResult = mapper.scan(GridPoint.class, scanExpression);
        for (GridPoint gp : scanResult) {
            System.out.println(gp);
        }
    }

    public void deleteTable() {
        Table table = dynamoDB.getTable("Grid");

        try {
            System.out.println("Attempting to delete table 'Grid', please wait...");
            table.delete();
            table.waitForDelete();
            System.out.print("Success.");
        }
        catch (Exception e) {
            System.err.println("Unable to delete table: ");
            System.err.println(e.getMessage());
        }
    }

}

这是GridPoint类的代码:

@DynamoDBTable(tableName = "Grid")
public class GridPoint {
    private String name;
    private int sqNum;
    private String continent;
    private String country;
    private HashSet<Double> coordinates; // [longitude, latitude]

    // Partition key
    @DynamoDBHashKey(attributeName = "name")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @DynamoDBAttribute(attributeName = "sqNum")
    public int getSqNum() {
        return sqNum;
    }
    public void setSqNum(int sqNum) {
        this.sqNum = sqNum;
    }

    @DynamoDBAttribute(attributeName = "continent")
    public String getContinent() {
        return continent;
    }
    public void setContinent(String continent) {
        this.continent = continent;
    }

    @DynamoDBAttribute(attributeName = "country")
    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }

    @DynamoDBAttribute(attributeName = "coordinates")
    public HashSet<Double> getCoordinates() {
        return coordinates;
    }
    public void setCoordinates(HashSet<Double> coordinates) {
        this.coordinates = coordinates;
    }

    @Override
    public String toString() {
        return "GP {name = " + name + ", sqNum = " + sqNum + ", continent = " + continent + ", country = " + country
            + ", coordinates = " + coordinates.toString() + "}";
    }

}

为什么这么慢?有什么办法可以加快写作过程吗? 在MongoDB中,相同的操作将花费不到一秒钟的时间。 当我运行它大约3000点时,花了几分钟才完成,这似乎是不合理的。 是否可以使批量保存过程并行进行?会加快速度吗? 我还尝试将ProvisionedThroughput参数设置为更高的值,但这没有帮助。 我迷路了,任何帮助将不胜感激,谢谢。

2 个答案:

答案 0 :(得分:1)

它很慢,因为它不是DynamoDB。没有本地DynamoDB!

DynamoDB是AWS提供的一项托管服务,它确实非常快(第一个字节为毫秒),高度可扩展且持久。这是一款性能非常不错的好产品,仅需少量金钱。但这是一项托管服务。它仅适用于AWS环境。您或其他任何人都无法获得副本并在Azure,GCP甚至您的本地环境中安装DynamoDB。

您正在使用的是门面,可能是由AWS Team开发以帮助开发人员测试其应用程序。还有其他DynamoDB外观,不是由AWS Team开发的,但那时的每个人都遵循一种协议,该协议接受来自原始产品的所有api调用。作为立面,他的目标只是提供一个可以接收您的呼叫并像原始产品一样做出响应的终结点。如果您致电原始DynamoDB将以“ OK”响应,则外观将以“ Ok”响应。如果您打电话说原始DynamoDB将以失败响应,则外观将向您发送失败。

在性能或数据持久性方面没有任何妥协。如果您需要性能持久的持久数据库,则必须使用MongoDB。 DynamoDB创建为仅在AWS环境中使用。

再次:没有像DynamoDB local这样的东西。

答案 1 :(得分:-1)

DynamoDB已预定义limits。您可能会遇到这些限制。考虑增加表的WriteCapacityUnits来提高性能。您可能还想增加ReadCapacityUnits进行扫描。