【问题标题】:What's a good practice for dealing with DynamoDB batchGetItem's unprocessedKeys处理 DynamoDB batchGetItem 的 unprocessedKeys 有什么好的做法
【发布时间】:2017-01-23 11:36:22
【问题描述】:

过去几周,我们在项目中开始使用 DynamoDB,既可以作为缓存,也可以作为系统中发生的事件列表(请不要讨论为什么有更好的替代方案来实现这一点,我曾争论过)我在选择 DynamoDB 之前没有结果)。

似乎由于预置的吞吐量限制,我希望在我的代码中实现一种在超出限制时重试未处理项目的方法。这是有道理的,但它也提出了关于批处理操作或查询的问题,我似乎无法自己回答。

我认为 BatchPutItem 很容易实现。如果我得到未处理的项目,我只需使用指数重试,这些项目最终将被持久化。我正在做这样的事情:

(...)
BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(new TableWriteItems(tableName).withItemsToPut(items));
processUnprocessed(outcome, 0);
(...)

private void processUnprocessed(BatchWriteItemOutcome outcome, int retryNumber) {

    if (MapUtils.isEmpty(outcome.getUnprocessedItems())) {
        return;
    }

    if (retryNumber > maxRetries) {
        log.error(Joiner.on(" ").join("Unable to process", outcome.getUnprocessedItems().size(), "items after", retryNumber, "tries"));
        return;
    }

    long retryTime = (long)Math.pow(retryFactor, retryNumber);
    log.info("Exceeded provisioning throughput. Retrying in " + retryTime);

    try {
        Thread.sleep(retryTime);
    } catch (InterruptedException e) {
        log.error(e.getMessage());
    }

    processUnprocessed(dynamoDB.batchWriteItemUnprocessed(outcome.getUnprocessedItems()), ++retryNumber);
}

因为异步后台任务正在填充数据库,所以工作正常。

但是,对于查询或 BatchGetItem,它并不是那么简单。最终用户正在等待 DynamoDB 调用的输出。我不能在这里进行指数重试,否则用户可能会等待很长时间。另一方面,我也不能不显示我要求的键的所有结果。

有没有人对处理这个问题的正确方法(我会选择一种体面的方法)有任何建议? 我是否以错误的方式处理问题?

顺便说一句,我正在使用 Amazon JavaSDK。

【问题讨论】:

    标签: java amazon-dynamodb aws-java-sdk


    【解决方案1】:

    不是我提出的问题的真正答案(我真的不认为有一个,请随时纠正我),但我重新设计了我思考问题的方式,它实际上感觉就像一个精心设计的解决方案,一点也不hacky。仔细想想就很明显了,但是这几天我完全想念它,所以我认为它值得分享。

    我最终只为 GetBatchItem 将重试逻辑放在客户端上,以便我可以显示可以立即检索的结果。我的后端代码 100% 没有任何未处理项目的重试逻辑。

    如您所料,我的后端端点返回一个项目列表和一个未处理密钥列表。

    {
      "items": [{
         "myPartitionKey": "whatever",
         "mySortKey": "whocares",
         "item": "myitem"
       }, (...)],
       "unprocessedKeys": [{
         "pKey": "unprocessed1"
         "sKey": "blah"
       }, (...)]
    }
    

    然后由我的 ReactJs 客户端根据成功接收的数据部分更新 UI,并仅使用丢失的键再次调用相同的服务,并使用某种指数退避。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-28
      • 1970-01-01
      • 1970-01-01
      • 2018-07-14
      • 2019-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多