Почему мой DynamoDB сканирует так быстро, имея только 1 выделенную единицу емкости чтения?

Aug 19 2020

Я сделал таблицу из 1346 элементов, каждый из которых был размером менее 4 КБ. Я выделил 1 единицу емкости чтения, поэтому я ожидал, что в среднем будет читать 1 элемент в секунду. Однако простое сканирование всех 1346 элементов возвращается почти сразу.

Что мне здесь не хватает?

Ответы

4 ChrisWilliams Aug 19 2020 at 14:24

Вероятно, это связано с пакетной емкостью, при которой вы получаете свою емкость за период 300 секунд для использования для пакетных действий (таких как сканирование всей таблицы).

Это означало бы, что если бы вы использовали все эти кредиты, другие взаимодействия пострадали бы, поскольку им не хватило бы доступной мощности.

Вы можете увидеть количество использованных WCU / RCU либо с помощью метрик CloudWatch, либо в самом интерфейсе DynamoDB (на вкладке «Метрики»).

2 Charles Aug 19 2020 at 22:43

Вы не указываете размер ваших записей, кроме как сказать «каждый элемент меньше 4 КБ». Насколько меньше?

1 RCU будет поддерживать 2 последовательных чтения в секунду для элементов размером до 4 КБ.

Другими словами, с 1 RCU и, в конечном итоге, последовательными чтениями вы можете читать 8 КБ данных в секунду.

Если ваши записи имеют размер 4 КБ, то вы получите 2 записи / сек
1 КБ, 8 / сек
512 Б, 16 / сек 256 Б
, 32 / сек

Таким образом, уже упомянутая возможность «пакетной передачи» позволила вам использовать 55 RCU. Но небольшой размер ваших записей позволил 55 RCU вернуть данные «почти сразу».

1 NadavHar'El Aug 20 2020 at 18:01

Здесь есть две вещи, которые работают в вашу пользу: первая заключается в том, что Scanоперация требует значительно меньше RCU, чем вы думали, для небольших элементов. Другое дело - «взрывная мощность». Я попытаюсь объяснить оба:

На странице цен DynamoDB указано, что «Для элементов размером до 4 КБ один RCU может выполнять два согласованных запроса чтения в секунду». Это говорит о том, что даже если размер элемента составляет 10 байт, его прочтение с конечной согласованностью будет стоить половину RCU. Однако, хотя они нигде не заявляют об этом, эта стоимость верна только для GetItemоперации по извлечению одного элемента. В Scanили Queryоказывается, что вы не платите отдельно за каждую единицу товара. Вместо этого эти операции последовательно сканируют данные, хранящиеся на диске, и вы платите за объем прочитанных таким образом данных. Если у вас 1000 крошечных элементов и общий размер, который DynamoDB должен было прочитать с диска, составлял 80 КБ, вы заплатите 80 КБ / 4 КБ / 2 или 10 RCU, а не 500 RCU.

Это объясняет, почему вы прочитали 1346 пунктов и измерили только 55 RCU, а не 1346/2 = 673.

Второе, что работает в вашу пользу, - это то, что DynamoDB имеет возможность «увеличения емкости», описанную здесь :

DynamoDB в настоящее время сохраняет до 5 минут (300 секунд) неиспользуемой емкости для чтения и записи. Во время периодического всплеска операций чтения или записи эти дополнительные единицы емкости могут быть использованы быстро - даже быстрее, чем выделенная пропускная способность в секунду, которую вы определили для своей таблицы.

Итак, если ваша база данных существовала за 5 минут до вашего запроса, DynamoDB сохранил для вас 300 RCU, которые вы можете использовать очень быстро. Поскольку 300 RCU - это намного больше, чем вам нужно для сканирования (55), сканирование выполняется очень быстро, без дросселирования.

1 SudhirJonathan Aug 24 2020 at 13:45

Когда вы выполняете запрос, счетчик RCU применяется к количеству прочитанных данных без учета количества прочитанных элементов. Поэтому, если ваши элементы небольшие, скажем, несколько байтов каждый, их можно легко запросить в одном RCU 4 КБ.

Это особенно полезно при чтении многих элементов из DynamoDB. Не сразу очевидно, что запрос множества мелких элементов намного дешевле и эффективнее, чем их BatchGetting.