Подтвердить что ты не робот

Как запросить DynamoDB по дате (клавиша диапазона) без очевидного хеш-ключа?

Мне нужно сохранить локальные данные в приложении iOS в синхронизации с данными в таблице DynamoDB. Таблица DynamoDB представляет собой ~ 2K строк с только хэш-ключом (id) и следующими атрибутами:

  • id (uuid)
  • lastModifiedAt (временная метка)
  • name
  • latitude
  • longitude

В настоящее время я просматриваю и фильтрую lastModifiedAt, где lastModifiedAt больше, чем последняя дата обновления приложения, но я думаю, что это станет дорогостоящим.

Самый лучший ответ, который я могу найти, - это добавить глобальный вторичный индекс с lastModifiedAt в качестве диапазона, но нет явного хэш-ключа для GSI.

Что лучше всего делать при запросе по диапазону с использованием GSI, но нет очевидного хеш-ключа?. Альтернативно, если полное сканирование является единственным вариантом, есть ли какие-либо рекомендации по сохранению вниз стоимость?

4b9b3361

Ответ 1

В то время как ответ Д.Шаули помог мне указать в правильном направлении, он пропустил два соображения для GSI:

  • Диапазон hash + должен быть уникальным, но дневная + временная метка (его рекомендуемый подход) не обязательно будет уникальной.
  • Используя только день в качестве хэша, мне нужно будет использовать большое количество запросов для получения результатов за каждый день с момента последнего обновления (это может быть месяцы или годы назад).

Таким образом, вот подход, который я принял:

  • Создан глобальный вторичный индекс (GSI) с хеш-ключом как YearMonth (например, 201508) и диапазон как id
  • Запросить GSI несколько раз, по одному запросу за каждый месяц с момента последнего обновления. Запросы также фильтруются с помощью lastModifiedAt > [given timestamp].

Ответ 2

Несмотря на то, что Global Secondary Index соответствует вашим требованиям, любая попытка включить связанную информацию timestamp как часть вашего Hash Key скорее всего создаст так называемый "горячий раздел", что крайне нежелательно.

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

Подробнее см. в документации:

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

В соответствии с тем, что указано, id, по-видимому, является хорошим выбором для вашего Hash Key (aka. Partition Key), я бы не изменил его, поскольку ключи GSI работают так же, как и секционирования. В качестве отдельной заметки производительность сильно оптимизирована, когда вы извлекаете данные, предоставляя весь Primary Key, поэтому мы должны попытаться найти решение, которое обеспечивает это, когда это возможно.

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

а. Ваши ежедневные обновления могут храниться в таблицах со следующим соглашением об именах: updates_DDMM

б. Таблицы updates_DDMM имели бы только id (хеш-ключи другой таблицы)

Теперь скажите, что последняя дата обновления приложения была от 2 дней назад (04/07/16), и вам нужно получить последние записи, тогда вам понадобится:

я. Сканируйте таблицы updates_0504 и updates_0604, чтобы получить все хэш-ключи.

II. Наконец, получите записи из основной таблицы (содержащие lat/lng, имя и т.д.), Отправив BatchGetItem со всеми полученными хэш-ключами.

BatchGetItem является супер быстрым и выполняет работу, как никакая другая операция.

Можно утверждать, что создание дополнительных таблиц приведет к увеличению стоимости вашего общего решения... ну, с GSI вы по существу дублируете свою таблицу (в случае, если вы проектируете все поля) и добавляете, что дополнительные затраты для всех ~ 2k записи, будучи недавно обновленными или нет...

Кажется, что это интуитивно понятное создание таблиц, как это, но на самом деле это лучшая практика при работе с данными временных рядов (из документации AWS DynamoDB):

[...] приложения могут отображать неравномерный шаблон доступа по всем элементам в таблице, где последние данные клиента более актуальны, и ваши приложение может чаще обращаться к последним и чаще эти предметы менее доступны, в конечном итоге старые элементы редко доступ к ним. Если это известный шаблон доступа, вы можете принять его при разработке схемы таблиц. Вместо сохраняя все элементы в одной таблице, вы можете использовать несколько таблиц для Храните эти предметы. Например, вы можете создавать таблицы для хранения ежемесячные или еженедельные данные. Для таблицы хранения данных из последних месяц или неделя, где скорость доступа к данным высока, запрос выше пропускной способности и для таблиц, хранящих старые данные, вы можете набрать пропускной способности и экономии ресурсов.

Вы можете сохранять ресурсы, сохраняя "горячие" элементы в одной таблице с помощью более высокие значения пропускной способности и "холодные" элементы в другой таблице с более низкие параметры пропускной способности. Вы можете удалить старые элементы, просто удалив столы. Вы можете при необходимости скопировать эти таблицы в другое хранилище такие как Amazon Simple Storage Service (Amazon S3). Удаление целая таблица значительно эффективнее, чем удаление элементов один за другим, что существенно удваивает пропускную способность записи, как вы это делаете как много операций удаления, как операции ввода.

Источник: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html

Надеюсь, это поможет. С наилучшими пожеланиями.

Ответ 3

Вы можете использовать "дневную" часть метки времени как хеш и использовать всю метку времени в качестве диапазона.