我正在尝试调用BatchGetItem从DynamoDB检索项目。作为输入,我们可以获得多达1000个按键(或少至1个按键)的列表。这些键与我们的DynamoDB表的hashKey一致。
由于BatchGetItem API每次调用最多只能容纳100个项目,因此我试图将请求拆分为每个仅包含100个项目的批处理,并行进行调用,然后将结果再次合并为一个Set。
对于那些不熟悉DynamoDB的人,他们仍然可以就精简版提供建议(第一个示例),我将不胜感激!否则,请参见下面的第二个更准确的示例。
第一个示例-精简
public Set<SomeResultType> retrieveSomething(Set<String> someSet) {
ImmutableSet.Builder<SomeResultType> resultBuilder = ImmutableSet.builder();
// FIXME - how to parallelize?
for (List<Map<String, String>> batch : Iterables.partition(someSet, 100)) {
result = callSomeLongRunningAPI(batch);
resultBuilder.addAll(result.getItems());
}
return resultBuilder.build();
}
第二个示例-更接近我的实际问题- 以下是我目前正在做的精简版虚拟版本(因此,请原谅格式/样式问题)。它目前可以工作并获取所有项目,但是我不知道如何获取批处理(请参阅FIXME)以并行执行并最终形成一个集合。由于性能在我要构建的系统中非常重要,因此帮助该代码更高效的任何技巧都将不胜感激!
public Set<SomeResultType> retrieveSomething(Set<String> someIds) {
if (someIds.isEmpty()) {
// handle this here
}
Collection<Map<String, AttributeValue>> keyAttributes = someIds.stream()
.map(id -> ImmutableMap.<String, AttributeValue>builder()
.put(tableName, new AttributeValue().withS(id)).build())
.collect(ImmutableList.toImmutableList());
ImmutableSet.Builder<SomeResultType> resultBuilder = ImmutableSet.builder();
Map<String, KeysAndAttributes> itemsToProcess;
BatchGetItemResult result;
// FIXME - make parallel?
for (List<Map<String, AttributeValue>> batch : Iterables.partition(keyAttributes, 100)) {
KeysAndAttributes keysAndAttributes = new KeysAndAttributes()
.withKeys(batch)
.withAttributesToGet(...// some attribute names);
itemsToProcess = ImmutableMap.of(tableName, keysAndAttributes);
result = this.dynamoDB.batchGetItem(itemsToProcess);
resultBuilder.addAll(extractItemsFromResults(tableName, result));
}
return resultBuilder.build());
}
非常感谢您提供有关超级精简案例或第二个示例的帮助!谢谢!