Jak Google przechowuje Twoje duże tabele zapytań i jaki ma to na Ciebie wpływ
Opublikowany: 2016-02-24Jest to instalacja techniczna naszego bloga, przygotowana przez wybitnego programistę, Adama Knoxa.
Chociaż Big Query używa składni bardzo podobnej do SQL, w rzeczywistości wymaga znacznie innego taktu niż rozwiązanie do przetwarzania dużych ilości danych. Big Query ma tendencję do brute force i w rzeczywistości nie używa indeksów, więc dużo danych oznacza dużo procesorów i czasu przetwarzania. Aby to osiągnąć, Google zastosował inny sposób przechowywania danych, który może wpłynąć na sposób projektowania zapytań.
Format pliku
Po utworzeniu tabeli Google używa formatu ColumnIO do przechowywania danych. Każda kolumna jest przechowywana jako osobny plik, z wyjątkiem powtarzających się pól. Jeśli masz tabelę z kolumnami: name (string), phoneNumbers (powtarzana liczba całkowita); nazwa będzie przechowywana w jednej linii z innymi nazwami, a wszystkie numery telefonów powiązane z tą nazwą będą przechowywane w jednej linii z numerami telefonów. Kolumny mogą również zostać podzielone, jeśli staną się zbyt duże, ale nie będzie to miało wpływu na przepływ pracy.
Wiedza o tym zapewnia możliwość uruchamiania szybszych zapytań przez nieprzetwarzanie kolumn, na których w rzeczywistości nie zależy, a w niektórych przypadkach nawet uniemożliwia uruchamianie zapytań. Zapytania mogą również stać się tańsze, ponieważ system pobiera opłaty za ilość przetworzonych danych, a jeśli kolumna nie jest uwzględniona w zapytaniu, dane nie są przetwarzane.
Nośnik danych
Jeśli utworzyłeś tabelę, możesz czuć się dość bezpiecznie, że nigdzie się nie wybiera, ponieważ po utworzeniu plików są one przechowywane w trzech różnych centrach danych, a nawet w trzech różnych miejscach w każdym centrum danych. Ponieważ Big Query powoduje problemy z procesorami, dane muszą być łatwo dostępne. Zastrzeżeniem są tymczasowe zbiory danych. Istnieje możliwość określenia czasu wygaśnięcia dla tabel w zestawie danych, a tabele znikną, gdy będą starsze niż ta data wygaśnięcia.
Hierarchia tabeli
Projekty mają możliwość przechowywania zbiorów danych, z których każdy może zawierać tabele. Pełne polecenie dostępu do tabeli w składni Big Query to [projectname:datasetname.tablename]
, jednak można je skrócić do dataset.tablename
, jeśli uzyskujesz dostęp do tabeli z projektu, w którym aktualnie pracujesz.
Podział powiązanych danych na osobne tabele (np. według daty lub po wystąpieniu określonego zdarzenia) może być korzystny dla tworzenia zapytań, które można łatwiej konserwować, ponieważ zapytania zazwyczaj działają na wszystkich wierszach w tabeli. Oznacza to, że możesz chcieć przeglądać wiele tabel, więc w każdym zestawie danych jest coś, co nazywa się metatabelą, która jest dostępna pod adresem [projectname:datasetname.__TABLES__]
i zawiera informacje o każdej tabeli w zestawie danych i może być używana do agregowania tabel dla zapytania.
Polecenie TABLE_QUERY
jest poleceniem, które umożliwia zagregowanie wielu podobnych tabel przed uruchomieniem zapytania w agregacie, a do utworzenia tej agregacji można użyć dowolnej kolumny w __TABLES__
. Na przykład, jeśli chcę mieć pojęcie o czasach odpowiedzi od 1 stycznia 2016 dla projektu, mogę uruchomić następujące zapytanie, które pokazuje minimalny, medianę i maksymalny czas odpowiedzi:
SELECT QUANTILES((protoPayload.endTime - protoPayload.startTime), 3) AS responseTimeBucketsInMilliseconds FROM (TABLE_QUERY(appengine_logs, "table_id CONTAINS 'appengine_googleapis_com_request_log' AND creation_time > 1451606400000"))
Ponieważ używane są tylko dwie kolumny, z których każda zawiera liczby całkowite, jest to nadal dość tanie zapytanie (0,0003 USD), mimo że uzyskuje dostęp do 28+, które według poniższego zapytania powiedziano mi, że ma 1,857 TB i kosztowałoby około 9 USD, aby uzyskać dostęp do każdego pola z .
SELECT SUM(size_bytes)/1000000000 FROM [repcore-prod:appengine_logs.__TABLES__] WHERE table_id CONTAINS 'appengine_googleapis_com_request_log' AND creation_time > 1451606400000
Aktualizacja plików
Big Query jest świetne, jeśli chodzi o rejestrowanie zmian i analizowanie tych zmian, ponieważ możesz przesyłać strumieniowo nowe wiersze do tabeli. Jest to jednak straszne urządzenie do przechowywania danych do szybkiego i częstego wyszukiwania określonych wierszy z powodu braku indeksów, a także nie jest świetne do przechowywania pojedynczych reprezentacji obiektów, które spodziewasz się zmienić, ponieważ wierszy w tabeli nie można modyfikować ani usuwać .

Stoły dzielące
W niektórych sytuacjach nawet dostęp do pojedynczej kolumny jest zbyt trudny do załatwienia w Big Query. Przedstawiam następujące nieużyteczne zapytanie, które zwraca identyfikatory aukcji według kolejności daty utworzenia aukcji:
SELECT lid FROM [repcore-prod:datastore.LIS] ORDER BY ct
Technicznie rzecz biorąc, ostatnio stało się to możliwe, ale nie dla osób w Vendasta, ponieważ wymaga to włączenia wyższego poziomu rozliczeń. Ponieważ nie ma indeksów zamówionych w przedsprzedaży, bardzo intensywnie przetwarza niewielką ilość danych, więc w tym przypadku pobiera opłatę za przetwarzanie. Zmianę poziomu rozliczeń można wykonać w interaktywnych zapytaniach w interfejsie użytkownika Big Query, zaznaczając „zezwól na nieograniczoną liczbę” (jeśli jest włączone) pod przyciskiem „opcje”.
Zakładając, że zapytanie jest tak wydajne, jak to tylko możliwe, pozostało kilka sposobów na zmniejszenie rozmiarów tabel w celu obejścia tego rodzaju sztywnych ograniczeń. Pierwszy to dekoratorzy czasu stołowego, a drugi z haszem.
Więcej o dekoratorach stołów dowiesz się tutaj. W przeciwieństwie do filtrowania wyników za pomocą poleceń takich jak LIMIT/WHERE/HAVING/OMIT
, dekoratory tabel faktycznie zmniejszą koszt zapytań do tabeli, ponieważ nie będą nawet uzyskiwać dostępu do danych spoza podanego zakresu. Niestety, ta metoda jest prawie bezużyteczna w Vendasta, ponieważ nawet w przypadku tabel takich jak ListingHistoryModel, do których faktycznie przesyłamy strumieniowo, nadal usuwamy całą tabelę i zastępujemy ją codziennie repliką, jeśli pochodzi z NDB, co oznacza, że dekoratory czasu stołu będą działać tylko na ListingHistoryModel, jeśli interesują Cię tylko wpisy z bieżącego dnia.
Przyjrzenie się wyrębowi to jedyne miejsce, w którym mogą być bardzo pomocne w Vendasta. Ze względu na rozmiar rzeczywistej zawartości dziennika, obliczenia i limity pamięci są łatwe do osiągnięcia, a wykonywanie zapytań nawet tylko w kolumnie zawartości dziennika jest kosztowne. W przypadku dzienników zwykle zależy nam tylko na określonych punktach w czasie, w czym pomaga dekorator czasu.
Wyniki zapytań
Za każdym razem, gdy uruchamiasz zapytanie, tworzy nową tabelę, a czasami w tle tworzy nieznane ukryte tabele. Jeśli tak zdecydujesz, możesz nadać tabeli wyników nazwę, aby ją zachować, lub pozostawić ją pod nazwą nadaną przez Google i pozwolić jej zniknąć po dniu. Jeśli kiedykolwiek natkniesz się na „Odpowiedź zbyt duża, aby wrócić”, dzieje się tak dlatego, że chronią Cię przed samym sobą. Łatwo jest tworzyć ogromne tabele (zwłaszcza z połączeniami krzyżowymi). Jeśli tak się stanie i spodziewałeś się, że tak się stanie, musisz nazwać tabelę i włączyć opcję „Zezwalaj na duże wyniki”. Jeśli powtórzysz zapytanie, do którego nie przesłano strumieniowo nowych wierszy, otrzymasz tylko wyniki z pamięci podręcznej, jeśli nadal są dostępne.
