Różnica między indeksami lokalnymi i globalnymi w DynamoDB

128

Ciekawi mnie te dwa drugorzędne indeksy i różnice między nimi. Trudno sobie wyobrazić, jak to wygląda. Myślę, że pomoże to większej liczbie ludzi niż tylko mnie.

Michael Czolko
źródło
1
Odpowiedzi w FAQ DynamoDB . Wyszukaj hasło „Czym różnią się globalne indeksy pomocnicze od lokalnych indeksów pomocniczych?”
markdsievers
1
Nie jest już tak łatwo znaleźć w FAQ. Może jest to zreorganizowane
binithb

Odpowiedzi:

114

Lokalne indeksy pomocnicze nadal opierają się na oryginalnym kluczu skrótu. Kiedy dostarczasz tabelę z hash + range, myśl o LSI jako hash + range1, hash + range2 .. hash + range6. Otrzymasz 5 dodatkowych atrybutów zakresu do przeszukania. Ponadto istnieje tylko jedna aprowizowana przepływność.

Global Secondary Indexes definiuje nowy paradygmat - różne klucze hash / range na indeks.
To łamie oryginalne użycie jednego klucza skrótu na tabelę. Z tego powodu podczas definiowania GSI wymagane jest dodanie aprowizowanej przepływności na indeks i zapłacenie za nią.

Bardziej szczegółowe informacje o różnicach można znaleźć w komunikacie GSI

Chen Harel
źródło
2
Może chcieć dodać 1) dodatkowe indeksy, czy to LSI, czy GSI, nie mające nic wspólnego z unikalnością
user1322092
1
Możesz mieć do 5 lokalnych indeksów wtórnych, dlatego Chen Harel mówi: „Otrzymujesz 5 dodatkowych atrybutów zakresu do zapytania” .
Felipe Alvarez
93

Oto formalna definicja z dokumentacji:

Globalny indeks pomocniczy - indeks z hashem i kluczem zakresu, które mogą się różnić od tych w tabeli. Globalny indeks pomocniczy jest uważany za „globalny”, ponieważ zapytania w indeksie mogą obejmować wszystkie dane w tabeli na wszystkich partycjach.

Lokalny indeks pomocniczy - indeks, który ma ten sam klucz skrótu co tabela, ale inny klucz zakresu. Lokalny indeks pomocniczy jest „lokalny” w tym sensie, że zakres każdej partycji lokalnego indeksu pomocniczego obejmuje partycję tabeli, która ma ten sam klucz skrótu.

Jednak różnice wykraczają daleko poza możliwości w zakresie kluczowych definicji. Znajdź poniżej kilka ważnych czynników, które będą miały bezpośredni wpływ na koszt i wysiłek związany z utrzymaniem indeksów:

  • Wydajność :

Lokalne indeksy pomocnicze zużywają przepustowość z tabeli. Podczas wykonywania zapytań dotyczących rekordów za pośrednictwem indeksu lokalnego operacja zużywa jednostki pojemności odczytu z tabeli. Kiedy wykonujesz operację zapisu (tworzenie, aktualizowanie, usuwanie) w tabeli, która ma indeks lokalny, będą dwie operacje zapisu, jedna dla tabeli, druga dla indeksu. Obie operacje będą zużywać jednostki pojemności zapisu z tabeli.

Globalne indeksy pomocnicze mają własną aprowizowaną przepustowość, podczas wykonywania zapytania o indeks operacja zużywa pojemność odczytu z indeksu, podczas wykonywania operacji zapisu (tworzenia, aktualizowania, usuwania) w tabeli, która ma indeks globalny, będą dwa operacje zapisu, jedna dla tabeli, druga dla indeksu *.

* Definiując aprowizowaną przepustowość dla globalnego indeksu pomocniczego, należy zwrócić szczególną uwagę na następujące wymagania:

Aby zapis w tabeli się powiódł, udostępnione ustawienia przepływności dla tabeli i wszystkie jej globalne indeksy pomocnicze muszą mieć wystarczającą pojemność zapisu, aby pomieścić zapis; w przeciwnym razie zapis do tabeli zostanie ograniczony.

  • Zarządzanie:

Lokalne indeksy pomocnicze można tworzyć tylko podczas tworzenia tabeli, nie ma możliwości dodania lokalnego indeksu pomocniczego do istniejącej tabeli, również po utworzeniu indeksu nie można go usunąć.

Globalne indeksy pomocnicze można tworzyć podczas tworzenia tabeli i dodawania do istniejącej tabeli, dozwolone jest również usunięcie istniejącego globalnego indeksu dodatkowego.

  • Czytaj spójność:

Lokalne indeksy pomocnicze obsługują ostateczną lub silną spójność, podczas gdy globalny indeks pomocniczy obsługuje tylko spójność ostateczną.

  • Występ:

Lokalne indeksy pomocnicze umożliwiają pobieranie atrybutów, które nie są prognozowane w indeksie (chociaż wiąże się to z dodatkowymi kosztami: wydajnością i zużytą pojemnością). Dzięki Global Secondary Index można pobrać tylko atrybuty rzutowane na indeks.

Szczególna uwaga dotycząca wyjątkowości kluczy zdefiniowanych w indeksach pomocniczych:

W lokalnym indeksie pomocniczym wartość klucza zakresu NIE musi być unikalna dla danej wartości klucza mieszającego, to samo dotyczy globalnych indeksów pomocniczych, wartości klucza (hasz i zakres) NIE muszą być unikalne.

Źródło: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html

bsd
źródło
1
Globalne indeksy pomocnicze mają własną, aprowizowaną przepływność, podczas wysyłania zapytania do indeksu operacja zużywa pojemność odczytu tabeli ” - błąd. Zapytania lub skanowanie w globalnym indeksie pomocniczym zużywają jednostki mocy obliczeniowej z indeksu, a nie z tabeli podstawowej.
ethanxyz_0
1
@bsd Sensowne byłoby dodanie uwagi o jednym głównym ograniczeniu, które nakłada użycie LSI: „W przypadku tabel z lokalnymi indeksami pomocniczymi istnieje limit rozmiaru 10 GB na wartość klucza partycji. Tabela z lokalnymi indeksami pomocniczymi może przechowywać dowolne liczba elementów, o ile całkowity rozmiar dla dowolnej wartości klucza partycji nie przekracza 10 GB. ” ( docs.aws.amazon.com/amazondynamodb/latest/developerguide/… )
wvdz
29

Oto możliwe wyszukiwania według indeksu:

  • Hash
  • Według skrótu + zakresu
  • Według Hash + Local Index
  • Według indeksu globalnego
  • Według indeksu globalnego + indeksu zakresu

Indeksy Hash and Range tabeli: są to zwykłe indeksy poprzednich wersji zestawu Amazon AWS SDK.

Indeksy globalne i lokalne: są to „dodatkowe” indeksy tworzone w tabeli, oprócz istniejących indeksów mieszania i zakresów tabeli. Indeks globalny jest podobny do skrótu. Indeks zakresu zachowuje się podobnie do indeksu zakresu używanego z hashem tabeli. W modelu jednostki w kodzie, metoda pobierająca musi być opisana w następujący sposób:

  • W przypadku indeksów globalnych:

    @DynamoDBIndexHashKey(globalSecondaryIndexName = INDEX_GLOBAL_RANGE_US_TS)
    @DynamoDBAttribute(attributeName = PROPERTY_USER)
    public String getUser() {
        return user;
    }
    
  • Dla indeksu zakresu związanego z indeksem globalnym:

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

Poza tym, jeśli czytasz tabelę według indeksu globalnego, musi to być odczyt ostateczny (nie spójny):

queryExpression.setConsistentRead(false);
Carlos AG
źródło
20

Można to ująć w następujący sposób:

LSI - umożliwia wykonanie zapytania na jednym kluczu Hash przy użyciu wielu różnych atrybutów do „filtrowania” lub ograniczania zapytania.

GSI - umożliwia wykonywanie zapytań na wielu kluczach skrótu w tabeli, ale w rezultacie zwiększa przepustowość.

Bardziej szczegółowe zestawienie typów tabel i ich działania, poniżej:

Tylko hash

Jak zapewne już wiesz; Hash-Key sam w sobie musi być unikalny, ponieważ zapis do już istniejącego Hash-Key spowoduje nadpisanie istniejących danych.

Hash + Range

Hash-Key + Range-Key pozwala na posiadanie wielu takich samych kluczy Hash, o ile mają one inny klucz zakresu. W tym przypadku, jeśli napiszesz do Hash-Key, który już istnieje, ale użyjesz Range-Key, który nie jest już używany przez Hash-Key, tworzy nowy przedmiot, podczas gdy jeśli przedmiot z tą samą kombinacją Hash + Range już istnieje, zastępuje pasujący element.

Można o tym myśleć inaczej, jak o pliku z formatem. Możesz mieć plik o tej samej nazwie (hash) co inny, w tym samym folderze (tabeli), o ile ich format (zakres) jest inny. Podobnie możesz mieć wiele plików w tym samym formacie, o ile ich nazwa jest inna.

LSI

LSI jest w zasadzie tym samym, co Hash-Key + Range-Key i podczas tworzenia elementów stosuje się do tych samych reguł, z wyjątkiem tego, że należy również podać wartości dla LSI; nie mogą być puste / puste.

Stwierdzenie, że LSI to „Klucz zakresu 2” nie jest całkowicie poprawne, ponieważ nie można mieć (używając analogii mojego pliku i formatu z wcześniejszej wersji) pliku o nazwie: file.format.lsii file.format.lsi2. Możesz jednak mieć file.format.lsii file.format2.lsilub file.format.lsii file2.format.lsi.

Zasadniczo LSI jest po prostu „kluczem filtru”, a nie rzeczywistym kluczem zakresu; Twoja podstawowa kombinacja wartości skrótu i ​​zakresu musi nadal być unikalna, podczas gdy wartości LSI wcale nie muszą być unikalne. Łatwiejszym sposobem spojrzenia na to może być myślenie o LSI jako o danych w plikach. Można by napisać kod, który znajdzie wszystkie pliki o nazwie „PROJECT101”, niezależnie od ich fileFormat, a następnie odczyta zawarte w nich dane, aby określić, co powinno być zawarte w zapytaniu, a co pominięte. W zasadzie tak działa LSI (bez dodatkowego obciążenia związanego z otwieraniem pliku w celu odczytania jego zawartości).

GSI

W przypadku GSI zasadniczo tworzysz inną tabelę dla każdego GSI, ale bez kłopotów z utrzymywaniem wielu oddzielnych tabel, które odzwierciedlają dane między nimi; dlatego kosztują więcej przepustowości.

Tak więc dla GSI możesz określić fileNamejako podstawowy klucz skrótu i fileFormatjako podstawowy klucz zakresu. Następnie możesz określić GSI, który ma Hash-Key of fileName2i Range-Key of fileFormat2. Następnie możesz przesyłać zapytania dotyczące jednego fileNamelub fileName2jeśli chcesz, w przeciwieństwie do LSI, w którym można wyszukiwać tylko fileName.

Główną zaletą jest to, że musisz utrzymywać tylko jedną tabelę zamiast 2, a za każdym razem, gdy piszesz do podstawowego skrótu / zakresu lub wartości skrótu / zakresu GSI, pozostałe również zostaną automatycznie zaktualizowane, więc nie można „zapomnieć” o zaktualizowaniu innych stołów, tak jak w przypadku konfiguracji wielostołowej. Ponadto nie ma szans na utratę połączenia po zaktualizowaniu jednego i przed zaktualizowaniem drugiego, tak jak w przypadku konfiguracji wielostołowej.

Ponadto wskaźnik GSI może „zachodzić” na podstawową kombinację mieszania / zakresu. Więc jeśli chcesz utworzyć tabelę z fileNamei fileFormatjako bazowy hash / zakres filePriorityi fileNamejako swój GSI, możesz.

Wreszcie, kombinacja GSI Hash + Range nie musi być unikalna, podczas gdy podstawowa kombinacja Hash + Range musi być niepowtarzalna. Jest to coś, co nie jest możliwe w przypadku konfiguracji z dwoma / wieloma stołami, ale jest w przypadku GSI. W rezultacie, podczas aktualizacji MUSISZ podać wartości zarówno dla podstawowego, jak i GSI Hash + Range; żadna z tych wartości nie może być pusta / zerowa.

DGolberg
źródło
13

Innym sposobem wyjaśnienia: LSI pomaga w wykonywaniu dodatkowych zapytań dotyczących elementów z tym samym kluczem skrótu. GSI pomaga w wykonywaniu podobnych zapytań dotyczących elementów „w poprzek tabeli”. Tak bardzo przydatne.

Jeśli masz tabelę profilu użytkownika: unikalny identyfikator, imię i nazwisko, adres e-mail. Tutaj, jeśli chcesz, aby tabela była możliwa do zapytania o imię i nazwisko, e-mail - jedynym sposobem jest uczynienie ich GSI (LSI nie pomoże)

Sony Kadavan
źródło
1

Ta dokumentacja daje całkiem dobre wyjaśnienie:

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

Nie mogłem skomentować tego pytania, ale co jest lepsze pod względem wydajności zapisu i odczytu:

(Indeks lokalny z przepustowością odczytu i zapisu tabeli równą 100) lub (Indeks globalny z przepustowością odczytu / zapisu równą 50 wraz z przepustowością odczytu / zapisu tabeli równą 50?)

Nie potrzebuję oddzielnego klucza partycji dla mojego przypadku użycia, więc indeks lokalny powinien wystarczyć dla wymaganej funkcjonalności.

Sindhu
źródło
0

GSI nie mogą być używane do spójnych odczytów.

LSI mogą być używane do spójnych odczytów, ale ograniczą rozmiar partycji głównej do 10 GB. LSI można również tworzyć tylko podczas tworzenia tabeli.

david_adler
źródło