Jak Google przechowuje Twoje duże tabele zapytań i jak to wpływa na Ciebie?

Opublikowany: 2016-02-24

Jest 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 tabel w zestawie danych, a tabele znikną, gdy będą starsze niż ta data wygaśnięcia.

Hierarchia tabeli

Projekty mają możliwość przechowywania zestawó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, nad którym aktualnie pracujesz.

Podział powiązanych danych na oddzielne tabele (np. według daty lub po wystąpieniu określonego zdarzenia) może być korzystny w przypadku tworzenia zapytań, które można łatwiej konserwować, ponieważ zapytania zazwyczaj działają na wszystkich wierszach w tabeli. Oznacza to, że możesz chcieć spojrzeć na wiele tabel, więc w każdym [projectname:datasetname.__TABLES__] danych jest coś, co nazywa się [projectname:datasetname.__TABLES__] 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 świetnie sprawdza się w rejestrowaniu zmian i analizowaniu 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 jednej kolumny to zbyt wiele, aby poradzić sobie z 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 zapytaniach interaktywnych 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 podejść do zmniejszenia 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ń o tabelę, ponieważ nie uzyskają nawet 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.

Patrzenie na wycinkę jest jedynym miejscem, 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 powrócić”, to dlatego, że chronią cię przed tobą. Ł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.