Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Ponieważ ClickHouse jest systemem specjalistycznym, przy jego użytkowaniu ważne jest uwzględnienie cech jego architektury. W tym raporcie Alexey opowie o przykładach typowych błędów podczas korzystania z ClickHouse, które mogą prowadzić do nieefektywnej pracy. Praktyczne przykłady pokażą, jak wybór tego lub innego schematu przetwarzania danych może zmienić wydajność o rząd wielkości.

Cześć wszystkim! Nazywam się Alexey, tworzę ClickHouse.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Po pierwsze, spieszę sprawić przyjemność od razu, dziś nie zdradzę, czym jest ClickHouse. Szczerze mówiąc, jestem tym zmęczony. Za każdym razem mówię ci, co to jest. I chyba każdy już to wie.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Zamiast tego powiem Ci, jakie są możliwe błędy, czyli jak możesz nieprawidłowo korzystać z ClickHouse. Tak naprawdę nie ma się czego bać, ponieważ rozwijamy ClickHouse jako system prosty, wygodny i działający od razu po wyjęciu z pudełka. Zainstalowałem, nie ma problemów.

Trzeba jednak mieć na uwadze, że jest to system wyspecjalizowany i łatwo można spotkać się z nietypowym przypadkiem użycia, który wyprowadzi ten system ze strefy komfortu.

Jaki więc jest rodzaj grabi? Przeważnie będę mówił o rzeczach oczywistych. Wszystko jest oczywiste dla każdego, każdy wszystko rozumie i może się cieszyć, że jest taki mądry, a ci, którzy nie rozumieją, nauczą się czegoś nowego.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Pierwszym i najprostszym przykładem, który niestety często się zdarza, jest duża liczba wkładek przy małych partiach, czyli duża liczba małych wkładek.

Jeśli weźmiemy pod uwagę sposób, w jaki ClickHouse wykonuje wstawianie, to w jednym żądaniu można przesłać przynajmniej terabajt danych. To nie problem.

Zobaczmy, jaka byłaby typowa wydajność. Na przykład mamy tabelę z danymi Yandex.Metrica. Hity. 105 niektóre kolumny. 700 bajtów nieskompresowanych. I będziemy wstawiać w dobry sposób w partiach po milion wierszy.

Wstawiamy MergeTree do tabeli, okazuje się, że pół miliona wierszy na sekundę. Świetnie. W zreplikowanej tabeli będzie ona nieco mniejsza, około 400 000 wierszy na sekundę.

A jeśli włączysz wstawianie kworum, uzyskasz nieco mniejszą, ale wciąż przyzwoitą wydajność, 250 000 terminów na sekundę. Wstawianie kworum to nieudokumentowana funkcja ClickHouse*.

* od 2020 r., już udokumentowane.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Co się stanie, jeśli zrobisz coś złego? Wstawiamy jeden wiersz do tabeli MergeTree i uzyskujemy 59 wierszy na sekundę. To 10 000 razy wolniej. W ReplicatedMergeTree – 6 wierszy na sekundę. A jeśli kworum jest włączone, okazuje się, że 2 linie na sekundę. Moim zdaniem to jakiś absolutny badziew. Jak można tak zwalniać? Mam nawet na koszulce napisane, że ClickHouse nie powinien zwalniać. Ale mimo to czasami się to zdarza.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

W rzeczywistości jest to nasza wada. Mogliśmy z łatwością sprawić, że wszystko będzie dobrze działać, ale tego nie zrobiliśmy. I nie zrobiliśmy tego, ponieważ nasz skrypt tego nie wymagał. Mieliśmy już butche. Właśnie otrzymaliśmy partie przy wejściu i nie było żadnych problemów. Wkładamy go i wszystko działa dobrze. Ale oczywiście możliwe są różne scenariusze. Na przykład, gdy masz kilka serwerów, na których generowane są dane. I nie wstawiają danych tak często, ale i tak często wstawiają. I musimy jakoś tego uniknąć.

Z technicznego punktu widzenia chodzi o to, że kiedy wstawisz dane w ClickHouse, dane nie trafią do żadnej tablicy memtable. Nie mamy nawet prawdziwej struktury dziennika MergeTree, ale tylko MergeTree, ponieważ nie ma ani dziennika, ani memTable. Po prostu natychmiast zapisujemy dane do systemu plików, już ułożone w kolumny. A jeśli masz 100 kolumn, wówczas w osobnym katalogu trzeba będzie zapisać ponad 200 plików. Wszystko to jest bardzo uciążliwe.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

I pojawia się pytanie: „Jak to zrobić dobrze?” Jeśli sytuacja jest taka, że ​​nadal trzeba jakoś rejestrować dane w ClickHouse.

Metoda 1. To najłatwiejszy sposób. Użyj jakiegoś rodzaju kolejki rozproszonej. Na przykład Kafkę. Po prostu wyodrębniasz dane z Kafki i przetwarzasz je wsadowo raz na sekundę. I wszystko będzie dobrze, nagrywasz, wszystko działa dobrze.

Wadą jest to, że Kafka jest kolejnym nieporęcznym systemem rozproszonym. Rozumiem też, jeśli masz już Kafkę w swojej firmie. To dobrze, to jest wygodne. Jeśli jednak nie istnieje, powinieneś pomyśleć trzy razy, zanim przeciągniesz do swojego projektu kolejny system rozproszony. Dlatego warto rozważyć alternatywy.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Metoda 2. To oldschoolowa alternatywa, a jednocześnie bardzo prosta. Czy masz jakiś serwer, który generuje logi. I po prostu zapisuje twoje logi do pliku. I raz na sekundę zmieniamy na przykład nazwę tego pliku i odrywamy nowy. Oddzielny skrypt, albo przez cron, albo przez jakiegoś demona, pobiera najstarszy plik i zapisuje go w ClickHouse. Jeśli będziesz nagrywać logi raz na sekundę, wszystko będzie dobrze.

Ale wadą tej metody jest to, że jeśli gdzieś zniknie Twój serwer, na którym generowane są logi, to znikną również dane.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Metoda 3. Istnieje jeszcze jedna ciekawa metoda, która w ogóle nie wymaga plików tymczasowych. Na przykład masz jakiś spinner reklamowy lub innego interesującego demona, który generuje dane. I możesz gromadzić mnóstwo danych bezpośrednio w pamięci RAM, w buforze. A gdy upłynie wystarczająca ilość czasu, odkładasz ten bufor, tworzysz nowy i w osobnym wątku wstawiasz to, co już zgromadziło się w ClickHouse.

Z drugiej strony dane również znikają przy kill -9. Jeśli Twój serwer ulegnie awarii, utracisz te dane. Kolejnym problemem jest to, że jeśli nie udało Ci się zapisać do bazy danych, Twoje dane zostaną zgromadzone w pamięci RAM. Albo zabraknie pamięci RAM, albo po prostu stracisz dane.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Metoda 4. Kolejna ciekawa metoda. Czy masz jakiś proces serwerowy. I może natychmiast wysłać dane do ClickHouse, ale zrób to w jednym połączeniu. Na przykład wysłałem żądanie http z kodowaniem transferu: fragmentaryczne z wstawką. I niezbyt rzadko generuje porcje, możesz wysłać każdą linię, chociaż kadrowanie tych danych będzie narzutem.

Jednakże w takim przypadku dane zostaną przesłane do ClickHouse niezwłocznie. A ClickHouse sam je buforuje.

Ale pojawiają się też problemy. Teraz stracisz dane, także w przypadku zabicia procesu i zabicia procesu ClickHouse, ponieważ będzie to niekompletna wstawka. A w ClickHouse wstawki są atomowe aż do pewnego określonego progu wielkości wierszy. W zasadzie jest to ciekawy sposób. Można również używać.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Metoda 5. Oto kolejna interesująca metoda. To rodzaj opracowanego przez społeczność serwera do przetwarzania wsadowego danych. Sam tego nie sprawdzałem, więc nic nie gwarantuję. Jednakże na sam ClickHouse nie udziela się żadnych gwarancji. Jest to również oprogramowanie typu open source, ale z drugiej strony możesz być przyzwyczajony do pewnych standardów jakości, które staramy się zapewnić. Ale w tym przypadku – nie wiem, przejdź do GitHuba, spójrz na kod. Może napisali coś normalnego.

* od 2020 r. należy również uwzględnić Dom Kociaka.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Metoda 6. Inną metodą jest użycie tabel buforowych. Zaletą tej metody jest to, że bardzo łatwo jest zacząć ją stosować. Utwórz tabelę buforów i wstaw ją do niej.

Wadą jest to, że problem nie został całkowicie rozwiązany. Jeśli przy szybkości takiej jak MergeTree musisz grupować dane jedną partią na sekundę, to przy szybkości w tabeli buforów musisz grupować co najmniej do kilku tysięcy na sekundę. Jeśli będzie więcej niż 10 000 na sekundę, nadal będzie źle. A jeśli wstawisz go partiami, zobaczysz, że okazuje się, że jest to sto tysięcy linii na sekundę. I to już na dość ciężkich danych.

A także tabele buforów nie mają dziennika. A jeśli coś będzie nie tak z Twoim serwerem, dane zostaną utracone.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Jako bonus, niedawno w ClickHouse otrzymaliśmy możliwość pobierania danych z Kafki. Istnieje silnik stołowy - Kafka. Po prostu tworzysz. Można na nim zawiesić zmaterializowane reprezentacje. W tym przypadku sam wydobędzie dane z Kafki i wstawi je do potrzebnych tabel.

A co szczególnie cieszy w tej możliwości, to fakt, że to nie my to zrobiliśmy. To jest funkcja społecznościowa. A kiedy mówię „cecha społecznościowa”, mam to na myśli bez żadnej pogardy. Przeczytaliśmy kod, zrobiliśmy recenzję, powinno działać dobrze.

*od 2020 roku pojawiło się podobne wsparcie dla RabbitMQ.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Co jeszcze może być niewygodne lub nieoczekiwane podczas wstawiania danych? Jeśli złożysz prośbę o wstawienie wartości i napiszesz w wartościach kilka wyrażeń obliczeniowych. Na przykład now() jest także wyrażeniem obliczeniowym. W tym przypadku ClickHouse jest zmuszony uruchomić interpreter tych wyrażeń w każdej linii, a wydajność spadnie o rząd wielkości. Lepiej tego unikać.

* w tej chwili problem został całkowicie rozwiązany, nie ma już regresji wydajności podczas używania wyrażeń w WARTOŚCIACH.

Innym przykładem mogą być problemy, gdy dane znajdują się w jednej partii należącej do kilku partycji. Domyślnie partycje ClickHouse są podzielone na miesiące. A jeśli wstawisz partię miliona wierszy, a będą tam dane z kilku lat, to będziesz miał tam kilkadziesiąt partycji. A to jest równoznaczne z faktem, że będą partie kilkadziesiąt razy mniejsze, bo wewnątrz zawsze są najpierw dzielone na przegródki.

* Ostatnio w trybie eksperymentalnym ClickHouse dodał obsługę kompaktowego formatu fragmentów i fragmentów w pamięci RAM z dziennikiem zapisu z wyprzedzeniem, co prawie całkowicie rozwiązuje problem.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Przyjrzyjmy się teraz drugiemu typowi problemu – wpisywaniu danych.

Wpisywanie danych może być ścisłe lub ciągowe. String ma miejsce wtedy, gdy właśnie go wziąłeś i zadeklarowałeś, że wszystkie twoje pola są typu string. To jest do bani. Nie ma potrzeby tego robić.

Zastanówmy się, jak to zrobić poprawnie w tych przypadkach, gdy chcesz powiedzieć, że mamy jakieś pole, ciąg znaków, i pozwól ClickHouse samodzielnie to rozgryźć, a ja nie będę się tym przejmować. Ale i tak warto się trochę postarać.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Na przykład mamy adres IP. W jednym przypadku zapisaliśmy go jako ciąg znaków. Na przykład 192.168.1.1. W innym przypadku będzie to liczba typu UInt32*. Dla adresu IPv32 wystarczą 4 bity.

Po pierwsze, co dziwne, dane zostaną skompresowane w przybliżeniu jednakowo. Różnica będzie oczywiście widoczna, ale nie aż tak duża. Nie ma więc specjalnych problemów z we/wy dysku.

Istnieje jednak poważna różnica w czasie procesora i czasie wykonywania zapytania.

Policzmy liczbę unikalnych adresów IP, jeśli są one przechowywane jako liczby. Daje to 137 milionów linii na sekundę. Jeśli to samo ma postać ciągów znaków, to 37 milionów linii na sekundę. Nie wiem dlaczego zdarzył się ten zbieg okoliczności. Sam spełniłem te prośby. Ale nadal około 4 razy wolniej.

A jeśli obliczysz różnicę w przestrzeni dyskowej, to również będzie różnica. A różnica wynosi około jednej czwartej, bo unikalnych adresów IP jest całkiem sporo. A gdyby istniały linie o niewielkiej liczbie różnych znaczeń, wówczas zgodnie ze słownikiem można je łatwo skompresować do mniej więcej tej samej objętości.

A czterokrotna różnica czasu nie leży w drodze. Może cię to oczywiście nie obchodzi, ale kiedy widzę taką różnicę, jest mi smutno.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Przyjrzyjmy się różnym przypadkom.

1. Jeden przypadek, gdy masz kilka różnych unikalnych wartości. W tym przypadku stosujemy prostą praktykę, którą prawdopodobnie znasz i możesz zastosować w dowolnym systemie DBMS. To wszystko ma sens nie tylko dla ClickHouse. Wystarczy wpisać identyfikatory numeryczne do bazy danych. Możesz także konwertować na ciągi znaków i z powrotem z boku aplikacji.

Na przykład masz region. I próbujesz zapisać go jako ciąg znaków. I będzie tam napisane: Moskwa i obwód moskiewski. A kiedy widzę, że jest napisane „Moskwa”, to nic, ale kiedy jest to Moskwa, jakoś robi się zupełnie smutno. To jest liczba bajtów.

Zamiast tego po prostu zapisujemy liczbę Ulnt32 i 250. W Yandex mamy 250, ale Twój może być inny. Na wszelki wypadek powiem, że ClickHouse ma wbudowaną możliwość pracy z geobazą. Po prostu zapisujesz katalog z regionami, w tym hierarchiczny, tj. będzie Moskwa, obwód moskiewski i wszystko, czego potrzebujesz. I możesz konwertować na poziomie żądania.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Druga opcja jest w przybliżeniu taka sama, ale z obsługą w ClickHouse. To jest typ danych Enum. Po prostu wpisz wszystkie potrzebne wartości w Enum. Na przykład wpisz typ urządzenia i wpisz: komputer stacjonarny, telefon komórkowy, tablet, telewizor. W sumie są 4 opcje.

Wadą jest to, że trzeba go okresowo zmieniać. Dodano tylko jedną opcję. Zmieńmy stół. W rzeczywistości zmiana stołu w ClickHouse jest bezpłatna. Szczególnie darmowy dla Enum, ponieważ dane na dysku się nie zmieniają. Niemniej jednak alter uzyskuje blokadę* na stole i musi poczekać, aż wszystkie selekcje zostaną wykonane. I dopiero po wykonaniu tej zmiany, czyli nadal występują pewne niedogodności.

* w najnowszych wersjach ClickHouse ALTER jest całkowicie nieblokujący.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Inną opcją, dość unikalną dla ClickHouse, jest podłączenie zewnętrznych słowników. W ClickHouse możesz wpisywać liczby, a swoje książki telefoniczne prowadzić w dowolnym dogodnym dla Ciebie systemie. Na przykład możesz użyć: MySQL, Mongo, Postgres. Możesz nawet stworzyć własny mikroserwis, który będzie przesyłał te dane poprzez protokół http. A na poziomie ClickHouse piszesz funkcję, która przekonwertuje te dane z liczb na ciągi znaków.

Jest to wyspecjalizowany, ale bardzo skuteczny sposób wykonania złączenia na tabeli zewnętrznej. Istnieją dwie opcje. W jednym wykonaniu dane te będą całkowicie buforowane, całkowicie obecne w pamięci RAM i aktualizowane z pewną częstotliwością. W innej opcji, jeśli te dane nie mieszczą się w pamięci RAM, możesz je częściowo buforować.

Oto przykład. Jest Yandex.Direct. Jest też firma reklamowa i banery. Firm reklamowych jest prawdopodobnie około kilkudziesięciu milionów. I mniej więcej mieszczą się w pamięci RAM. A banerów są miliardy, nie mieszczą się. Używamy buforowanego słownika z MySQL.

Jedynym problemem jest to, że słownik buforowany będzie działał dobrze, jeśli współczynnik trafień jest bliski 100%. Jeśli jest mniejszy, to podczas przetwarzania zapytań o każdą partię danych będziesz musiał wziąć brakujące klucze i pobrać dane z MySQL. Jeśli chodzi o ClickHouse, to jeszcze mogę zagwarantować – tak, nie zwalnia, o innych systemach nie będę mówił.

Jako bonus, słowniki umożliwiają bardzo łatwą aktualizację danych w ClickHouse z mocą wsteczną. Oznacza to, że miałeś raport o firmach reklamowych, użytkownik po prostu zmienił firmę reklamową i we wszystkich starych danych, we wszystkich raportach te dane również się zmieniły. Jeśli napiszesz wiersze bezpośrednio do tabeli, nie będzie możliwości ich aktualizacji.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Inny sposób, gdy nie wiesz, skąd wziąć identyfikatory dla swoich ciągów. możesz po prostu to hashować. Co więcej, najprostszą opcją jest pobranie 64-bitowego skrótu.

Jedynym problemem jest to, że jeśli skrót jest 64-bitowy, prawie na pewno wystąpią kolizje. Ponieważ jeśli jest tam miliard linii, prawdopodobieństwo już staje się zauważalne.

A mieszanie w ten sposób nazw firm reklamowych nie byłoby zbyt dobre. Jeśli kampanie reklamowe różnych firm zostaną pomieszane, powstanie coś niezrozumiałego.

I jest prosty trik. To prawda, że ​​\uXNUMXb\uXNUMXbnie nadaje się również do poważnych danych, ale jeśli coś nie jest bardzo poważne, po prostu dodaj identyfikator klienta do klucza słownika. A wtedy będziesz miał kolizje, ale tylko w obrębie jednego klienta. Używamy tej metody do map linków w Yandex.Metrica. Mamy tam adresy URL, przechowujemy skróty. I wiemy, że oczywiście zdarzają się kolizje. Jednak podczas wyświetlania strony można pominąć prawdopodobieństwo, że na jednej stronie jednego użytkownika niektóre adresy URL zostaną sklejone i zostanie to zauważone.

Jako bonus, do wielu operacji wystarczą same skróty, a same ciągi znaków nie muszą być nigdzie przechowywane.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Innym przykładem jest sytuacja, gdy ciągi znaków są krótkie, na przykład domeny witryn internetowych. Można je przechowywać w niezmienionej formie. Lub na przykład język przeglądarki ru ma 2 bajty. Oczywiście bardzo mi przykro z powodu bajtów, ale nie martw się, 2 bajty to nie szkoda. Proszę zachować tak jak jest, nie martw się.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Inny przypadek ma miejsce, gdy przeciwnie, linii jest wiele i jest w nich wiele unikalnych, a nawet zestaw jest potencjalnie nieograniczony. Typowym przykładem są wyszukiwane frazy lub adresy URL. Wyszukiwane frazy, łącznie z literówkami. Zobaczmy, ile unikalnych wyszukiwanych słów pojawia się dziennie. I okazuje się, że stanowią one niemal połowę wszystkich wydarzeń. W tym przypadku możesz pomyśleć, że musisz znormalizować dane, policzyć identyfikatory i umieścić je w osobnej tabeli. Ale nie musisz tego robić. Po prostu zachowaj te linie takimi, jakie są.

Lepiej niczego nie wymyślać, bo jeśli przechowujesz to osobno, będziesz musiał zrobić łączenie. A to połączenie jest w najlepszym przypadku losowym dostępem do pamięci, jeśli nadal się w niej mieści. Jeśli to nie będzie pasować, będą problemy.

A jeśli dane są przechowywane na miejscu, to po prostu są odczytywane w wymaganej kolejności z systemu plików i wszystko jest w porządku.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Jeśli masz adresy URL lub inny złożony długi ciąg znaków, warto rozważyć, czy możesz wcześniej obliczyć jakiś wyciąg i zapisać go w osobnej kolumnie.

Na przykład w przypadku adresów URL możesz przechowywać domenę osobno. A jeśli naprawdę potrzebujesz domeny, po prostu użyj tej kolumny, a adresy URL będą tam leżeć, a ty nawet ich nie dotkniesz.

Zobaczmy, jaka jest różnica. ClickHouse posiada wyspecjalizowaną funkcję obliczającą domenę. Jest bardzo szybki, zoptymalizowaliśmy go. I szczerze mówiąc, nie jest nawet zgodny z RFC, ale mimo to uwzględnia wszystko, czego potrzebujemy.

W jednym przypadku po prostu otrzymamy adresy URL i obliczymy domenę. Daje to 166 milisekund. A jeśli weźmiemy gotową domenę, to okaże się, że zajmie to zaledwie 67 milisekund, czyli prawie trzy razy szybciej. I jest szybciej nie dlatego, że musimy wykonać jakieś obliczenia, ale dlatego, że czytamy mniej danych.

Dlatego jedno żądanie, które jest wolniejsze, ma większą prędkość gigabajtów na sekundę. Ponieważ czyta więcej gigabajtów. To zupełnie niepotrzebne dane. Żądanie wydaje się działać szybciej, ale jego wykonanie trwa dłużej.

A jeśli spojrzysz na ilość danych na dysku, okaże się, że adres URL ma 126 megabajtów, a domena tylko 5 megabajtów. Okazuje się, że 25 razy mniej. Niemniej jednak żądanie jest wykonywane tylko 4 razy szybciej. Ale to dlatego, że dane są gorące. A gdyby było zimno, prawdopodobnie byłoby 25 razy szybsze dzięki dyskowym we/wy.

Swoją drogą, jeśli oszacujesz, o ile mniejsza jest domena od adresu URL, okazuje się, że jest ona około 4 razy mniejsza, ale z jakiegoś powodu dane zajmują na dysku 25 razy mniej. Dlaczego? Z powodu kompresji. Adres URL jest skompresowany i domena jest skompresowana. Ale często adres URL zawiera mnóstwo śmieci.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

I oczywiście opłaca się używać odpowiednich typów danych, które są zaprojektowane specjalnie dla pożądanych wartości lub są odpowiednie. Jeśli korzystasz z protokołu IPv4, zapisz UInt32*. Jeśli IPv6, to FixString(16), ponieważ adres IPv6 ma 128 bitów, tj. jest przechowywany bezpośrednio w formacie binarnym.

Ale co, jeśli czasami masz adresy IPv4, a czasem IPv6? Tak, możesz przechowywać oba. Jedna kolumna dla IPv4, druga dla IPv6. Oczywiście istnieje możliwość wyświetlenia IPv4 w IPv6. To również zadziała, ale jeśli często potrzebujesz adresu IPv4 w żądaniach, dobrze byłoby umieścić go w osobnej kolumnie.

* ClickHouse ma teraz oddzielne typy danych IPv4, IPv6, które przechowują dane równie efektywnie jak liczby, ale reprezentują je równie wygodnie jak ciągi znaków.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Warto też pamiętać, że warto wcześniej przetworzyć dane. Na przykład otrzymujesz surowe dzienniki. I może nie powinieneś od razu umieszczać ich w ClickHouse, chociaż bardzo kuszące jest nic nie robić i wszystko będzie działać. Ale nadal warto przeprowadzić obliczenia, które są możliwe.

Na przykład wersja przeglądarki. W jakimś pobliskim dziale, na który nie chcę wskazywać palcem, wersja przeglądarki jest przechowywana w ten sposób, czyli jako ciąg znaków: 12.3. A następnie, aby sporządzić raport, biorą ten ciąg i dzielą go na tablicę, a następnie na pierwszy element tablicy. Naturalnie wszystko zwalnia. Zapytałem, dlaczego to robią. Powiedzieli mi, że nie lubią przedwczesnej optymalizacji. A ja nie lubię przedwczesnej pesymizacji.

Zatem w tym przypadku bardziej poprawne byłoby podzielenie na 4 kolumny. Tutaj się nie bójcie, bo to ClickHouse. ClickHouse to baza danych kolumnowa. A im bardziej schludne małe kolumny, tym lepiej. Będzie 5 wersji przeglądarki, utwórz 5 kolumn. Jest okej.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Przyjrzyjmy się teraz, co zrobić, jeśli masz dużo bardzo długich ciągów znaków i bardzo długich tablic. W ogóle nie trzeba ich przechowywać w ClickHouse. Zamiast tego możesz przechowywać identyfikator tylko w ClickHouse. I umieść te długie linie w jakimś innym systemie.

Na przykład jedna z naszych usług analitycznych ma pewne parametry zdarzeń. A jeśli parametrów zdarzeń jest wiele, po prostu zapisujemy pierwsze 512, które się pojawią. Bo 512 to nie szkoda.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

A jeśli nie możesz się zdecydować na typ danych, to możesz także zapisywać dane w ClickHouse, ale w tymczasowej tabeli typu Log, specjalnej dla danych tymczasowych. Następnie możesz przeanalizować, jaki rozkład wartości tam masz, co tam jest ogólnie i stworzyć odpowiednie typy.

*ClickHouse ma teraz typ danych Niska kardynalność co pozwala na efektywne przechowywanie ciągów przy mniejszym wysiłku.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Przyjrzyjmy się teraz innemu interesującemu przypadkowi. Czasami dla ludzi wszystko działa dziwnie. Wchodzę i to widzę. I od razu wydaje się, że zrobił to jakiś bardzo doświadczony, mądry administrator, który ma duże doświadczenie w konfigurowaniu MySQL w wersji 3.23.

Widzimy tutaj tysiąc tabel, z których każda rejestruje resztę dzielenia nie wiadomo czego przez tysiąc.

W zasadzie szanuję doświadczenie innych ludzi, w tym zrozumienie cierpienia, jakie można zyskać dzięki temu doświadczeniu.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

A przyczyny są mniej więcej jasne. Są to stare stereotypy, które mogły narosnąć podczas pracy z innymi systemami. Na przykład tabele MyISAM nie mają klastrowego klucza podstawowego. A taki sposób podziału danych może być desperacką próbą uzyskania tej samej funkcjonalności.

Innym powodem jest to, że trudno jest wykonywać jakiekolwiek operacje zmiany na dużych tabelach. Wszystko zostanie zablokowane. Chociaż we współczesnych wersjach MySQL problem ten nie jest już tak poważny.

Albo na przykład microsharding, ale o tym później.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

W ClickHouse nie ma takiej potrzeby, ponieważ po pierwsze, klucz podstawowy jest klastrowany, dane są uporządkowane według klucza podstawowego.

Czasami ludzie pytają mnie: „Jak zmienia się wydajność zapytań o zakres w ClickHouse w zależności od rozmiaru tabeli?” Mówię, że to się wcale nie zmienia. Na przykład masz tabelę zawierającą miliard wierszy i czytasz zakres jednego miliona wierszy. Wszystko w porządku. Jeśli w tabeli jest bilion wierszy, a ty przeczytasz milion wierszy, będzie prawie tak samo.

Po drugie, nie są wymagane żadne inne rzeczy, takie jak ręczne partycje. Jeśli wejdziesz i sprawdzisz, co jest w systemie plików, zobaczysz, że tabela to naprawdę poważna sprawa. A w środku jest coś w rodzaju przegródek. Oznacza to, że ClickHouse zrobi wszystko za Ciebie i nie musisz cierpieć.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Zmiana w ClickHouse jest bezpłatna, jeśli zmienisz kolumnę dodawania/upuszczania.

I nie powinieneś tworzyć małych tabel, ponieważ jeśli masz 10 wierszy lub 10 000 wierszy w tabeli, to nie ma to żadnego znaczenia. ClickHouse to system, który optymalizuje przepustowość, a nie opóźnienia, więc nie ma sensu przetwarzać 10 linii.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Prawidłowe jest użycie jednego dużego stołu. Pozbądź się starych stereotypów, wszystko będzie dobrze.

Jako bonus, w najnowszej wersji mamy teraz możliwość utworzenia dowolnego klucza partycjonowania w celu wykonywania wszelkiego rodzaju operacji konserwacyjnych na poszczególnych partycjach.

Np. potrzebujesz wielu małych tabel, np. gdy zachodzi potrzeba przetworzenia jakichś danych pośrednich, otrzymujesz porcje i musisz wykonać na nich transformację przed zapisaniem do tabeli końcowej. W tym przypadku istnieje wspaniały silnik tabeli - StripeLog. To trochę jak TinyLog, tylko lepsze.

* teraz ClickHouse również ma wejście funkcji tabeli.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Kolejnym antywzorcem jest microsharding. Na przykład musisz podzielić dane i masz 5 serwerów, a jutro będzie 6 serwerów. I zastanawiasz się, jak ponownie zrównoważyć te dane. Zamiast tego rozpadasz się nie na 5 odłamków, ale na 1 odłamków. Następnie mapujesz każdy z tych mikroodłamków na osobny serwer. I dostaniesz np. 000 ClickHouse na jednym serwerze. Oddzielne instancje na oddzielnych portach lub oddzielnych bazach danych.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Ale w ClickHouse nie jest to zbyt dobre. Ponieważ nawet jedna instancja ClickHouse próbuje wykorzystać wszystkie dostępne zasoby serwera do przetworzenia jednego żądania. Oznacza to, że masz jakiś serwer i ma on na przykład 56 rdzeni procesora. Uruchamiasz zapytanie, które zajmuje jedną sekundę i zużywa 56 rdzeni. A jeśli umieścisz tam 200 ClickHouse na jednym serwerze, to okaże się, że uruchomi się 10 000 wątków. Ogólnie wszystko będzie bardzo źle.

Innym powodem jest to, że rozkład pracy pomiędzy tymi instancjami będzie nierówny. Niektórzy skończą wcześniej, inni później. Gdyby to wszystko wydarzyło się w jednym przypadku, ClickHouse sam wymyśliłby, jak poprawnie rozdzielić dane pomiędzy wątkami.

Innym powodem jest to, że będziesz mieć komunikację międzyprocesorową za pośrednictwem protokołu TCP. Dane będą musiały zostać serializowane i deserializowane, a to oznacza ogromną liczbę mikroodłamków. To po prostu nie będzie działać skutecznie.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Kolejny antywzór, choć trudno go nazwać antywzorem. Jest to duża ilość wstępnej agregacji.

Ogólnie rzecz biorąc, wstępna agregacja jest dobra. Miałeś miliard wierszy, zagregowałeś je i wyszło 1 wierszy, a teraz zapytanie jest wykonywane natychmiast. Wszystko w porządku. Możesz to zrobić. W tym celu nawet ClickHouse ma specjalny typ tabeli, AggregatingMergeTree, który wykonuje agregację przyrostową w miarę wstawiania danych.

Są jednak chwile, kiedy myślisz, że będziemy agregować takie dane i agregować takie dane. A w jakimś sąsiednim dziale, nie chcę też mówić, który, używają tabel SummingMergeTree do podsumowania według klucza podstawowego, a około 20 kolumn jest używanych jako klucz podstawowy. Na wszelki wypadek zmieniłem nazwy niektórych kolumn dla zachowania tajemnicy, ale to w zasadzie tyle.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

I pojawiają się takie problemy. Po pierwsze, ilość danych nie zmniejsza się zbytnio. Na przykład zmniejsza się trzykrotnie. Trzykrotność to dobra cena, aby pozwolić sobie na nieograniczone możliwości analityczne, które powstają, jeśli Twoje dane nie są agregowane. Jeżeli dane są zagregowane, to zamiast analityki otrzymujemy jedynie żałosne statystyki.

A co w tym takiego specjalnego? Faktem jest, że ci ludzie z sąsiedniego działu czasami przychodzą i proszą o dodanie kolejnej kolumny do klucza podstawowego. Oznacza to, że zagregowaliśmy dane w ten sposób, ale teraz chcemy trochę więcej. Ale ClickHouse nie ma alternatywnego klucza podstawowego. Dlatego musimy napisać kilka skryptów w C++. A ja nie lubię skryptów, nawet jeśli są w C++.

A jeśli spojrzeć na to, do czego stworzono ClickHouse, to dane niezagregowane są dokładnie tym scenariuszem, dla którego się narodziły. Jeśli używasz ClickHouse do danych niezagregowanych, robisz to dobrze. Jeśli agregujesz, czasami można to wybaczyć.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Innym ciekawym przypadkiem są zapytania w nieskończonej pętli. Czasami idę na jakiś serwer produkcyjny i patrzę tam na pokaż listę procesów. I za każdym razem odkrywam, że dzieje się coś strasznego.

Na przykład tak. Od razu widać, że wszystko można załatwić w ramach jednego wniosku. Po prostu wpisz adres URL i listę.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Dlaczego wiele takich zapytań w nieskończonej pętli jest złych? Jeśli indeks nie jest używany, będziesz miał wiele przejść przez te same dane. Ale jeśli na przykład używany jest indeks, masz klucz podstawowy dla ru i piszesz tam url = coś. I myślisz, że jeśli z tabeli zostanie odczytany tylko jeden adres URL, wszystko będzie dobrze. Ale właściwie nie. Ponieważ ClickHouse robi wszystko partiami.

Kiedy musi przeczytać pewien zakres danych, czyta trochę więcej, ponieważ indeks w ClickHouse jest rzadki. Indeks ten nie pozwala na znalezienie pojedynczego wiersza w tabeli, a jedynie pewien zakres. Dane są kompresowane w blokach. Aby przeczytać jedną linię, musisz wziąć cały blok i go rozluźnić. A jeśli wykonujesz wiele zapytań, zadania będą się w dużym stopniu pokrywać i będziesz miał mnóstwo pracy do wykonania w kółko.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

A jako bonus możesz zauważyć, że w ClickHouse nie powinieneś bać się transferu nawet megabajtów, a nawet setek megabajtów do sekcji IN. Pamiętam z naszej praktyki, że jeśli w MySQL przeniesiemy garść wartości do sekcji IN, na przykład przeniesiemy tam 100 megabajtów jakichś liczb, to MySQL zjada 10 gigabajtów pamięci i nic więcej się z nią nie dzieje, wszystko działa słabo.

A drugie jest takie, że w ClickHouse, jeśli Twoje zapytania korzystają z indeksu, to zawsze nie jest to wolniejsze niż pełne skanowanie, czyli jeśli trzeba przeczytać prawie całą tabelę, to pójdzie sekwencyjnie i przeczyta całą tabelę. Ogólnie rzecz biorąc, rozwiąże to sam.

Niemniej jednak istnieją pewne trudności. Na przykład fakt, że IN z podzapytaniem nie korzysta z indeksu. Ale to jest nasz problem i musimy go rozwiązać. Nie ma tu nic fundamentalnego. Naprawimy to*.

Kolejną interesującą rzeczą jest to, że jeśli masz bardzo długie żądanie i trwa przetwarzanie rozproszone, to bardzo długie żądanie zostanie wysłane do każdego serwera bez kompresji. Na przykład 100 megabajtów i 500 serwerów. Odpowiednio będziesz mieć 50 gigabajtów przesłanych przez sieć. Zostanie przesłany i wtedy wszystko zakończy się pomyślnie.

*już używam; Wszystko zostało naprawione zgodnie z obietnicą.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Dość częstym przypadkiem jest żądanie pochodzące z interfejsu API. Na przykład stworzyłeś jakąś własną usługę. A jeśli ktoś potrzebuje Twojej usługi, to otwierasz API i dosłownie dwa dni później widzisz, że dzieje się coś niezrozumiałego. Wszystko jest przeciążone i napływają okropne prośby, które nigdy nie powinny się wydarzyć.

Rozwiązanie jest tylko jedno. Jeśli otworzyłeś API, będziesz musiał je wyciąć. Na przykład wprowadź jakiś rodzaj kwot. Nie ma innych normalnych opcji. Inaczej od razu napiszą scenariusz i będą problemy.

ClickHouse ma specjalną funkcję - obliczanie kwot. Co więcej, możesz przenieść swój klucz przydziału. Jest to np. wewnętrzny identyfikator użytkownika. A kwoty będą naliczane niezależnie dla każdego z nich.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Teraz kolejna ciekawa rzecz. To jest replikacja ręczna.

Znam wiele przypadków, w których pomimo wbudowanej obsługi replikacji ClickHouse ludzie replikują ClickHouse ręcznie.

Jaka jest zasada? Masz potok przetwarzania danych. I działa niezależnie, na przykład w różnych centrach danych. Te same dane zapisujesz w ten sam sposób w ClickHouse. To prawda, praktyka pokazuje, że dane nadal będą się różnić ze względu na pewne funkcje w kodzie. Mam nadzieję, że jest w twoim.

Od czasu do czasu nadal będziesz musiał przeprowadzić ręczną synchronizację. Na przykład raz w miesiącu administratorzy wykonują polecenie rsync.

Tak naprawdę znacznie łatwiej jest skorzystać z replikacji wbudowanej w ClickHouse. Ale mogą istnieć pewne przeciwwskazania, ponieważ do tego trzeba użyć ZooKeepera. Nie powiem nic złego o ZooKeeperze, w zasadzie system działa, ale zdarza się, że ludzie z niego nie korzystają ze względu na java-fobię, bo ClickHouse to taki dobry system, napisany w C++, z którego można korzystać i wszystko będzie dobrze. A ZooKeeper jest w Javie. I jakoś nie chcesz nawet szukać, ale wtedy możesz skorzystać z ręcznej replikacji.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

ClickHouse to praktyczny system. Bierze pod uwagę Twoje potrzeby. Jeśli masz replikację ręczną, możesz utworzyć tabelę rozproszoną, która przegląda repliki ręczne i przełącza między nimi awaryjnie. Dostępna jest nawet specjalna opcja, która pozwala uniknąć flopów, nawet jeśli Twoje linie systematycznie się rozchodzą.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Jeśli użyjesz prymitywnych silników tabel, mogą pojawić się dalsze problemy. ClickHouse to konstruktor, który ma wiele różnych silników tabel. We wszystkich poważnych przypadkach, jak zapisano w dokumentacji, użyj tabel z rodziny MergeTree. I cała reszta - tak jest w indywidualnych przypadkach lub na potrzeby testów.

W tabeli MergeTree nie musisz mieć żadnej daty ani godziny. Nadal możesz z niego korzystać. Jeśli nie ma daty i godziny, wpisz, że wartość domyślna to 2000. To zadziała i nie będzie wymagało zasobów.

W nowej wersji serwera możesz nawet określić, że masz niestandardowe partycjonowanie bez klucza partycji. Będzie tak samo.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Z drugiej strony można używać prymitywnych silników tabel. Na przykład wypełnij dane raz, a następnie spójrz, przekręć i usuń. Możesz użyć Loga.

Lub przechowywanie małych woluminów do przetwarzania pośredniego to StripeLog lub TinyLog.

Pamięć można wykorzystać, jeśli ilość danych jest niewielka i można po prostu coś przekręcić w pamięci RAM.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

ClickHouse tak naprawdę nie lubi renormalizowanych danych.

Oto typowy przykład. To ogromna liczba adresów URL. Umieszczasz je w następnej tabeli. A potem postanowili zrobić z nimi JOIN, ale z reguły to nie zadziała, ponieważ ClickHouse obsługuje tylko Hash JOIN. Jeśli nie ma wystarczającej ilości pamięci RAM do połączenia dużej ilości danych, funkcja JOIN nie będzie działać*.

Jeśli dane mają dużą liczność, nie martw się, przechowuj je w zdenormalizowanej formie, adresy URL znajdują się bezpośrednio w głównej tabeli.

* a teraz ClickHouse posiada także funkcję łączenia scalającego, która działa w warunkach, w których dane pośrednie nie mieszczą się w pamięci RAM. Jest to jednak nieskuteczne i zalecenie pozostaje w mocy.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Jeszcze kilka przykładów, ale już wątpię, czy są one anty-wzorcowe, czy nie.

ClickHouse ma jedną znaną wadę. Nie wie, jak zaktualizować*. W pewnym sensie to nawet dobrze. Jeśli masz jakieś ważne dane, np. księgowe, to nikt nie będzie mógł ich przesłać, bo nie ma aktualizacji.

* obsługa aktualizacji i usuwania w trybie wsadowym została dodana dawno temu.

Istnieje jednak kilka specjalnych sposobów, które umożliwiają aktualizacje jakby w tle. Na przykład tabele takie jak ZamieńMergeTree. Dokonują aktualizacji podczas łączenia w tle. Możesz to wymusić, używając tabeli optymalizacji. Ale nie rób tego zbyt często, ponieważ spowoduje to całkowite nadpisanie partycji.

Rozproszone JOIN w ClickHouse są również źle obsługiwane przez planistę zapytań.

Źle, ale czasami OK.

Używanie ClickHouse tylko do odczytywania danych za pomocą opcji Select*.

Nie polecam używania ClickHouse do uciążliwych obliczeń. Nie jest to jednak do końca prawdą, gdyż już odchodzimy od tego zalecenia. Niedawno dodaliśmy możliwość stosowania modeli uczenia maszynowego w ClickHouse – Catboost. I niepokoi mnie to, bo myślę: „Co za horror. Okazuje się, ile cykli na bajt! Naprawdę nienawidzę marnować zegarów na bajty.

Efektywne wykorzystanie ClickHouse. Aleksiej Miłowidow (Yandex)

Ale nie bój się, zainstaluj ClickHouse, wszystko będzie dobrze. Jeśli już, to mamy społeczność. Swoją drogą, społeczność to ty. A jeśli masz jakieś problemy, możesz przynajmniej udać się na nasz czat i miejmy nadzieję, że ci pomogą.

pytania

Dziękujemy za raport! Gdzie mogę złożyć skargę dotyczącą awarii ClickHouse?

Możesz już teraz złożyć skargę do mnie osobiście.

Niedawno zacząłem używać ClickHouse. Natychmiast porzuciłem interfejs CLI.

Jesteś szczęściarzem.

Nieco później zawiesiłem serwer za pomocą małego wyboru.

Masz talent.

Otworzyłem błąd w GitHubie, ale został on zignorowany.

Zobaczymy.

Alexey namówił mnie do wzięcia udziału w raporcie, obiecując, że powie mi, w jaki sposób uzyskujesz dostęp do znajdujących się w nim danych.

Bardzo prosta.

Uświadomiłem sobie to wczoraj. Więcej szczegółów.

Nie ma tam strasznych sztuczek. Jest po prostu kompresja blok po bloku. Wartość domyślna to LZ4, możesz włączyć ZSTD*. Bloki od 64 kilobajtów do 1 megabajta.

* dostępna jest także obsługa specjalistycznych kodeków kompresyjnych, które można stosować w łańcuchu z innymi algorytmami.

Czy bloki to tylko surowe dane?

Nie do końca surowe. Istnieją tablice. Jeśli masz kolumnę liczbową, liczby w wierszu są umieszczane w tablicy.

Jest jasne.

Alexey, przykład dotyczył uniqExact przez IP, tj. fakt, że obliczenia uniqExact za pomocą linii zajmują więcej czasu niż liczb i tak dalej. A co jeśli zastosujemy zwód uszami i rzucimy na czas korekty? To znaczy, wydaje się, że powiedziałeś, że na naszym dysku nie różni się zbytnio. Jeśli odczytamy linie z dysku i rzutujemy, czy nasze agregaty będą szybsze, czy nie? A może jeszcze tutaj trochę zyskamy? Wydaje mi się, że testowałeś to, ale z jakiegoś powodu nie wskazałeś tego w benchmarku.

Myślę, że będzie wolniej niż bez castingu. W takim przypadku adres IP musi zostać przeanalizowany na podstawie ciągu. Oczywiście w ClickHouse zoptymalizowane jest również nasze parsowanie adresów IP. Bardzo się staraliśmy, ale tam masz liczby zapisane w formie dziesięciotysięcznej. Bardzo niewygodnie. Z kolei funkcja uniqExact będzie działać wolniej na ciągach znaków, nie tylko dlatego, że są to ciągi znaków, ale także dlatego, że wybrano inną specjalizację algorytmu. Ciągi są po prostu przetwarzane inaczej.

A co jeśli przyjmiemy bardziej prymitywny typ danych? Na przykład zapisaliśmy identyfikator użytkownika, który mamy, zapisaliśmy go w postaci linijki, a następnie zaszyfrowaliśmy, czy będzie fajniej, czy nie?

Wątpię. Myślę, że będzie jeszcze smutniej, bo przecież analizowanie liczb to poważny problem. Wydaje mi się, że ten kolega nawet dał raport na temat tego, jak trudno jest analizować liczby w formie dziesięciotysięcznej, ale może nie.

Alexey, dziękuję bardzo za raport! I bardzo dziękuję za ClickHouse! Mam pytanie odnośnie planów. Czy są plany wprowadzenia funkcji niepełnej aktualizacji słowników?

To znaczy częściowy restart?

Tak tak. Podobnie jak możliwość ustawienia tam pola MySQL, czyli aktualizacji po, aby ładowały się tylko te dane, jeśli słownik jest bardzo duży.

Bardzo interesująca funkcja. I myślę, że jakaś osoba zasugerowała to na naszym czacie. Może to nawet byłeś ty.

Nie sądzę.

Świetnie, teraz okazuje się, że są dwie prośby. I możesz powoli zacząć to robić. Ale chcę od razu ostrzec, że ta funkcja jest dość prosta do wdrożenia. Oznacza to, że teoretycznie wystarczy wpisać w tabelce numer wersji, a następnie wpisać: wersja mniejsza niż taka i taka. Oznacza to, że najprawdopodobniej zaoferujemy to pasjonatom. Czy jesteś entuzjastą?

Tak, ale niestety nie w C++.

Czy Twoi koledzy wiedzą, jak pisać w C++?

Znajdę kogoś.

Świetnie*.

* funkcja została dodana dwa miesiące po zgłoszeniu - autor pytania opracował ją i przesłał pociągnij żądanie.

Dziękuję!

Cześć! Dziękujemy za raport! Wspomniałeś, że ClickHouse bardzo dobrze wykorzystuje wszystkie dostępne zasoby. A mówca obok Luxofta opowiadał o swoim rozwiązaniu dla Poczty Rosyjskiej. Powiedział, że naprawdę spodobał im się ClickHouse, ale nie używali go zamiast swojego głównego konkurenta właśnie dlatego, że zżerał cały procesor. Nie mogli też podłączyć tego do swojej architektury, do swojego ZooKeepera z dokerami. Czy można w jakiś sposób ograniczyć ClickHouse tak, aby nie zużywał wszystkiego, co będzie mu dostępne?

Tak, jest to możliwe i bardzo łatwe. Jeśli chcesz zużywać mniej rdzeni, po prostu napisz set max_threads = 1. I to wszystko, wykona żądanie w jednym rdzeniu. Co więcej, możesz określić różne ustawienia dla różnych użytkowników. Więc nie ma problemu. I powiedz swoim kolegom z Luxoft, że to niedobrze, że nie znaleźli tego ustawienia w dokumentacji.

Aleksiej, cześć! Chciałbym zapytać o to pytanie. Nie pierwszy raz słyszę, że wiele osób zaczyna używać ClickHouse jako miejsca do przechowywania logów. W raporcie powiedziałeś, żeby tego nie robić, tj. nie musisz przechowywać długich ciągów. Co o tym sądzisz?

Po pierwsze, logi z reguły nie są długimi ciągami znaków. Są oczywiście wyjątki. Na przykład jakaś usługa napisana w Javie zgłasza wyjątek i jest rejestrowana. I tak dalej w nieskończonej pętli, aż skończy się miejsce na dysku twardym. Rozwiązanie jest bardzo proste. Jeśli linie są bardzo długie, przetnij je. Co znaczy długo? Dziesiątki kilobajtów są złe*.

* w najnowszych wersjach ClickHouse włączona jest „adaptacyjna granulacja indeksu”, co w większości eliminuje problem przechowywania długich wierszy.

Czy kilobajt jest normalny?

To normalne.

Cześć! Dziękujemy za raport! Pytałem już o to na czacie, ale nie pamiętam, czy otrzymałem odpowiedź. Czy są plany rozbudowy sekcji WITH na wzór CTE?

Jeszcze nie. Nasza sekcja WITH jest nieco niepoważna. Dla nas to taka mała funkcja.

Rozumiem. Dziękuję!

Dziękujemy za raport! Bardzo interesujące! Pytanie globalne. Czy są jakieś plany modyfikacji usuwania danych, być może w formie jakiegoś kodu pośredniczącego?

Koniecznie. To nasze pierwsze zadanie w kolejce. Teraz aktywnie myślimy o tym, jak zrobić wszystko poprawnie. I powinieneś zacząć naciskać klawiaturę*.

* nacisnął przyciski na klawiaturze i zrobił wszystko.

Czy wpłynie to w jakiś sposób na wydajność systemu, czy nie? Czy wstawianie będzie tak szybkie jak obecnie?

Być może same usunięcia i aktualizacje będą bardzo ciężkie, ale nie wpłynie to na wydajność selekcji ani wydajność wstawień.

I jeszcze jedno małe pytanie. Podczas prezentacji mówiłeś o kluczu podstawowym. W związku z tym mamy partycjonowanie, które jest domyślnie comiesięczne, prawda? A gdy ustalimy zakres dat mieszczący się w miesiącu, to czytana będzie tylko ta partycja, prawda?

Tak.

Pytanie. Jeśli nie możemy wybrać żadnego klucza podstawowego, to czy dobrze jest zrobić to konkretnie według pola „Data”, aby w tle było mniej przestawiania tych danych, aby pasowały w bardziej uporządkowany sposób? Jeśli nie masz zapytań o zakres i nie możesz nawet wybrać żadnego klucza podstawowego, czy warto umieścić datę w kluczu podstawowym?

Tak.

Być może sensowne jest umieszczenie w kluczu podstawowym pola, które będzie lepiej kompresować dane, jeśli zostaną posortowane według tego pola. Na przykład identyfikator użytkownika. Użytkownik na przykład odwiedza tę samą witrynę. W takim przypadku należy podać identyfikator użytkownika i godzinę. A wtedy Twoje dane będą lepiej skompresowane. Jeśli chodzi o datę, jeśli naprawdę nie masz i nigdy nie miałeś zapytań o zakres dat, nie musisz umieszczać daty w kluczu podstawowym.

Ok, bardzo dziękuję!

Źródło: www.habr.com

Dodaj komentarz