W tym wpisie spojrzymy nieco szerzej na komponenty i ekosystem DynamoDB. Pracujemy tutaj z tabelami, atrybutami i elementami.
Tabela zawiera zestaw elementów a elementy zawierają zestawy atrybutów. Atrybut to podstawowy element danych, który nie wymaga dalszej dekompozycji, np. pole.
Klucz główny
Klucz ten służy do unikalnej identyfikacji dla elementów tabeli a indeksy wtórne (o nich za chwilę) zapewniają elastyczność zapytań. DynamoDB
strumieniowo rejestruje zdarzenia poprzez modyfikacje danych tabeli.
Przy tworzeniu tabeli, oprócz podania jej nazwy, należy utworzyć klucz główny, który identyfikuje elementy tabeli. Żadne dwa elementy nie mają wspólnego klucza.
DynamoDB używa dwóch typów kluczy głównych:
partition key (klucz partycji) – ten prosty klucz główny składa się z pojedynczego atrybutu określanego jako ‘klucz partycji’.
Wewnętrznie DynamoDB używa wartości klucza jako danych wejściowych dla funkcji haszującej;
partition key and sort key (klucz partycji i klucz sortowania) – zwany
również Composite Primary Key (złożony klucz podstawowy), to klucz składający się z dwóch atrybutów:
klucz partycji;
klucz sortowania.
Pierwszy z nich używany jest jako atrybut funkcji haszującej. Atrybut ten pozwala na przechowywanie elementów z tym samym kluczem razem, przy czym ich kolejność jest
określona przez klucz sortowania. Elementy takie mogą współdzielić klucz partycji ale nie klucz sortowania.
Atrybuty klucza głównego pozwalają jedynie na wartości skalarne (pojedyncze) oraz łańcuchy znaków, liczby oraz binarne typy danych. Atrybuty nie będące
kluczami nie mają tych ograniczeń.
Indeksy pomocnicze
Indeksy te pozwalają na zapytanie o dane z tabeli za pomocą alternatywnego klucza. Ich użycie nie jest wymuszone przez DynamoDB
przy czym pozwala na optymalizację zapytań.
W DynamoDB możemy się spotkać z dwoma typami indeksów wtórnych:
Global Secondary Index (globalny indeks wtórny) – indeks ten składa się z klucza partycji i klucza sortowania,
które mogą różnić się od kluczy tabeli;
Local Secondary Index (lokalny indeks wtórny) – indeks ten składa się klucza partycji, który jest identyczny z
kluczem tabeli ale różni się kluczem sortowania.
Znamy już podstawowe pojęcia, spójrzmy teraz na możliwe operacje z perspektywy API.
API
API pozwala nam na wykonanie operacji na dwóch płaszczyznach, tj. płaszczyzna danych (tworzenie, odczyt, aktualizacja i usuwanie)
oraz operacje strumieniowe, tj. uporządkowany przepływ informacji o zmianach elementów w tabeli DynamoDB.
Do pierwszej grupy zaliczamy poniższe operacje:
CreateTable;
DescribeTable (operacja zwraca informacje o tabeli, w tym bieżący stan tabeli, czas jej utworzenia, schemat klucza
podstawowego i wszelkie indeksy w tabeli);
ListTables;
UpdateTable;
DeleteTable;
W ramach operacji na płaszczyźnie danych możemy wykonywać poniższe operacje CRUD:
Create
Read
Update
Delete
PutItem BatchWriteItem
GetItem BatchGetItem Query Scan
UpdateItem
DeleteItem BatchWriteItem
Większość operacji nie wymaga większego komentarza. Warto jednak znać różnicę pomiędzy Query a Scan.
Pierwsza z nich używa klucza podstawowego lub klucza indeksu. Z kolei Scan (jak sama nazwa wskazuje), skanuje całą tabelę w
poszukiwaniu określonego wyniku. DynamoDB zostało zaprojektowane tak, aby być w pełni zoptymalizowane pod kątem zapytań.
Na to zagadnienie poświecimy więcej czasu w kolejnych wpisach.
Wracając jednak do omawianych zagadnień...operacje strumieniowe możemy zdefiniować jako:
ListStreams;
DescribeStream;
GetShardIterator;
GetRecords;
Wszystkie powyższe operacje najłatwiej opisać jako zmiany zachodzące w naszej aplikacji, które są odzwierciedlone w postaci operacji aktualizacji, tworzenia czy kasowania
elementów z tabeli. DynamoDB Streams zapisuje rekord strumienia z atrybutami klucza głównego elementów, które zostały zmodyfikowane.
Rekord strumienia zawiera informacji o modyfikacji danych do pojedynczego elementu w tabeli a może zostać skonfigurowany tak, aby przechwytywał dodatkowe informacje
takie jak obrazy "przed" i "po" zmodyfikowaniu elementów.
Więcej informacji możecie znaleźć tutaj:
https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Operations_Amazon_DynamoDB_Streams.html
Przepustowość
W tym wpisie poznajemy jedynie podstawowe pojęcia. Przepustowość, towarzyszące jej jednostki odczytu i zapisu, tryby przetwarzania takie jak
On-demand oraz Provisioned, radzenie sobie ze zwiększonym ruchem czy
pojęcie throttlingu to niezwykle istotny temat ale trudny do omówienia we wpisie "podstawowe pojęcia". Na ten moment chciałbym,
żebyście wiedzieli, że podczas tworzenia tabeli ustawiamy przepustowość, która jest odzwierciedlona przez zarezerwowane jednostki odczytu i zapisu. W momencie przekroczenia
tych wartości przez naszą aplikację dochodzi do zakończenia rosnącej liczby żądań niepowodzeniem. W tym celu należy monitorować ustawioną vs używaną przepustowość dla
lepszej obsługi żądań. Ten temat zostanie omówiony bardzo dokładnie na późniejszym etapie tego cyklu ponieważ prędzej czy później każdy spotka się z tym tematem – nie chcę
jednak na tym etapie komplikować poziomu wpisu i poznanych zagadnień.
Spójność odczytu
Read consistency to kolejne niezwykle ważne pojęcie. DynamoDB używa dwóch trybów odczytu:
eventually consistent oraz strong consistent. Ten pierwszy, jak sama nazwa wskazuje, nie
gwarantuje, że odczyty zawsze dostarczają aktualne dane. W przypadku rozproszonych systemów może dojść do sytuacji, że dane odczytywane z tabeli
DynamoDB mogą nie odzwierciedlać stanu niedawno zakończonej (innej operacji) mającej wpływ na dane zawarte w tabeli.
Jeżeli dane żądanie odczytu zostanie powtórzone po krótkim czasie, odpowiedź powinna zawierać najnowsze (aktualne) dane. Musimy pamiętać, że odczyt w
trybie eventually consistent jest ustawieniem domyślnym.
Przeciwieństwem tego trybu jest silnie spójny odczyt, tj. strongly consistent read - odczyt zawsze dostarcza aktualnych
danych (za wyjątkiem awarii sprzętu czy problemów sieciowych). Na ten moment więcej szczegółowych informacji możecie znaleźć w oficjalnej dokumentacji:
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadConsistency.html - na późniejszym etapie tego cyklu skupimy się również na tym
problemie, zagłębimy się w jego przyczyny oraz poszukamy rozwiązań mając na uwadze jakie ograniczenia niesie za sobą silnie spójny odczyt.
Partycje
Ostatnie pojęcie, na które spojrzymy w tym wpisie to tzw. partycje. DynamoDB używa partycji do przechowywania danych.
To nic innego jak alokacje pamięci masowej w postaci dysków SSD oraz automatyczna funkcjonalność replikowania danych w wielu
stefach dostępności w ramach danego regionu AWS. Zarządzanie to odbywa się automatycznie przez DynamoDB.
Na ten moment skupimy się jedynie na informacji, że podczas tworzenia tabeli wchodzi ona w stan CREATING. Jeżeli
wszystko przebiegnie pomyślnie, proces tworzenia zostanie ukończony, tabela przejdzie w stan ACTIVE, który pozwala na wykonywanie różnych
operacji. Do zmiany partycji dochodzi zwykle po osiągnięciu maksymalnej pojemności bądź zmianie przepustowości. Jest to temat, który poruszymy również w dalszej części
cyklu – jak widzicie, podstawowe pojęcia/koncepcje są ze sobą bardzo mocno powiązane. Spróbujmy jednak w pierwszej kolejności utworzyć tabele, wykonać różne operacje,
wyszukać interesujące nas informacje – w dalszej części rozszerzymy wszelkie pojęcia. Jeżeli jednak chcecie dowiedzieć się więcej o tym procesie w szczegółach odsyłam do
oficjalnej dokumentacji:
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.Partitions.html
My przechodzimy do kolejnego wpisu w którym utworzymy sobie lokalną instancję DynamoDB i zaczniemy eksperymentować.