Разница между локальными и глобальными индексами в DynamoDB


129

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


1
Ответ в FAQ DynamoDB . Введите запрос «Чем глобальные вторичные индексы отличаются от локальных вторичных индексов?»
markdsievers

1
Не так-то просто найти сейчас в FAQ. Может быть, его реорганизовали
binithb 05

Ответы:


114

Локальные вторичные индексы по-прежнему полагаются на исходный хеш-ключ. Когда вы предоставляете таблицу с хешем + диапазон, думайте о LSI как о хеш + диапазон1, хэш + диапазон2 .. хэш + диапазон6. У вас есть еще 5 атрибутов диапазона для запроса. Кроме того, имеется только одна подготовленная пропускная способность.

Глобальные вторичные индексы определяют новую парадигму - разные хеш-ключи / ключи диапазона для каждого индекса.
Это нарушает первоначальное использование одного хеш-ключа на таблицу. По этой же причине при определении GSI необходимо добавить выделенную пропускную способность для каждого индекса и заплатить за нее.

Более подробную информацию о различиях можно найти в объявлении GSI.


2
Могу добавить 1) вторичные индексы, будь то LSI или GSI, не имеющие ничего общего с уникальностью
user1322092

1
Вам разрешено иметь до 5 локальных вторичных индексов, поэтому Чен Харел говорит: «У вас есть еще 5 атрибутов диапазона для запроса» .
Фелипе Альварес,

93

Вот формальное определение из документации:

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

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

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

  • Пропускная способность:

Локальные вторичные индексы потребляют пропускную способность из таблицы. Когда вы запрашиваете записи через локальный индекс, операция потребляет единицы емкости чтения из таблицы. Когда вы выполняете операцию записи (создание, обновление, удаление) в таблице, имеющей локальный индекс, будут две операции записи, одна для таблицы, другая для индекса. Обе операции будут использовать единицы емкости записи из таблицы.

Глобальные вторичные индексы имеют собственную подготовленную пропускную способность, когда вы запрашиваете индекс, операция будет использовать емкость чтения из индекса, когда вы выполняете операцию записи (создание, обновление, удаление) в таблице с глобальным индексом, будет два операции записи, одна для таблицы, другая для индекса *.

* При определении предоставленной пропускной способности для глобального вторичного индекса убедитесь, что вы уделяете особое внимание следующим требованиям:

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

  • Управление:

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

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

  • Прочтите согласованность:

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

  • Проекция:

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

Особое внимание к уникальности ключей, определенных для вторичных индексов:

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

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


1
« Глобальные вторичные индексы имеют собственную подготовленную пропускную способность, при запросе индекса операция будет использовать емкость чтения из таблицы » - Неверно. Запросы или сканирование глобального вторичного индекса потребляют единицы емкости из индекса, а не из базовой таблицы.
ethanxyz_0 08

1
@bsd Имеет смысл добавить примечание об одном главном ограничении, которое накладывает использование LSI: «Для таблиц с локальными вторичными индексами существует ограничение на размер 10 ГБ для каждого значения ключа раздела. Таблица с локальными вторичными индексами может хранить любые количество элементов, если общий размер для любого значения ключа раздела не превышает 10 ГБ ". ( docs.aws.amazon.com/amazondynamodb/latest/developerguide/… )
wvdz

29

Возможные варианты поиска по индексу:

  • По хешу
  • По хешу + диапазон
  • По хешу + локальный индекс
  • По глобальному индексу
  • По Глобальному индексу + Индекс диапазона

Индексы хэша и диапазона таблицы: это обычные индексы предыдущих версий Amazon AWS SDK.

Глобальные и локальные индексы: это «дополнительные» индексы, созданные для таблицы, в дополнение к существующим хэш-индексам и индексам диапазона таблицы. Глобальный индекс похож на хеш. Индекс диапазона ведет себя так же, как индекс диапазона, используемый с хешем таблицы. В вашей модели сущности в вашем коде геттер должен быть аннотирован следующим образом:

  • Для глобальных индексов:

    @DynamoDBIndexHashKey(globalSecondaryIndexName = INDEX_GLOBAL_RANGE_US_TS)
    @DynamoDBAttribute(attributeName = PROPERTY_USER)
    public String getUser() {
        return user;
    }
    
  • Для индекса диапазона, связанного с глобальным индексом:

    @DynamoDBIndexRangeKey(globalSecondaryIndexName = INDEX_GLOBAL_RANGE_US_TS)
    @DynamoDBAttribute(attributeName = PROPERTY_TIMESTAMP)
    public String getTimestamp() {
        return timestamp;
    }
    

Кроме того, если вы читаете таблицу по глобальному индексу, это должно быть конечное чтение (а не последовательное чтение):

queryExpression.setConsistentRead(false);

20

Можно выразиться так:

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

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

Более подробная информация о типах таблиц и принципах их работы приведена ниже:

Только хеш

Как вы, наверное, уже знаете; сам по себе хеш-ключ должен быть уникальным, поскольку запись в уже существующий хеш-ключ приведет к перезаписи существующих данных.

Hash + Диапазон

Hash-Key + Range-Key позволяет иметь несколько одинаковых хеш-ключей, если у них другой ключ диапазона. В этом случае, если вы пишете в уже существующий Hash-Key, но используете Range-Key, который еще не используется этим Hash-Key, он создает новый элемент, тогда как если элемент с той же комбинацией Hash + Range уже существует, он перезаписывает соответствующий элемент.

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

БИС

LSI в основном такая же, как Hash-Key + Range-Key, и следует тем же правилам при создании элементов, за исключением того, что вы также должны предоставить значения для LSI; их нельзя оставлять пустыми / нулевыми.

Сказать, что LSI - это «Range-Key 2», не совсем правильно, так как у вас не может быть (используя мою аналогию с файлами и форматами ранее) файл с именем: file.format.lsiи file.format.lsi2. Однако вы можете иметь file.format.lsiи file.format2.lsiили file.format.lsiи file2.format.lsi.

По сути, LSI - это просто «ключ фильтра», а не фактический ключ диапазона; ваша базовая комбинация значений Hash и Range должна быть уникальной, в то время как значения LSI не обязательно должны быть уникальными. Более простой способ взглянуть на это - представить LSI как данные в файлах. Вы можете написать код, который находит все файлы с именем «PROJECT101», независимо от их fileFormat, а затем считывает данные внутри, чтобы определить, что следует включить в запрос, а что опустить. В основном так работает LSI (только без дополнительных затрат на открытие файла для чтения его содержимого).

GSI

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

Итак, для GSI вы можете указать fileNameкак базовый хэш-ключ, так и fileFormatкак базовый ключ диапазона. Затем вы можете указать GSI с хеш-ключом fileName2и диапазоном fileFormat2. Затем вы можете запросить либо, fileNameлибо, fileName2если хотите, в отличие от LSI, где вы можете запрашивать только fileName.

Основные преимущества заключаются в том, что вам нужно поддерживать только одну таблицу вместо двух, и каждый раз, когда вы пишете либо в основной хэш / диапазон, либо в GSI Hash / Range (ы), другие (и) также будут автоматически обновлены, поэтому вы не можете «забыть» обновить другие таблицы, как при настройке с несколькими таблицами. Кроме того, нет шансов на потерю соединения после обновления одного и перед обновлением другого, как при настройке с несколькими таблицами.

Кроме того, GSI может «перекрывать» базовую комбинацию хэша / диапазона. Так что если вы хотите сделать таблицу с fileNameи в fileFormatкачестве базового Hash / Range и filePriorityи в fileNameкачестве GSI, вы можете.

Наконец, комбинация GSI Hash + Range не обязательно должна быть уникальной, в то время как базовая комбинация Hash + Range должна быть уникальной. Это то, что невозможно при настройке двух / нескольких столов, но это возможно с GSI. В результате при обновлении вы ДОЛЖНЫ предоставить значения как для базового, так и для GSI Hash + Range; ни одно из этих значений не может быть пустым / нулевым.


13

Другой способ объяснения: LSI помогает выполнять дополнительные запросы к элементам с тем же хеш-ключом. GSI помогает вам делать аналогичные запросы по элементам «по всей таблице». Очень полезно.

Если у вас есть таблица профиля пользователя: unique-id, name, email. Здесь, если вам нужно сделать таблицу доступной для запросов по имени, электронной почте - тогда единственный способ - сделать их GSI (LSI не поможет)


1

Этот документ дает довольно хорошее объяснение:

https://aws.amazon.com/blogs/aws/now-available-global-secondary-indexes-for-amazon-dynamodb/

Я не мог прокомментировать этот вопрос, но он лучше с точки зрения производительности записи и чтения:

(Локальный индекс с пропускной способностью чтения и записи таблицы 100) или (Глобальный индекс с пропускной способностью чтения / записи 50 вместе с пропускной способностью чтения / записи таблицы 50?)

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


0

GSI нельзя использовать для последовательного чтения.

LSI можно использовать для последовательного чтения, но они ограничивают размер основного раздела до 10 ГБ. Также LSI могут быть созданы только при создании таблицы.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.