AWS DynamoDB — использовать GSI или сканирование, если я просто хочу запросить таблицу по дате

#amazon-web-services #amazon-dynamodb

#amazon-web-services #amazon-dynamodb

Вопрос:

Мне кажется, что я думаю о себе кругами. Может быть, вы все можете помочь 🙂

Допустим, у меня есть этот простой дизайн таблицы в DynamoDB:

 Id | Employee | Created | SomeExtraMetadataColumns... | LastUpdated  
 

Скажем, мой единственный вариант использования — найти все строки в этой таблице, где lastUpdated < (сейчас — 2 часа).

Предположим, что 99% данных в таблице не будут соответствовать этому критерию. Предположим, что каждые 15 минут выполняется какое-то задание, которое обновляет столбец lastUpdated.

Предположим, что, скажем, 100 000 строк и, возможно, растет на 1000 строк в день. (нет необходимости в большой емкости записи).

Предположим, что один объект будет выполнять этот вариант использования «чтение» (нет необходимости в большой емкости для чтения).

Варианты, которые я могу придумать:

  • Выполните сканирование.

Pro: может использовать параллельные сканирования для масштабирования в будущем.

Против: тратится много денег на чтение строк, которые не соответствуют критериям фильтрации.

  • Добавьте новый столбец с именем ‘Constant’, который всегда будет иметь значение ‘Foo’, и создайте GSI с ключом раздела ‘Constant’ и ключом сортировки lastUpdated. Затем выполните запрос по этому индексу для Constant = ‘Foo’ и lastUpdated < (сейчас — 2 часа).

Pro: запрашивает только строки, соответствующие фильтру. Никаких потраченных впустую денег.

Против: теоретически это может быть связано с проблемой «горячего раздела», если записи увеличиваются. Но я не уверен, насколько серьезной проблемой это будет, поскольку aws обозначил эту проблему как уходящую в прошлое.

Честно говоря, я склоняюсь к последнему варианту. Но мне любопытно, что думают сообщества по этому поводу. Возможно, я что-то упускаю.

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

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

2. Эй, Алекс, хороший вызов. Это мой единственный шаблон доступа к этой таблице. Я обновил свой вопрос для большей ясности.

Ответ №1:

Исходя из предположения, что поле last_updated является единственным полем, к которому вам нужно запросить, я бы сделал что-то вроде этого:

 PK: EMPLOYEE::{emp_id}
SK: LastUpdated
Attributes: Employee, ..., Created
 
 PK: EMPLOYEE::UPDATE
SK: LastUpdated::{emp_id}
Attributes: Employee, ..., Created
 

Денормализуя здесь свои данные , вы получаете возможность создать запись обновления со строкой обновления , которую можно запросить с PK = EMPLOYEE::UPDATE помощью и SK between 'datetime' and 'datetime' . Это предполагает, что вы сохраняете дату и время как что -то вроде 2020-10-01T00:00:00Z .

Вы можете либо вставить эту дополнительную строку здесь, либо рассмотреть возможность использования потоков DynamoDB для потоковой передачи событий обновления в Lambda, а затем добавить строку оттуда. Вы можете установить TTL в строке «обновить», срок действия которого истекает где-то между 0 и 48 часами с момента установки TTL для поддержания чистоты таблицы. Его не нужно мгновенно удалять, потому что вы все равно выполняете запросы на основе PK и SK.

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

Вы также можете использовать потоки DynamoDB для передачи ваших данных в хранилища данных, которые подходят для аналитики, чего, я полагаю, вы пытаетесь достичь здесь. Например, вы можете передавать данные в redshift, RDS и т.д. И т.п. Это требует нескольких дополнительных шагов и может принести пользу kinesis в зависимости от масштаба обновлений, но это еще кое-что, что нужно учитывать.

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

PS: Я почти всегда вызываю свои атрибуты PK и SK PK SK и использую их в виде строк, поэтому я могу легко добавлять различные типы данных или денормализации в таблицу.

Ответ №2:

Определенно держитесь подальше от сканирования…

Я бы посмотрел на GSI с

 PK: YYYY-MM-DD-HH
SK: MM-SS.mmmmmm
 

Теперь, чтобы обновить записи за последние два часа, вам нужно сделать всего три запроса.