Різниця між локальними та глобальними показниками в DynamoDB


128

Мені цікаво ці два вторинні індекси та відмінності між ними. Важко уявити, як це виглядає. І я думаю, це допоможе більше людям, ніж тільки мені.


1
Відповів в DynamoDB FAQ . Шукайте "Як глобальні вторинні індекси відрізняються від локальних вторинних індексів?"
markdsievers

1
Зараз не так просто знайти в FAQ. Можливо, це реорганізовано
бінітб

Відповіді:


114

Місцеві вторинні індекси все ще покладаються на оригінальний ключ Hash. Подаючи таблицю з діапазоном хеш +, подумайте про LSI як хеш + діапазон1, хеш + діапазон2 .. хеш + діапазон6. Ви отримуєте ще 5 атрибутів діапазону для запиту. Крім того, існує лише одна передбачена пропускна здатність.

Global Secondary Indexes визначає нову парадигму - різні хеш / діапазони ключів на індекс.
Це порушує початкове використання одного хеш-ключа на таблицю. Це також, чому при визначенні GSI вам потрібно додати умовну пропускну здатність на індекс і оплатити його.

Більш детальну інформацію про відмінності можна знайти в оголошенні GSI


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

1
У вас може бути до 5 локальних вторинних індексів, тому Чен Харел каже: "Ви отримуєте ще 5 атрибутів діапазону для запиту" .
Феліпе Альварес

93

Ось формальне визначення з документації:

Глобальний вторинний індекс - індекс з ключем хешу та діапазону, який може відрізнятися від таблиць. Глобальний вторинний індекс вважається "глобальним", оскільки запити щодо індексу можуть охоплювати всі дані в таблиці, на всіх розділах.

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

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

  • Пропускна здатність:

Місцеві вторинні індекси споживають пропускну здатність з таблиці. Коли ви запитуєте записи через локальний індекс, операція споживає одиниці потужності зчитування з таблиці. Під час виконання операції запису (створення, оновлення, видалення) у таблиці, що має локальний індекс, буде дві операції запису, одна для таблиці, інша для індексу. Обидві операції будуть споживати одиниці потужності запису з таблиці.

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

* Визначаючи забезпечену пропускну здатність для Глобального вторинного індексу, обов'язково зверніть особливу увагу на такі вимоги:

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

  • Управління:

Локальні вторинні індекси можна створити лише тоді, коли ви створюєте таблицю, немає можливості додати локальний вторинний індекс до існуючої таблиці, також коли ви створюєте індекс, ви не можете його видалити.

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

  • Прочитайте послідовність:

Місцеві вторинні індекси підтримують можливу або міцну послідовність, тоді як глобальний вторинний індекс підтримує лише можливу узгодженість.

  • Проекція:

Локальні вторинні індекси дозволяють отримувати атрибути, які не проектуються на індекс (хоча з додатковими витратами: одиниці продуктивності та споживаної потужності). За допомогою Global Secondary Index ви можете отримати лише атрибути, спроектовані на індекс.

Спеціальне врахування щодо унікальності ключів, визначених для вторинних показників:

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

Джерело: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html


1
" Глобальні вторинні індекси мають власну забезпечену пропускну здатність, коли ви запитуєте індекс, операція буде споживати ємність зчитування з таблиці " - Неправильно. Запити або сканування глобального вторинного індексу споживають одиниці потужності з індексу, а не з базової таблиці.
ethanxyz_0

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

29

Це можливі пошуки за індексом:

  • За Хеш
  • По діапазону Hash +
  • За допомогою Hash + Local Index
  • За глобальним індексом
  • За глобальним індексом + індекс діапазону

Індекси хеш-та діапазону таблиці: Це звичайні індекси попередніх версій 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-Key + Range-Key дозволяє вам мати декілька однакових клавіш, якщо вони мають інший діапазонний ключ. У цьому випадку, якщо ви пишете на Hash-Key, який вже існує, але використовуєте Range-Key, який ще не використовується цим Hash-ключем, він створює новий елемент, тоді як якщо елемент із тією ж комбінацією Hash + Range вже існує, він перезаписує відповідний елемент.

Ще один спосіб подумати про це - як файл із форматом. Ви можете мати файл з тим самим іменем (хеш), як інший, в тій же папці (таблиці), якщо їх формат (діапазон) відрізняється. Так само ви можете мати декілька файлів одного формату, якщо їх ім’я відрізняється.

LSI

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 .

Основні переваги полягають у тому, що вам потрібно підтримувати лише одну таблицю, а не 2, і в будь-який час ви пишете або в основний хеш / діапазон, або в хеш / діапазон GSI, інші (і) автоматично також буде оновлено, тому ви не можете "забути" оновити іншу таблицю (ів), як можна, за допомогою налаштування кількох таблиць. Крім того, немає жодного шансу втратити з'єднання після оновлення одного та перед оновленням іншого, як це відбувається при налаштуванні мультитаблиці.

Крім того, GSI може "перекривати" базову комбінацію Hash / Range. Так що якщо ви хочете зробити таблицю з fileNameі в fileFormatякості базового Hash / Range і filePriorityіfileName в якості GSI, ви можете.

Нарешті, комбінація GSI Hash + Range не повинна бути унікальною, тоді як базова комбінація Hash + Range повинна бути унікальною. Це неможливо при установці подвійних / мульти таблиць, але це стосується GSI. Як результат, ви ОБОВ'ЯЗКОВО надаєте значення як для базового, так і для GSI Hash + діапазону під час оновлення; жодне з цих значень не може бути порожнім / нульовим.


13

Ще один спосіб пояснити: LSI допомагає робити додаткові запити щодо елементів із тим самим ключем Hash. GSI допомагає виконувати подібні запити щодо предметів "через стіл". Так дуже корисно.

Якщо у вас є таблиця профілів користувача: унікальний ідентифікатор, ім’я, електронна пошта. Тут, якщо вам потрібно зробити таблицю вичерпною за назвою, електронною поштою - тоді єдиний спосіб - зробити їх 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.