Piszę prostą usługę logowania w DynamoDB.
Mam tabelę dzienników, która jest kluczowana przez hash user_id i zakres datownika (int w epoce systemu Unix).
Kiedy użytkownik serwisu zamyka swoje konto, muszę usunąć wszystkie pozycje z tabeli, niezależnie od wartości zakresu.
Jaki jest zalecany sposób wykonywania tego rodzaju operacji (pamiętaj, że mogą istnieć miliony elementów do usunięcia)?
Moje opcje, o ile widzę, to:
Odp .: Wykonaj operację skanowania, wywołując usuwanie dla każdego zwróconego elementu, dopóki nie zostaną żadne elementy
B: Wykonaj operację BatchGet, ponownie wywołując usuwanie dla każdego elementu, dopóki żaden nie zostanie
Oba te wyglądają dla mnie okropnie, ponieważ zajmą dużo czasu.
To, co chciałbym zrobić, to wywołać LogTable.DeleteItem (user_id) - bez podawania zakresu i usunąć wszystko za mnie.
BatchWriteItem
elementami należy określić za pośrednictwemTableWriteItems
batch_writer()
jako częśćboto3.resource.Table
API, który „automatycznie obsługuje buforowanie i wysyłanie elementów w partiach. Ponadto piszący partie również automatycznie obsługuje wszelkie nieprzetworzone elementy i ponownie je wysyła w razie potrzeby ”tj. jest to opakowanie wokół BatchWriteItem, które zarządza irytującymi częściami. boto3.amazonaws.com/v1/documentation/api/latest/reference/…Zgodnie z dokumentacją DynamoDB można po prostu usunąć całą tabelę.
Zobacz poniżej:
„Usunięcie całej tabeli jest znacznie bardziej wydajne niż usuwanie elementów pojedynczo, co zasadniczo podwaja przepustowość zapisu, ponieważ wykonujesz tyle operacji usuwania, ile operacji put”
Jeśli chcesz usunąć tylko podzbiór danych, możesz utworzyć osobne tabele dla każdego miesiąca, roku lub podobnego. W ten sposób możesz usunąć „ostatni miesiąc” i zachować resztę danych w stanie nienaruszonym.
Oto jak usunąć tabelę w Javie za pomocą AWS SDK:
źródło
Jeśli chcesz usunąć pozycje po jakimś czasie, np. Po miesiącu, wystarczy skorzystać z opcji Time To Live. To będzie nie liczyć jednostki zapisu.
W twoim przypadku dodałbym ttl, gdy logi wygasną i zostawiłem je po usunięciu użytkownika. TTL zapewni, że dzienniki zostaną ostatecznie usunięte.
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/howitworks-ttl.html
źródło
Odpowiedź na to pytanie zależy od liczby pozycji i ich wielkości oraz budżetu. Zależy od tego, że mamy 3 przypadki:
1- Liczba pozycji i rozmiar pozycji w tabeli nie są zbyt duże. następnie, jak powiedział Steffen Opel, możesz użyć zapytania zamiast skanowania, aby pobrać wszystkie elementy dla user_id, a następnie przejrzeć wszystkie zwrócone elementy i albo ułatwić,
DeleteItem
alboBatchWriteItem
. Pamiętaj jednak, że możesz tutaj spalić dużą przepustowość. Na przykład rozważmy sytuację, w której trzeba usunąć 1000 pozycji z tabeli DynamoDB. Załóżmy, że każdy element ma rozmiar 1 KB, co daje około 1 MB danych. To zadanie usuwania zbiorczego będzie wymagało łącznie 2000 jednostek pojemności zapisu do wykonywania zapytań i usuwania. Aby wykonać to ładowanie danych w ciągu 10 sekund (co w niektórych aplikacjach nie jest nawet uważane za tak szybkie), należałoby ustawić udostępnioną przepustowość zapisu tabeli na 200 jednostek pojemności zapisu. Jak widać, można go użyć w ten sposób, jeśli jest to dla mniejszej liczby przedmiotów lub przedmiotów o małych rozmiarach.2- Mamy w tabeli wiele pozycji lub bardzo duże pozycje i możemy je przechowywać według czasu w różnych tabelach. Wtedy, jak powiedział Jonathan, możesz po prostu usunąć tabelę. to jest o wiele lepsze, ale nie sądzę, aby pasowało do twojego przypadku. Ponieważ chcesz usunąć wszystkie dane użytkowników bez względu na czas tworzenia logów, w tym przypadku nie możesz usunąć konkretnej tabeli. jeśli chcesz mieć osobną tabelę dla każdego użytkownika, myślę, że jeśli liczba użytkowników jest duża, jest to tak drogie i nie jest praktyczne w twoim przypadku.
3- Jeśli masz dużo danych i nie możesz podzielić swoich gorących i zimnych danych na różne tabele i musisz często usuwać na dużą skalę, to niestety DynamoDB wcale nie jest dla Ciebie dobrą opcją. Może stać się droższy lub bardzo powolny (w zależności od budżetu). W takich przypadkach radzę poszukać innej bazy danych.
źródło
Moje podejście do usuwania wszystkich wierszy z tabeli i DynamoDb polega po prostu na wyciągnięciu wszystkich wierszy z tabeli za pomocą DynamoDbs ScanAsync, a następnie przesłaniu listy wyników do DynamoDbs AddDeleteItems. Poniższy kod w C # u mnie działa dobrze.
Uwaga: Usunięcie tabeli, a następnie ponowne utworzenie jej z konsoli internetowej może spowodować problemy, jeśli do tworzenia tabeli używasz YAML / CloudFront.
źródło
Nie mamy możliwości obcinania tablic dynamo. musimy porzucić tabelę i ponownie stworzyć. Opłaty za DynamoDB są oparte na ReadCapacityUnits i WriteCapacityUnits. Jeśli usuniemy wszystkie elementy za pomocą funkcji BatchWriteItem, użyje ona WriteCapacityUnits, więc lepiej usunąć określone rekordy lub usunąć tabelę i zacząć od nowa.
źródło