Может ли использование инкрементных (но уникальных) Идентификаторы в качестве ключа раздела создают горячие разделы в DynamoDB?

#amazon-web-services #amazon-dynamodb

Вопрос:

Согласно документам, я понимаю, что DynamoDB примет значение предоставленного ключа раздела и пропустит его через функцию хеширования, чтобы решить, в какое физическое местоположение должны поступать данные.

Означает ли это, что запись элементов с последовательным, но уникальным ключом раздела приведет к созданию ключа горячего раздела?

Например, позволит ли вставка элементов со значениями ключа раздела 10001, 10002, 10003, 10004 равномерно распределять данные по разделам?

Или случайное генерирование значения ключа раздела, например UUID, сделает его более равномерно распределенным?

Ответ №1:

DynamoDB поддерживает два разных типа первичных ключей:

  1. Ключ раздела
  2. Ключ раздела ключ сортировки

Ключ раздела

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

Ваши ключи всегда уникальны, внутренняя хэш-функция DynamoDB всегда выводит уникальные хэши, и все ваши данные всегда будут равномерно распределены по логическим и физическим разделам.

Например, это хэш MD5 для 10001: d89f3a35931c386956c1a402a8e09941

Это хэш MD5 для 10002: 9103c8c82514f39d8360c7430c4ee557

Несмотря на то, что 10001 был увеличен только на 1, весь хэш отличается и никоим образом не похож на хэш MD5 для 10002.

С точки зрения последовательного хеширования нет разницы между значениями UUID или инкрементными значениями.

Вы получите горячий раздел только в том случае, если вы очень часто обращаетесь к одному определенному разделу (синоним item здесь), и в этом случае RCU и WCU должны быть установлены правильно, и вам следует подумать о том, чтобы, возможно, реализовать уровень кэширования для часто используемых элементов.


Ключ раздела ключ сортировки

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

Все элементы с одинаковым значением ключа раздела физически хранятся вместе в отсортированном порядке по значению ключа сортировки.

Если у вас нет максимально четких первичных ключей, вы можете создавать горячие разделы.

Позвольте мне привести вам пример:

Веб-сайт электронной коммерции решает создать свою таблицу заказов следующим образом: текущая дата является ключом раздела, а ключ сортировки — идентификатором товара:

  --------------- ---------- 
| Partition Key | Sort Key |
 --------------- ---------- 
| 19/10/2021    | item3000 |
| 19/10/2021    | item3001 |
| 20/10/2021    | item4000 |
 --------------- ---------- 
 

Это может отлично работать в этом масштабе — в приведенном выше примере они обрабатывают 1000 элементов в день, и это работает нормально.

Наступает Черная пятница — 26/11/2021, и теперь у них более 20000 заказов за один день:

  --------------- ----------- 
| Partition Key | Sort Key  |
 --------------- ----------- 
| 26/10/2021    | item6000  |
| 26/10/2021    | item15000 |
| 26/10/2021    | item27000 |
| 27/10/2021    | item27100 |
 --------------- ----------- 
 

Это создаст серьезную проблему с горячими разделами, поскольку все заказы 20000 на 26/10/2021 теперь записываются только в одно значение ключа раздела (как я уже упоминал, элементы с одним и тем же ключом раздела будут храниться вместе).

Ключ раздела 26/11/2021 будет сильно запрашиваться и нагреваться, что снизит производительность базы данных, поскольку вы будете пытаться обрабатывать заказы, и в конечном итоге вы потеряете доход из-за низкой производительности приложения.

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


Если у вас нет ключа сортировки как части вашего первичного ключа, не беспокойтесь о горячих разделах в том смысле, который подразумевается в документации — если у вас есть 1/2 часто используемых элементов, рассмотрите решение для кэширования, например, DAX.

Если у вас есть ключ сортировки как часть вашего первичного ключа, создайте схему таблицы таким образом, чтобы комбинация вашего раздела ключ сортировки была как можно более уникальной и отличительной, чтобы избежать горячих разделов.

Комментарии:

1. ах, невероятное и подробное объяснение. Спасибо!

2. @user1542422 более чем приветствуется, надеюсь, это прояснит ситуацию 🙂

3. Вы сказали: «Если у вас есть первичный ключ только с ключом раздела, вы никогда не столкнетесь с проблемой горячего раздела» Я не верю, что это точно. Раздел считается «горячим», если к нему часто обращаются относительно других разделов. Причиной горячего раздела является дисбаланс в рабочей нагрузке, а не отсутствие ключа сортировки. Горячие разделы возникают в результате несбалансированной рабочей нагрузки, а не независимо от того, является ли ваш первичный ключ простым или составным

4. Я перефразирую @SethGeoghegan, но о горячих разделах в том виде, в котором указано в документации, не следует беспокоиться при использовании ключей разделов — я уточнил.

5. Можете ли вы указать, где в документации об этом говорится? Насколько я понимаю, горячие разделы возникают из-за неравномерного доступа к данным. В качестве крайнего примера представьте, что у вас есть таблица с элементами, первичные ключи которых состоят только из ключа раздела. Затем вы пишете приложение, которое обращается к одному из этих элементов миллионы раз в день, но к другим элементам обращаются только 1-2 раза в день. Этот несбалансированный доступ вызывает горячий раздел в разделе, к которому часто обращаются. Я считаю, что избегать горячих разделов — это значит разрабатывать ваши ключи для равномерного распределения рабочей нагрузки на вашу таблицу. Я ошибаюсь?