10

DynamoDBテーブルのすべてのアイテムを反復処理しようとしています。(これは非効率的なプロセスであることを理解していますが、インデックステーブルを作成するためにこれを1回だけ実行しています。)

DynamoDBのscan()関数が1MBまたは指定された制限のいずれか小さい方を返すことを理解しています。これを補うために、「LastEvaluatedKey」の結果を検索し、LastEvaluatedKeyから再クエリしてすべての結果を取得する関数を作成しました。

残念ながら、関数がループするたびに、データベース全体のすべてのキーがスキャンされ、割り当てられた読み取りユニットがすぐに使い果たされてしまうようです。非常に遅いです。

これが私のコードです:

def search(table, scan_filter=None, range_key=None,
           attributes_to_get=None,
           limit=None):
    """ Scan a database for values and return
        a dict.
    """

    start_key = None
    num_results = 0
    total_results = []
    loop_iterations = 0
    request_limit = limit

    while num_results < limit:
        results = self.conn.layer1.scan(table_name=table,
                                  attributes_to_get=attributes_to_get,
                                  exclusive_start_key=start_key,
                                  limit=request_limit)
        num_results = num_results + len(results['Items'])
        start_key = results['LastEvaluatedKey']
        total_results = total_results + results['Items']
        loop_iterations = loop_iterations + 1
        request_limit = request_limit - results['Count']

        print "Count: " + str(results['Count'])
        print "Scanned Count: " + str(results['ScannedCount'])
        print "Last Evaluated Key: " + str(results['LastEvaluatedKey']['HashKeyElement']['S'])
        print "Capacity: " + str(results['ConsumedCapacityUnits'])
        print "Loop Iterations: " + str(loop_iterations)

    return total_results

関数の呼び出し:

db = DB()
results = db.search(table='media',limit=500,attributes_to_get=['id'])

そして私の出力:

Count: 96
Scanned Count: 96
Last Evaluated Key: kBR23QJNAwYZZxF4E3N1crQuaTwjIeFfjIv8NyimI9o
Capacity: 517.5
Loop Iterations: 1
Count: 109
Scanned Count: 109
Last Evaluated Key: ATcJFKfY62NIjTYY24Z95Bd7xgeA1PLXAw3gH0KvUjY
Capacity: 516.5
Loop Iterations: 2
Count: 104
Scanned Count: 104
Last Evaluated Key: Lm3nHyW1KMXtMXNtOSpAi654DSpdwV7dnzezAxApAJg
Capacity: 516.0
Loop Iterations: 3
Count: 104
Scanned Count: 104
Last Evaluated Key: iirRBTPv9xDcqUVOAbntrmYB0PDRmn5MCDxdA6Nlpds
Capacity: 513.0
Loop Iterations: 4
Count: 100
Scanned Count: 100
Last Evaluated Key: nBUc1LHlPPELGifGuTSqPNfBxF9umymKjCCp7A7XWXY
Capacity: 516.5
Loop Iterations: 5

これは予想される動作ですか?または、私は何が間違っているのですか?

4

1 に答える 1

5

短い答え

あなたは何も悪いことをしていません

長い答え

これは、Amazonが容量単位を計算する方法と密接に関連しています。まず、次のことを理解することが非常に重要です。

  • capacity units == reserved computational units
  • capacity units != reserved network transit

まあ、それでも厳密に言えば正確ではありませんが、特にそれに関しては非常に近いScanです。

手術中Scan、基本的な違いがあります

  • スキャンされたアイテム:累積サイズは最大limit1MBですが、すでに到達している場合はそのサイズを下回る可能性があります
  • 返されたアイテム:スキャンされたアイテムの すべての一致するアイテム

capacity unit計算単位であるため、スキャンしたアイテムの料金を支払います。さて、実際には、スキャンされたアイテムの累積サイズに対して支払います。このサイズには、すべてのストレージとインデックスのオーバーヘッドが含まれることに注意してください...0.5 capacity / cumulated KB

スキャンされるサイズは、フィールドセレクターであれ結果フィルターであれ、フィルターに依存しません。

あなたの結果から、あなたのアイテムはそれぞれ約10KBを必要とし、実際のペイロードサイズに関するあなたのコメントが確認する傾向があると思います。

もう一つの例

非常に小さな要素のみを含むテストテーブルがあります。1.0スキャンは100アイテムを取得するために容量ユニットのみを消費します。cumulated size < 2KB

于 2012-08-30T19:19:12.363 に答える