Paweł Łukasiewicz
2024-04-05
Paweł Łukasiewicz
2024-04-05
Udostępnij Udostępnij Kontakt
Wprowadzenie

W tym i kilku kolejnych wpisach poruszymy tematy dotyczące indeksów oraz skupimy się na poprawie dostępu do danych za pomocą indeksów wtórnych (secondary indexes).

DynamoDB zapewnia szybki dostęp do elementów w tabeli poprzez określenie wartości klucza podstawowego. Możemy jednak wykorzystać dostępność jednego lub większej liczby kluczy pomocniczych (lub alternatywnych) w celu zwiększenia wydajności dostępu do danych z atrybutami innymi niż klucz podstawowy. W celu rozwiązania tego problemu możemy utworzyć jeden lub więcej indeksów pomocniczych tabeli i wysyłać żądania zapytania lub skanowania w odniesieniu do tych indeksów.

Indeks pomocniczy/wtórny (secondary index) jest strukturą danych, która zapewnia podzbiór atrybutów z tabeli wraz z kluczem alternatywnym aby wspierać operacje Query. Możemy pobierać dane z indeksu za pomocą zapytania w taki sam sposób jak w przypadku zapytania do tabeli. Tabela może posiadać wiele indeksów wtórnych, które dają aplikacjom dostęp do wielu różnych wzorców zapytań (query patterns). Nie wspomniałem o tym w poprzednim zdaniu, ale skanowanie indeksu odbywa się również w taki sam sposób jak skanowanie na tabeli.

Każdy indeks wtórny jest związany dokładnie z jedną tabelą, z której pobieramy dane. Jest to tabelowa bazowa dla indeksu. Podczas tworzenia indeksu definiujemy klucz alternatywny dla indeksu (klucz partycji i klucz sortowania). Określamy również atrybuty, które mają być rzutowane lub kopiowane z tabeli bazowej do indeksu. DynamoDB kopiuje te atrybuty do indeksu wraz z atrybutami klucza głównego z tabeli bazowej. Możemy wówczas zapytać lub przeskanować indeks tak samo jak w przypadku tych operacji wykonanych na tabeli.

Każdy indeks wtórny jest automatycznie używany przez DynamoDB. Kiedy dodajemy, modyfikujemy lub usuwamy elementy z tabeli podstawowej, wszystkie indeksy na tej tabeli są również aktualizowane aby odzwierciedlić te zmiany.

DynamoDB obsługuje dwa rodzaje indeksów wtórnych:

  • Global secondary index (globalny indeks wtórny) – indeks z kluczem partycji i kluczem sortowania, które mogą być różne od kluczy tabeli podstawowej. Globalny indeks wtórny jest uważany za "globalny" ponieważ zapytania na indeksie mogą obejmować wszystkie dane w tabeli podstawowej, we wszystkich partycjach. Globalny indeks wtórny przchowywany jest w swojej własnej przestrzeni partycji z dala od tabeli podstawowej i skaluje się niezależnie od tej tabeli;
  • Local secondary index (lokalny indeks wtórny) – indeks, który posiada ten sam klucz partycji co tabela podstawowa ale inny klucz sortowania. Lokalny indeks pomocniczy jest "lokalny" w tym sensie, że każda partycja lokalnego indeksu pomocniczego jest przypisana do partycji tabeli bazowej, która ma tę samą wartość klucza partycji.

Zanim przejdziemy dalej powinniśmy skupić się na wymaganiach aplikacji w celu określenia typu indeksu, którego powinniśmy użyć. Poniższa tabela przedstawia główne różnice pomiędzy globalnym indeksem wtórnym a lokalnym indeksem wtórnym:

Charakterystyka Global secondary index Local secondary index
Schemat klucza (Key Schema) Klucz partycji indeksu oraz klucz sortowania (jeżeli występuje) mogą być dowolnymi atrybutami tabeli bazowej typu string, number lub binary Klucz partycji indeksu jest tym samym atrybutem co klucz partycji tabeli bazowej. Klucz sortowania może być dowolnym atrybutem tabeli bazowej typu string, number lub binary
Ograniczenia rozmiaru na wartość klucza partycji Nie ma ograniczeń rozmiaru dla globalnych indeksów wtórnych Dla każdej wartości klucza partycji, całkowity rozmiar wszystkich indeksowanych elementów musi wynosić 10GB lub mniej
Operacje na (utworzonym) indeksie Globalne indeksy wtórne mogą być tworzone podczas tworzenia tabeli. Możemy także dodać nowy globalny indeks wtórny dla istniejącej tabeli lub usunąć istniejący globalny indeks wtórny Lokalne indeksy wtórne tworzone są w momencie tworzenia tabeli. Nie można dodać lokalnego indeksu wtórnego do istniejącej tabeli ani usunąć istniejących lokalnych wtórnych
Zapytania i partycje Globalny indeks wtórny pozwala na zapytanie o całą tabelę, we wszystkich partycjach Lokalny indeks wtórny pozwala na zapytanie o pojedynczą partycję określoną przez wartość klucza partycji w zapytaniu
Spójność odczytu (read consistency) Zapytania do globalnych indeksów wtórnych pozwalają jedynie na odczyt w trybie spójności ostatecznej (eventual consistency) W przypadku zapytań do lokalnego indeksu wtórnego można wybrać ostatecznie spójny lub silnie spójny (strong consistency) odczyt
Zużycie przepustowości (Provisioned Throughput) Każdy globalny indeks wtórny posiada własne ustawienia przepustowości dla odczytu i zapisu. Zapytania lub skanowanie na globalnym indeksie wtórym zużywają jednostki pojemności z indeksu a nie tabeli podstawowej. To samo dotyczy aktualizacji indeksu wtórnego spowodowanych zapisami w tabeli. Zapytania lub skany na lokalnym indeksie pochłaniają jednostki pojemności odczytu z tabeli bazowej. Gdy zapisujemy do tabeli, jej lokalne indeksy wtórne są również aktualizowane - te aktualizacje zużywają jednostki pojemności zapisu z tabeli bazowej
Projekcja atrybutów Przy zapytaniach lub skanowaniu globalnego indeksu wtórnego możemy zażądać tylko atrybutów, które są rzutowane na indeks. DynamoDB nie pobiera żadnych atrybutów z tabeli Jeżeli zapytamy lub zeskanujemy lokalny indeks wtórny możemy zażądać atrybutów, które nie są rzutowane na indeks. DynamoDB automatycznie pobiera te atrybuty z tabeli

Jeżeli chcemy utworzyć więcej niż jedną tabelę z indeksami wtórnymi musimy to zrobić sekwencyjnie. Prostym przykładem jest utworzenie pierwszej tabeli i czekanie aż stanie się aktywna. W następnym kroku tworzymy następną tabelę i czekamy aż stanie się aktywna, itd. Jeżeli spróbujemy utworzyć więcej niż jedną tabelę z indeksem wtórnym DynamoDB zwróci nam wyjątek LimitExceededException.

Dla każdego indeksu wtórnego musimy określić następujące elementy:

  • typ tworzonego indeksu - globalny indeks wtórny lub lokalny indeks wtórny;
  • nazwa indeksu - zasady nazewnictwa indeksów są takie same jak tabel. Nazwa musi być unikalna dla tabeli bazowej z którą jest powiązana, ale możemy użyć tej samej nazwy dla indeksów powiązanych z różnymi tabelami podstawowymi;
  • schemat klucza indeksu - każdy atrybut w schemacie musi być atrybutem najwyższego poziomu typu String, Number lub Binary. Inne typy danych w tym dokumenty i zestawy (sets) nie są dozwolone. Inne wymagania dla schematu klucz zależą od typu indeksu:
    • dla globalnego indeksu wtórnego kluczem partycji może być dowolny atrybut skalarny tabeli podstawowej. Klucz sortowania jest opcjonalny i również może być dowolnym atrybutem skalarnym tabeli bazowej;
    • dla lokalnego indeksu wtórnego klucz partycji musi być taki sam jak klucz partycji tabeli podstawowej a klucz sortowania musi być atrybutem tabeli podstawowej bez klucza.
  • dodatkowe atrybuty (jeżeli występują) w celu rzutowania z tabeli bazowej do indeksu. Atrybuty te są dodatkiem do atrybutów klucza tabeli, które są automatycznie rzutowane do każdego indeksu. Możesz rzutować atrybuty dowolnego typu danych, w tym skalary, dokumenty i zestawy.
  • ustawienia przepustowości dla indeksu, jeżeli jest to koniecznie:
    • dla globalnego indeksu wtórnego musisz określić ustawienia jednostek przepustowości odczytu i zapisu. Ustawienia przepustowości są niezależne od ustawień tabeli podstawowej;
    • dla lokalnego indeksu wtórnego nie musisz określać ustawień jednostek pojemności odczytu i zapisu – wszystkie operacje odczytu i zapisu na lokalnym indeksie wtórnym korzystają z ustawień przepustowości tabeli podstawowej;

Dla zapewnienia maksymalnej elastyczności zapytań można utworzyć do 20 globalnych indeksów wtórnych (domyślny limit) oraz do 5 lokalnych indeksów wtórnych na tabelę.

Limit globalnych indeksów wtórnych wynosi 5 dla następujących regionów: AWS GovCloud (US-East), AWS GovCloud (US-West) oraz Europa (Stockholm) (w momencie przygotowywania wpisu).

W celu uzyskania szczegółowej listy indeksów wtórnych tabeli należy posłużyć się operacją DescribeTable - zwróci ona nazwę, rozmiar przechowywania oraz liczbę elementów dla każdego indeksu wtórnego na tabeli. Wartości te nie są aktualizowane w czasie rzeczywistym ale są odświeżane mniej więcej co 6 godzin.

Dostęp do danych w indeksie wtórnym można uzyskać za pomocą zapytania lub skanowania. Musimy określić nazwę tabeli podstawowej i nazwę indeksu, który chcesz wykorzystać, podać atrybuty, które mają zostać zwrócone w wynikach oraz wszelkie wyrażenia warunkowe lub filtry, które chcesz wykorzystać. DynamoDB może zwrócić wyniki w kolejności rosnącej lub malejącej.

Wraz z usunięciem tabeli dochodzi również do usunięcia wszystkich indeksów powiązanych z tą tabelą.

W kolejnych wpisach skupimy się na szczegółowym omówieniu globalnych oraz lokalnych indeksów pomocniczych/wtórnych.