Czego być może nie wiedzą Państwo o kolumnowych pamięciach masowych?

Kolumnowa pamięć masowa jest powszechnie stosowaną techniką przechowywania danych. Często wiąże się ona z wysoką wydajnością i w zasadzie stała się standardową konfiguracją dla dzisiejszych analitycznych baz danych.

Podstawową zasadą przechowywania kolumnowego jest zmniejszenie ilości danych pobieranych z dysku twardego. Tabela danych może mieć wiele kolumn, ale obliczenia mogą wykorzystywać tylko bardzo małą ich liczbę. W przypadku przechowywania kolumnowego, bezużyteczne kolumny nie muszą być pobierane, podczas gdy w przypadku przechowywania wierszowego wszystkie kolumny muszą być skanowane. Gdy pobierane kolumny zajmują tylko bardzo małą część całości, przechowywanie kolumnowe ma dużą przewagę pod względem czasu IO, a obliczenia wydają się być znacznie szybsze.

Ale kolumnowa pamięć masowa ma też drugą stronę – nie jest najszybsza w żadnym scenariuszu.

Wdrożenie magazynu kolumnowego jest znacznie bardziej złożone niż wdrożenie magazynu wierszowego, ponieważ w przypadku tabeli danych liczbę kolumn można określić z wyprzedzeniem, ale liczba wierszy nie przestanie rosnąć. W przypadku przechowywania wierszowego zapisujemy i dołączamy dane do tabeli zgodnie z kolejnością rekordów. Łatwo jest przechowywać tabelę danych jako pojedynczy plik. Nie działa to jednak w przypadku danych przechowywanych w formacie kolumnowym. Ponieważ dane będą dołączane, nie możemy wcześniej znać liczby wierszy, a zatem niemożliwe jest zakończenie zapisu jednej kolumny, a następnie następnej. Ogólnie rzecz biorąc, dzielimy przestrzeń dyskową na kilka bloków, zapisujemy stałą liczbę wierszy (reprezentowaną przez N) w jednym bloku, a następnie przechodzimy do następnego po zakończeniu zapisu. Później dane będą pobierane blok po bloku. W każdym bloku dane są przechowywane w formacie kolumnowym, natomiast między blokami dane mogą być traktowane jako przechowywane w formacie wierszowym. Potrzebny jest specjalny moduł zarządzania, w którym spis treści służy do rejestrowania informacji o stale rosnących blokach danych i każdej przechowywanej przez nie kolumnie, co powoduje wiele niedogodności. W związku z tym trudno jest zaimplementować przechowywanie kolumnowe w pojedynczym pliku danych. Schemat przechowywania jest zwykle przyjmowany przez specjalne produkty hurtowni danych.

Mechanizm przechowywania blokowego jest jednak nieprzyjazny dla implementacji przetwarzania równoległego, gdy ilość danych nie jest duża. Przetwarzanie równoległe wymaga podziału danych na wiele segmentów. Aby było to możliwe, muszą być spełnione dwa warunki: prawie równa ilość danych w każdym segmencie (równe obciążenie przetwarzania dla każdego wątku) oraz możliwość elastycznej segmentacji (liczba równoległych zadań nie może być określona z góry). Dane wierszowe mogą być segmentowane zgodnie z liczbą wierszy, a przetwarzanie równoległe staje się wykonalne nawet dla bardzo małej ilości danych. Dane kolumnowe można podzielić tylko na bloki, w których dane nie mogą być dalej dzielone. Liczba rekordów (wspomniane wyżej N) nie powinna być zbyt mała; w przeciwnym razie zbyt wiele zasobów zostanie zmarnowanych z powodu istnienia najmniejszej jednostki pobierania dysku. W skrajnym przypadku N=1, schemat przechowywania jest równy przechowywaniu wierszowemu. Gdy N jest zbyt małe, a całkowita ilość danych jest ogromna, spis treści staje się bardzo duży i nadmiernie obciąża zarządzanie treścią. Tak więc, N jest zwykle określane jako milion lub więcej. Aby elastycznie segmentować dane, muszą istnieć co najmniej setki bloków danych. Oznacza to, że równoległe obliczenia na danych kolumnowych stają się płynne tylko wtedy, gdy całkowita ilość danych osiąga co najmniej setki milionów wierszy danych.

esProc SPL oferuje strategię segmentacji z podwójnym przyrostem, aby N rosło wraz ze wzrostem ilości danych przy zachowaniu tej samej liczby bloków danych. W ten sposób rozmiar spisu treści może być również stały, przechowywanie kolumnowe może być wygodnie zaimplementowane w pojedynczym pliku, a elastyczna segmentacja może być zaimplementowana do wykonywania równoległych obliczeń na niewielkiej ilości danych.

Zgodnie z zasadą przechowywania kolumnowego, schemat przechowywania przynosi oczywistą korzyść tylko wtedy, gdy obliczenia obejmują stosunkowo niewielką liczbę kolumn. Wiele przypadków testowych wydajności (takich jak TPCH używany jako międzynarodowy standard) wybiera takie scenariusze obliczeniowe, więc są one wygodne do wydobywania zalet kolumnowych baz danych. To tylko część rzeczywistych scenariuszy biznesowych. W branży finansowej nierzadko zdarza się, że obliczenia obejmują większość kolumn w tabeli mającej ponad sto kolumn. W takim przypadku pamięć kolumnowa tylko połowicznie wykorzystuje swoją przewagę. Nawet jeśli przechowywanie kolumnowe ma wyższy współczynnik kompresji i mniejszą ilość pobieranych danych niż przechowywanie wierszowe, jego przewaga nie jest tak zauważalna, gdy w obliczeniach bierze udział wiele kolumn. W końcu proces pobierania danych przechowywanych kolumnowo jest znacznie bardziej złożony niż proces pobierania danych przechowywanych wierszowo.

Dlatego też, gdy obliczenia w świecie rzeczywistym nie mają tak dobrej wydajności, jak w przypadku testowym, jest to normalne i nie oznacza to, że wynik testu jest fałszywy.

Kolumnowa pamięć masowa prowadzi również do losowego dostępu do dysku. Dane w każdej kolumnie są przechowywane w sposób ciągły, ale dane w różnych kolumnach nie są. Im więcej kolumn jest pobieranych, tym większy jest stopień losowości wynikający z pobierania, nawet w przypadku zadania jednowątkowego. W przypadku dysków SSD nie jest to bardzo poważny problem, ponieważ gdy dane w każdej kolumnie są ciągłe, a wspomniane powyżej N jest wystarczająco duże, koszt pobierania zajmuje bardzo małą część, a dysk SSD nie ma czasu wyszukiwania.

Ale w przypadku dysków HDD, które mają czas wyszukiwania, problem staje się katastrofalny. Gdy uzyskuje się dostęp do wielu kolumn, prawdopodobne jest, że wydajność nie będzie nawet tak dobra, jak w przypadku przechowywania wierszowego. Zarówno współbieżność, jak i przetwarzanie równoległe pogorszą ten problem. Z drugiej strony, zwiększenie rozmiaru pamięci podręcznej w celu złagodzenia problemu zajmie zbyt dużo miejsca w pamięci.

Proszę zachować ostrożność podczas korzystania z kolumnowych pamięci masowych na dyskach twardych.

Innym dużym problemem związanym z pamięcią kolumnową jest to, że ma ona znacznie niższą wydajność indeksowania niż pamięć wierszowa. Jak już wspomnieliśmy, tabela indeksów przechowuje uporządkowane wartości kluczy i pozycje odpowiadających im rekordów w oryginalnej tabeli. W przypadku przechowywania wierszowego pozycja rekordu może być reprezentowana przez jedną liczbę, ale w przypadku przechowywania kolumnowego każda kolumna w rekordzie ma inną pozycję i zasadniczo wszystkie te pozycje powinny być rejestrowane. Tworzy to tabelę indeksów prawie tak dużą jak oryginalna tabela, co prowadzi do dużego wykorzystania pamięci masowej i wysokich kosztów wyszukiwania. Nie ma dużej różnicy między tym a metodą kopiowania oryginalnej tabeli i sortowania jej.

Oczywiście nikt nie zrobi tego w praktyce. Ogólnym podejściem jest nadal wspomniany wcześniej mechanizm przechowywania blokowego. Indeks przechowuje tylko numery porządkowe rekordów. Wyszukiwanie odczytuje numer porządkowy z tabeli indeksu, lokalizuje odpowiedni blok, “liczy” od pierwszego rekordu do tego z odpowiednim numerem porządkowym w bloku i pobiera wartość kolumny. Czynność “liczenia” jest wykonywana dla każdej kolumny. W najlepszym przypadku odczytana zostanie liczba jednostek dyskowych równa liczbie kolumn; jeśli nie mają Państwo szczęścia, przeskanowany zostanie cały blok. Dla kontrastu, indeks do przechowywania wierszowego zazwyczaj musi odczytać tylko jedną lub dwie jednostki dyskowe (określone przez przestrzeń zajmowaną przez rekordy). Ilość danych pobieranych w przypadku przechowywania kolumnowego jest dziesiątki, a nawet sto razy większa niż w przypadku przechowywania wierszowego. W przypadku dysków twardych występuje również nieznośny czas wyszukiwania. Dlatego też kolumnowa pamięć masowa zasadniczo nie jest w stanie sprostać wymaganiom zapytań o wysokiej współbieżności.

Do przeszukiwania należy używać magazynu kolumnowego, a do wyszukiwania – magazynu wierszowego. W przypadku danych, dla których zarówno przeszukiwanie, jak i wyszukiwanie wymagają wysokiej wydajności, konieczne jest nawet redundantne przechowywanie dwóch kopii danych. Platforma danych powinna umożliwiać programistom przyjęcie najbardziej odpowiedniego schematu przechowywania dla każdego scenariusza obliczeniowego, zamiast podejmowania tej samej decyzji dla wszystkich scenariuszy.

Cóż, esProc SPL pozwala użytkownikom wybrać bardziej odpowiedni między przechowywaniem wierszowym a kolumnowym. Oferuje również strategię indeksowania dołączonego do wartości w celu przechowywania kopii danych zorientowanych na wiersze danych kolumnowych zorientowanych na wyszukiwanie.