ここ数週間、プロジェクトで DynamoDB をキャッシュとして、またシステムで発生したイベントのリストとして使用し始めました (これを実装するためのより良い代替手段がある理由には立ち入らないでください。 DynamoDB が選択されましたが、結果はありません)。
プロビジョニングされたスループットの制限により、制限を超えるたびに未処理のアイテムを再試行する方法をコードに実装することが期待されているようです。それは理にかなっていますが、バッチ操作やクエリに関して、自分では答えられないように思われる質問も出てきます。
BatchPutItem は簡単に実装できると思います。unprocesseditem を取得した場合は、指数関数的な再試行を使用するだけで、アイテムは最終的に永続化されます。私はこのようなことをしています:
(...)
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);
}
非同期バックグラウンド タスクが DB にデータを入力しているため、これは正常に機能します。
ただし、クエリまたは BatchGetItem の場合は、それほど単純ではありません。エンドユーザーは、DynamoDB 呼び出しの出力を待っています。ここで指数関数的な再試行を行うことはできません。そうしないと、ユーザーが非常に長い間待機する可能性があります。一方で、求めているキーのすべての結果を表示することもできません。
これを処理する正しい方法(私はまともな方法で解決します)について誰か提案がありますか?私は間違った方法で問題に取り組んでいますか?
私は Amazon JavaSDK を使用しています。