{"id":80775,"date":"2020-05-08T13:42:47","date_gmt":"2020-05-08T11:42:47","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/clickhouse-dlya-prodvinutyh-polzovatelej-v-voprosah-i-otvetah"},"modified":"2020-05-08T13:42:47","modified_gmt":"2020-05-08T11:42:47","slug":"clickhouse-dlya-prodvinutyh-polzovatelej-v-voprosah-i-otvetah","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/clickhouse-dlya-prodvinutyh-polzovatelej-v-voprosah-i-otvetah","title":{"rendered":"ClickHouse dla zaawansowanych u\u017cytkownik\u00f3w w pytaniach i odpowiedziach","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>W kwietniu in\u017cynierowie Avito spotkali si\u0119 na&nbsp;spotkaniu online z g\u0142\u00f3wnym deweloperem ClickHouse, Aleksejem Milowidowem, i Kirillem Szwakowem, deweloperem Golang z&nbsp;firmy Integros. Dyskutowali, jak wykorzystujemy system zarz\u0105dzania bazami danych i jakie trudno\u015bci napotykamy. <\/p>\n<p><\/p>\n<p>Na podstawie spotkania przygotowali\u015bmy artyku\u0142 z odpowiedziami ekspert\u00f3w na nasze i widz\u00f3w pytania dotycz\u0105ce backup\u00f3w, reshardingu danych, zewn\u0119trznych s\u0142ownik\u00f3w, sterownika Golang oraz aktualizacji wersji ClickHouse. Mo\u017ce by\u0107 on przydatny dla deweloper\u00f3w, kt\u00f3rzy ju\u017c aktywnie pracuj\u0105 z&nbsp;SGBD \u00abYandeks\u00bb i interesuj\u0105 si\u0119 jej tera\u017aniejszo\u015bci\u0105 i przysz\u0142o\u015bci\u0105. Domy\u015blnie odpowiedzi Alekseja Milowidowa, je\u015bli nie napisano inaczej. <\/p>\n<p><\/p>\n<p>Uwaga, pod&nbsp;tym wpisem znajduje si\u0119 du\u017co tekstu. Mamy nadziej\u0119, \u017ce tre\u015b\u0107 z pytaniami pomo\u017ce Ci si\u0119 zorientowa\u0107.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"ClickHouse dla zaawansowanych u\u017cytkownik\u00f3w w pytaniach i odpowiedziach\" src=\"\/wp-content\/uploads\/2020\/05\/242b1d8d002fe115614435c242297fd2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2 id=\"soderzhanie\">Spis tre\u015bci<\/h2>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"#old-data\">ClickHouse ci\u0105gle si\u0119 aktualizuje, a nasze dane \u2014 nie. Co z&nbsp;tym zrobi\u0107?<\/a><\/noindex> <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#backup-best-practicies\">Jakie s\u0105 najlepsze praktyki obecnie stosowane w&nbsp;tworzeniu kopii zapasowych danych z&nbsp;ClickHouse?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#replication\">Czy b\u0119dzie mo\u017cna zorganizowa\u0107 kontrolowane op\u00f3\u017anienie replik w&nbsp;walach?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#soooo-changeable\">Co robi\u0107, je\u015bli struktura tabeli si\u0119 zmieni\u0142a?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#resharding-best-practices\">Jakie s\u0105 obecnie najlepsze praktyki w&nbsp;reshardingu danych?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#clickhouse-copier\">W ClickHouse jest narz\u0119dzie clickhouse-copier. Czy mo\u017cesz o&nbsp;nim opowiedzie\u0107?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#resharding-tool\">Mieli\u015bcie pilota\u017cow\u0105 funkcj\u0119, kt\u00f3ra nazywa\u0142a si\u0119 resharding. Co si\u0119 z&nbsp;ni\u0105 dzieje?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#move-to-slow-disk\">Czy mo\u017cna po\u0142\u0105czy\u0107 wszystkie cz\u0119\u015bci danych w&nbsp;jeden element przed przeniesieniem na wolniejsze dyski?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#up-to-date\">Jak przechodzi\u0107 na nowe wersje ClickHouse, je\u015bli nie ma mo\u017cliwo\u015bci wcze\u015bniejszego sprawdzenia zgodno\u015bci?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#kill-query\">Zabijanie zapyta\u0144 powinno dzia\u0142a\u0107, ale nie dzia\u0142a. Dlaczego?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#reading-time\">Jak obliczy\u0107 czas odpowiedzi przy obci\u0105\u017ceniu odczytu?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#pimp-my-clickhouse\">Co dostroi\u0107 w&nbsp;ClickHouse, aby wi\u0119cej danych znajdowa\u0142o si\u0119 w&nbsp;cache?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#storage-configuration\">Jak mo\u017cna skonfigurowa\u0107 storage_configuration do przechowywania w pami\u0119ci operacyjnej?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#low-cardinality\">Do jakiej liczby unikalnych warto\u015bci Low Cardinality jest efektywny?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#fulltext-search\">Jakie s\u0105 najlepsze praktyki w&nbsp;pe\u0142notekstowym wyszukiwaniu w&nbsp;tablicy zawieraj\u0105cej pi\u0119\u0107 miliard\u00f3w wierszy?<\/a><\/noindex> <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#hello-and-welcome\">Jak najlepiej zorganizowa\u0107 dost\u0119p do ClickHouse dla du\u017cej liczby u\u017cytkownik\u00f3w?<\/a><\/noindex> <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#smorgasbord\">Czy mo\u017cna przekaza\u0107 wyniki jednego zapytania dziesi\u0119ciu klientom?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#asynchronous\">Co zrobi\u0107 z&nbsp;operacjami asynchronicznymi i materializowanymi widokami?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#dashboard\">W ClickHouse jest du\u017co log\u00f3w. Jak mog\u0119 zobaczy\u0107 wszystko, co si\u0119 dzieje z&nbsp;serwerem w&nbsp;tym momencie?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#zen\">Jak wp\u0142ywa\u0107 na&nbsp;mergery, aby serwer nie pada\u0142 w&nbsp;OOM?<\/a><\/noindex> <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#go\">Jak b\u0119dzie przebiega\u0107 rozw\u00f3j sterownika Golang dla ClickHouse?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#lazy-load\">Zewn\u0119trzny s\u0142ownik nie \u0142aduje si\u0119 po&nbsp;ponownym uruchomieniu z&nbsp;w\u0142\u0105czon\u0105 opcj\u0105 lazy_load. Co robi\u0107?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#reload-dictionaries\">Co zrobi\u0107, gdy system reload dictionaries nie \u0142aduje \u017cadnego z&nbsp;licznych s\u0142ownik\u00f3w, je\u015bli cho\u0107 jeden z&nbsp;nich ko\u0144czy si\u0119 b\u0142\u0119dem?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#connection\">Czy jest spos\u00f3b na skonfigurowanie danych w konfiguracji ClickHouse, \u017ceby nie ujawnia\u0107 ich w przypadku b\u0142\u0119d\u00f3w?<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"#zoom-backgrounds\">Bonus: t\u0142a na Zoom z naszych spotka\u0144<\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<blockquote><p>Je\u015bli nie chcesz czyta\u0107 tekstu, mo\u017cesz obejrze\u0107 nagranie spotkania. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=n1tm4j4W8ZQ&amp;t=8147s\">na naszym kanale YouTube<\/a><\/noindex>. Czas\u00f3wki znajduj\u0105 si\u0119 w pierwszym komentarzu pod wideo.<\/p><\/blockquote>\n<p><\/p>\n<h2 id=\"anchorold-dataanchorclickhouse-postoyanno-obnovlyaetsya-a-nashi-dannyenbsp-net-chto-snbspetim-delat\"><noindex><a rel=\"nofollow\" name=\"old-data\"><\/a><\/noindex>ClickHouse jest stale aktualizowany, a nasze dane nie. Co z tym zrobi\u0107?<\/h2>\n<p><\/p>\n<blockquote><p>ClickHouse jest stale aktualizowany, a nasze dane, kt\u00f3re zosta\u0142y przetworzone za pomoc\u0105 optimize final, nie s\u0105 aktualizowane i znajduj\u0105 si\u0119 w kopii zapasowej. <\/p>\n<p>Za\u0142\u00f3\u017cmy, \u017ce mieli\u015bmy jakikolwiek problem i dane zosta\u0142y utracone. Postanowili\u015bmy je przywr\u00f3ci\u0107 i okaza\u0142o si\u0119, \u017ce stare partycje, kt\u00f3re s\u0105 przechowywane na serwerach kopii zapasowej, bardzo mocno r\u00f3\u017cni\u0105 si\u0119 od aktualnie u\u017cywanej wersji ClickHouse. Co w takiej sytuacji zrobi\u0107 i czy jest to mo\u017cliwe?<\/p><\/blockquote>\n<p>Sytuacja, w kt\u00f3rej przywr\u00f3cono z kopii zapasowej dane w starym formacie, a w nowej wersji nie mo\u017cna ich pod\u0142\u0105czy\u0107, nie jest mo\u017cliwa. Zadbali\u015bmy o to, aby format danych w ClickHouse zawsze pozostawa\u0142 zgodny wstecz. To jest znacznie wa\u017cniejsze ni\u017c zgodno\u015b\u0107 funkcjonalno\u015bci, je\u015bli zmieni\u0142o si\u0119 zachowanie jakiej\u015b rzadko u\u017cywanej funkcji. Dane przechowywane na dysku w nowej wersji ClickHouse zawsze musz\u0105 by\u0107 czytelne. To jest zasada. <\/p>\n<p><\/p>\n<h2 id=\"anchorbackup-best-practiciesanchorkakie-luchshie-praktiki-est-nanbspdannyy-moment-ponbsprezervnomu-kopirovaniyu-dannyh-iznbspclickhouse\"><noindex><a rel=\"nofollow\" name=\"backup-best-practicies\"><\/a><\/noindex>Jakie s\u0105 najlepsze praktyki obecnie stosowane w&nbsp;tworzeniu kopii zapasowych danych z&nbsp;ClickHouse?<\/h2>\n<p><\/p>\n<blockquote><p>Jak robi\u0107 kopie zapasowe bior\u0105c pod uwag\u0119, \u017ce mamy operacje optimize final, ogromn\u0105 baz\u0119 danych na terabajty i dane, kt\u00f3re aktualizujemy, powiedzmy, przez ostatnie trzy dni, a p\u00f3\u017aniej nie przeprowadzamy z nimi \u017cadnych procedur? <\/p>\n<p>Mo\u017cemy stworzy\u0107 w\u0142asne rozwi\u0105zanie i na bashu napisa\u0107: zbieraj w ten i ten spos\u00f3b te kopie zapasowe. Mo\u017ce jednak nie trzeba nic wymy\u015bla\u0107, poniewa\u017c rower zosta\u0142 ju\u017c dawno wynaleziony? <\/p><\/blockquote>\n<p>Na pocz\u0105tek w kwestii najlepszych praktyk. Moi koledzy zawsze radz\u0105 w odpowiedzi na pytania dotycz\u0105ce kopii zapasowych przypomina\u0107 o us\u0142udze 'Yandex.Cloud', gdzie to zadanie jest ju\u017c rozwi\u0105zane. Skorzystaj z niej, je\u015bli masz tak\u0105 mo\u017cliwo\u015b\u0107. <\/p>\n<p><\/p>\n<p>Nie ma pe\u0142nego rozwi\u0105zania, w stu procentach wbudowanego w ClickHouse, dla kopii zapasowych. Istniej\u0105 pewne szablony, kt\u00f3re mo\u017cna wykorzysta\u0107. Aby uzyska\u0107 pe\u0142ne rozwi\u0105zanie, trzeba b\u0119dzie nieco samodzielnie si\u0119 tym zaj\u0105\u0107 lub stworzy\u0107 opakowania w postaci skrypt\u00f3w.<\/p>\n<p><\/p>\n<p>Zaczn\u0119 od najprostszych rozwi\u0105za\u0144 i zako\u0144cz\u0119 najbardziej z\u0142o\u017conymi w zale\u017cno\u015bci od obj\u0119to\u015bci danych i rozmiaru klastra. Im wi\u0119kszy klaster, tym bardziej skomplikowane staje si\u0119 rozwi\u0105zanie.<\/p>\n<p><\/p>\n<p>Je\u017celi tabela z danymi zajmuje tylko kilka gigabajt\u00f3w, kopi\u0119 zapasow\u0105 mo\u017cna wykona\u0107 w nast\u0119puj\u0105cy spos\u00f3b: <\/p>\n<p><\/p>\n<ol>\n<li>Zachowaj definicj\u0119 tabeli, czyli metadane \u2014 <strong>show create table<\/strong>.<\/li>\n<li>Zr\u00f3b zrzut przy pomocy klienta ClickHouse \u2014 <strong>select<\/strong> * <strong>z\u00a0tabeli<\/strong> do pliku. Domy\u015blnie otrzymasz plik w formacie TabSeparated. Je\u015bli chcesz bardziej efektywnie \u2014 mo\u017cesz w formacie Native. <\/li>\n<\/ol>\n<p><\/p>\n<p>Je\u015bli obj\u0119to\u015b\u0107 danych jest wi\u0119ksza, to kopia zapasowa zajmie wi\u0119cej czasu i du\u017co miejsca. Nazywa si\u0119 to kopi\u0105 zapasow\u0105 logiczn\u0105, nie jest zwi\u0105zana z formatem danych ClickHouse. Je\u017celi taka kopia istnieje, to w ostateczno\u015bci mo\u017cesz wzi\u0105\u0107 j\u0105 i za\u0142adowa\u0107 do MySQL w celu przywr\u00f3cenia. <\/p>\n<p><\/p>\n<p>Dla bardziej zaawansowanych przypadk\u00f3w w ClickHouse wbudowana jest mo\u017cliwo\u015b\u0107 stworzenia migawki partycji w lokalnym systemie plik\u00f3w. Mo\u017cliwo\u015b\u0107 ta dost\u0119pna jest w formie zapytania <strong>alter table freeze partition<\/strong>. Lub po\u00a0prostu <strong>alter table freeze<\/strong> \u2014 to\u00a0migawka ca\u0142ej tabeli. <\/p>\n<p><\/p>\n<p>Migawka zostanie utworzona w spos\u00f3b sp\u00f3jny dla jednej tabeli na jednym shardzie, co oznacza, \u017ce nie mo\u017cna w ten spos\u00f3b stworzy\u0107 sp\u00f3jnej migawki ca\u0142ego klastra. Jednak dla wi\u0119kszo\u015bci zada\u0144 taka potrzeba nie wyst\u0119puje i wystarczy na ka\u017cdym shardzie wykona\u0107 zapytanie i uzyska\u0107 sp\u00f3jn\u0105 migawk\u0119. Tworzona jest w formie hardlink\u00f3w i dlatego nie zajmuje dodatkowego miejsca. Nast\u0119pnie t\u0119 migawk\u0119 kopiujesz na serwer kopii zapasowej lub do magazynu, kt\u00f3rego u\u017cywasz do kopii zapasowych.<\/p>\n<p><\/p>\n<p>Odtworzenie takiej kopii zapasowej jest wystarczaj\u0105co proste. Najpierw tworzysz tabele wed\u0142ug dost\u0119pnych definicji tabel. Nast\u0119pnie kopiujesz zapisane migawki partycji do Directory-Detached dla danych tabel i wykonujesz zapytanie <strong>attach partition<\/strong>. Takie rozwi\u0105zanie jest ca\u0142kiem odpowiednie dla najbardziej powa\u017cnych obj\u0119to\u015bci danych. <\/p>\n<p><\/p>\n<p>Czasami potrzebne jest co\u015b jeszcze bardziej zaawansowanego \u2014 w przypadkach, gdy masz dziesi\u0105tki, a nawet setki terabajt\u00f3w na ka\u017cdym serwerze i setki serwer\u00f3w. Istnieje tutaj rozwi\u0105zanie, kt\u00f3re podpatrzy\u0142em u koleg\u00f3w z 'Yandex.Metrica'. Nie poleca\u0142bym go ka\u017cdemu \u2014 przeczytaj i sam zdecyduj, czy pasuje, czy nie. <\/p>\n<p><\/p>\n<p>Najpierw nale\u017cy stworzy\u0107 kilka serwer\u00f3w z du\u017cymi zasobami dyskowymi. Nast\u0119pnie na tych serwerach uruchomi\u0107 kilka serwer\u00f3w ClickHouse i skonfigurowa\u0107 je tak, aby dzia\u0142a\u0142y jako dodatkowa replika dla tych samych shard\u00f3w. A potem u\u017cywa\u0107 na tych serwerach systemu plik\u00f3w lub jakiego\u015b narz\u0119dzia, kt\u00f3re pozwala na tworzenie zrzut\u00f3w. S\u0105 dwie opcje. Pierwsza opcja to zrzuty LVM, druga opcja to ZFS na Linuxie. <\/p>\n<p><\/p>\n<p>Po tym codziennie nale\u017cy tworzy\u0107 zrzut, kt\u00f3ry b\u0119dzie zajmowa\u0142 jakie\u015b miejsce. Oczywi\u015bcie, je\u015bli dane si\u0119 zmieniaj\u0105, to z czasem obj\u0119to\u015b\u0107 zajmowanego miejsca b\u0119dzie si\u0119 zwi\u0119ksza\u0107. Taki zrzut mo\u017cna przywr\u00f3ci\u0107 w dowolnym momencie, to takie dziwne rozwi\u0105zanie. Dodatkowo trzeba ograniczy\u0107 te repliki w konfiguracji, aby nie pr\u00f3bowa\u0142y stawa\u0107 si\u0119 liderami.<\/p>\n<p><\/p>\n<h2 id=\"anchorreplicationanchormozhno-li-budet-organizovat-kontroliruemoe-otstavanie-replik-vnbspvalah\"><noindex><a rel=\"nofollow\" name=\"replication\"><\/a><\/noindex>Czy b\u0119dzie mo\u017cna zorganizowa\u0107 kontrolowane op\u00f3\u017anienie replik w&nbsp;walach?<\/h2>\n<p><\/p>\n<blockquote><p>W tym roku planujecie wprowadza\u0107 w ClickHouse walce. Czy b\u0119dzie mo\u017cna w nich zorganizowa\u0107 kontrolowane op\u00f3\u017anienie replik? Chcieliby\u015bmy przy jego pomocy zabezpieczy\u0107 si\u0119 przed negatywnymi scenariuszami z alternatywami i innymi zmianami. <\/p>\n<p>Czy mo\u017cna zrobi\u0107 jakie\u015b rollbacki dla alternatyw? Na przyk\u0142ad w istniej\u0105cym wale wzi\u0105\u0107 i powiedzie\u0107, \u017ce do tego momentu stosuj zmiany, a od tego momentu przesta\u0144 stosowa\u0107 zmiany?<\/p>\n<p>Je\u015bli do naszego klastra przysz\u0142a ekipa i go zepsu\u0142a, to mamy umown\u0105 replik\u0119 z op\u00f3\u017anieniem godzinnym, gdzie mo\u017cemy powiedzie\u0107, \u017ce chcemy u\u017cywa\u0107 w\u0142a\u015bnie jej w danym momencie, ale ostatnich dziesi\u0119ciu minut zmian w niej stosowa\u0107 nie b\u0119dziemy? <\/p><\/blockquote>\n<p>Na pocz\u0105tku o kontrolowanym op\u00f3\u017anieniu replik. Taki wniosek pojawi\u0142 si\u0119 od u\u017cytkownik\u00f3w i stworzyli\u015bmy zg\u0142oszenie na GitHubie z pro\u015bb\u0105: \u201eJe\u015bli kto\u015b tego potrzebuje, \u0142apka w g\u00f3r\u0119, dajcie serduszko\u201d. Nikt nie nacisn\u0105\u0142, wi\u0119c zg\u0142oszenie zamkni\u0119to. Niemniej jednak, ju\u017c teraz mo\u017cna uzyska\u0107 t\u0119 mo\u017cliwo\u015b\u0107, konfiguruj\u0105c ClickHouse. Prawda, tylko pocz\u0105wszy od wersji 20.3.<\/p>\n<p><\/p>\n<p>ClickHouse ci\u0105gle w tle prowadzi \u0142\u0105czenie danych \u2014 merge. Kiedy merge jest wykonany, pewien zestaw kawa\u0142k\u00f3w danych jest zast\u0119powany przez wi\u0119kszy kawa\u0142ek. Przy tym kawa\u0142ki danych, kt\u00f3re by\u0142y wcze\u015bniej, nadal pozostaj\u0105 na dysku przez pewien czas.<\/p>\n<p><\/p>\n<p>Po pierwsze, b\u0119d\u0105 one przechowywane tak d\u0142ugo, jak d\u0142ugo istniej\u0105 zapytania select, kt\u00f3re z nich korzystaj\u0105, aby zapewni\u0107 bezblokuj\u0105c\u0105 prac\u0119. Zapytania select spokojnie odczytuj\u0105 ze starych fragment\u00f3w.<\/p>\n<p><\/p>\n<p>Po drugie, istnieje te\u017c pr\u00f3g czasowy \u2014 stare fragmenty danych le\u017c\u0105 na dysku przez osiem minut. Te osiem minut mo\u017cna skonfigurowa\u0107 i wyd\u0142u\u017cy\u0107 nawet do jednego dnia. B\u0119dzie to kosztowa\u0107 miejsce na dysku: w zale\u017cno\u015bci od strumienia danych mo\u017ce si\u0119 okaza\u0107, \u017ce w ci\u0105gu ostatniego dnia dane nie tylko si\u0119 podwajaj\u0105, mog\u0105 by\u0107 pi\u0119\u0107 razy wi\u0119ksze. Ale w przypadku powa\u017cnych problem\u00f3w mo\u017cesz zatrzyma\u0107 serwer ClickHouse i wszystko uporz\u0105dkowa\u0107.<\/p>\n<p><\/p>\n<p>Teraz pojawia si\u0119 pytanie, jak to chroni przed alterami. Nale\u017cy spojrze\u0107 g\u0142\u0119biej, poniewa\u017c w starych wersjach ClickHouse alter dzia\u0142a\u0142 w ten spos\u00f3b, \u017ce po prostu zmienia\u0142 fragmenty. Jest fragment danych z jakimi\u015b plikami, i robimy na przyk\u0142ad <strong>alter drop column<\/strong>. Wtedy ta kolumna jest fizycznie usuwana ze wszystkich fragment\u00f3w.<\/p>\n<p><\/p>\n<p>Jednak zaczynaj\u0105c od wersji 20.3, mechanizm alter\u00f3w zosta\u0142 ca\u0142kowicie zmieniony i teraz fragmenty danych s\u0105 zawsze niemodyfikowalne. Nie zmieniaj\u0105 si\u0119 w og\u00f3le \u2014 altery dzia\u0142aj\u0105 teraz podobnie do merge. Zamiast zmienia\u0107 fragment na miejscu, tworzymy nowy. W nowym fragmencie pliki, kt\u00f3re si\u0119 nie zmieni\u0142y, staj\u0105 si\u0119 hardlinkami, a je\u015bli usuniemy jak\u0105\u015b kolumn\u0119, po prostu nie b\u0119dzie jej w nowym fragmencie. Stary fragment domy\u015blnie zostanie usuni\u0119ty po o\u015bmiu minutach, a tutaj mo\u017cna dostosowa\u0107 ustawienia, o kt\u00f3rych wspomniano powy\u017cej. <\/p>\n<p><\/p>\n<p>To samo dotyczy alter\u00f3w typu mutacji. Kiedy robisz <strong>alter delete<\/strong> lub <strong>alter update<\/strong>, nie zmienia fragmentu, a tworzy nowy. A potem usuwa stary.<\/p>\n<p><\/p>\n<h2 id=\"anchorsoooo-changeableanchorkak-byt-esli-struktura-tablicy-pomenyalas\"><noindex><a rel=\"nofollow\" name=\"soooo-changeable\"><\/a><\/noindex>Co robi\u0107, je\u015bli struktura tabeli si\u0119 zmieni\u0142a?<\/h2>\n<p><\/p>\n<blockquote><p>Jak przywr\u00f3ci\u0107 backup, kt\u00f3ry zosta\u0142 zrobiony ze star\u0105 schem\u0105? A drugie pytanie dotyczy przypadku z snapshotami i \u015brodkami systemu plik\u00f3w. Czy Btrfs nadaje si\u0119 tutaj zamiast ZFS w Linux LVM?<\/p><\/blockquote>\n<p>Je\u015bli wykonujesz <strong>attach partition<\/strong> partycje z inn\u0105 struktur\u0105, to ClickHouse powie Ci, \u017ce tak nie mo\u017cna. Oto rozwi\u0105zanie. Po pierwsze \u2014 utworzy\u0107 tymczasow\u0105 tabel\u0119 typu MergeTree ze star\u0105 struktur\u0105, do\u0142\u0105czy\u0107 tam dane za pomoc\u0105 attach, wykona\u0107 zapytanie alter. Nast\u0119pnie mo\u017cna albo skopiowa\u0107 lub przenie\u015b\u0107 te dane i ponownie wykona\u0107 attach, albo u\u017cy\u0107 zapytania. <strong>alter table move partition<\/strong>.<\/p>\n<p><\/p>\n<p>Teraz drugie pytanie \u2014 czy mo\u017cna u\u017cywa\u0107 Btrfs. Na pocz\u0105tek, je\u015bli masz LVM, wystarcz\u0105 zrzuty LVM, a system plik\u00f3w mo\u017ce by\u0107 ext4, to nie ma znaczenia. Z Btrfs wszystko zale\u017cy od twojego do\u015bwiadczenia z nim. To dojrza\u0142y system plik\u00f3w, ale wci\u0105\u017c pojawiaj\u0105 si\u0119 pewne w\u0105tpliwo\u015bci co do tego, jak wszystko zadzia\u0142a w praktyce w konkretnym scenariuszu. Nie poleca\u0142bym tego u\u017cywa\u0107, je\u015bli nie masz Btrfs w produkcji.<\/p>\n<p><\/p>\n<h2 id=\"anchorresharding-best-practicesanchorkakie-seychas-luchshie-praktiki-vnbspreshardinge-dannyh\"><noindex><a rel=\"nofollow\" name=\"resharding-best-practices\"><\/a><\/noindex>Jakie s\u0105 obecnie najlepsze praktyki w&nbsp;reshardingu danych?<\/h2>\n<p><\/p>\n<p>Pytanie o przeszardowanie jest skomplikowane i wieloaspektowe. Mo\u017cna odpowiedzie\u0107 na nie na kilka sposob\u00f3w. Mo\u017cna podej\u015b\u0107 od jednej strony i powiedzie\u0107, \u017ce w ClickHouse nie ma wbudowanej mo\u017cliwo\u015bci przeszardowania. Ale obawiam si\u0119, \u017ce ta odpowied\u017a nikogo nie zadowoli. Dlatego mo\u017cna podej\u015b\u0107 od drugiej strony i powiedzie\u0107, \u017ce w ClickHouse istnieje wiele sposob\u00f3w przeszardowania danych. <\/p>\n<p><\/p>\n<p>Je\u015bli ko\u0144czy si\u0119 miejsce w klastrze lub nie radzi sobie z obci\u0105\u017ceniem, dodajesz nowe serwery. Ale te serwery s\u0105 domy\u015blnie puste, nie ma na nich danych, nie ma \u017cadnego obci\u0105\u017cenia. Musisz przenie\u015b\u0107 dane, aby by\u0142y r\u00f3wnomiernie roz\u0142o\u017cone po nowym, powi\u0119kszonym klastrze.<\/p>\n<p><\/p>\n<p>Pierwszy spos\u00f3b, w jaki mo\u017cna to zrobi\u0107, to skopiowa\u0107 cz\u0119\u015b\u0107 partycji na nowe serwery za pomoc\u0105 zapytania. <strong>alter table fetch partition<\/strong>Na przyk\u0142ad, mia\u0142yby\u015b partycje wed\u0142ug miesi\u0119cy, bierzesz pierwszy miesi\u0105c 2017 roku i kopiujesz na nowy serwer, potem \u2014 trzeci miesi\u0105c kopiujesz na jaki\u015b inny nowy serwer. I tak robisz, a\u017c stanie si\u0119 to bardziej lub mniej r\u00f3wnomierne.<\/p>\n<p><\/p>\n<p>Przesuni\u0119cie mo\u017cna przeprowadzi\u0107 tylko dla tych partycji, kt\u00f3re nie zmieniaj\u0105 si\u0119 podczas zapisu. Dla \u015bwie\u017cych partycji zapisy musz\u0105 by\u0107 wy\u0142\u0105czone, poniewa\u017c ich przeniesienie nie jest atomowe. W przeciwnym razie otrzymasz duplikaty lub luki w danych. Niemniej jednak, ten spos\u00f3b jest praktyczny i dzia\u0142a wystarczaj\u0105co skutecznie. Po sieci przesy\u0142ane s\u0105 ju\u017c gotowe skompresowane partycje, co oznacza, \u017ce dane nie s\u0105 kompresowane ani ponownie kodowane.<\/p>\n<p><\/p>\n<p>Ta metoda ma jedn\u0105 wad\u0119, kt\u00f3ra zale\u017cy od schematu shardowania; istotne jest, czy zaplanowali\u015bcie ten schemat shardowania oraz jaki klucz shardowania u\u017cyli\u015bcie. W waszym przyk\u0142adzie dla przypadku z metrykami klucz shardowania to hash \u015bcie\u017cki. Podczas zapytania select w tabeli rozproszonej, dane s\u0105 pobierane z wszystkich shard\u00f3w klastra jednocze\u015bnie. <\/p>\n<p><\/p>\n<p>Oznacza to, \u017ce w praktyce nie ma znaczenia, jakie dane znajduj\u0105 si\u0119 na kt\u00f3rym shardzie. Najwa\u017cniejsze jest to, \u017ce dane z jedn\u0105 \u015bcie\u017ck\u0105 znajduj\u0105 si\u0119 na jednym shardzie, a na kt\u00f3rym dok\u0142adnie \u2014 to nie ma znaczenia. W takim przypadku przenoszenie gotowych partycji \u015bwietnie si\u0119 sprawdza, poniewa\u017c przy zapytaniach select zar\u00f3wno przed, jak i po przenoszeniu shard\u00f3w, schemat warto\u015bci nie odgrywa szczeg\u00f3lnej roli \u2014 otrzymacie pe\u0142ne dane.<\/p>\n<p><\/p>\n<p>Jednak s\u0105 sytuacje znacznie bardziej skomplikowane. Je\u015bli na poziomie logiki aplikacji zak\u0142adacie specjalny schemat shardowania, wed\u0142ug kt\u00f3rego ten klient znajduje si\u0119 na takim a nie innym shardzie, zapytanie mo\u017cna wys\u0142a\u0107 bezpo\u015brednio tam, a nie do tabeli rozproszonej. Lub u\u017cywacie wystarczaj\u0105co \u015bwie\u017cej wersji ClickHouse i w\u0142\u0105czyli\u015bcie ustawienie. <strong>optimize skip unused shards<\/strong>. W takim przypadku podczas zapytania select wyra\u017cenie w sekcji where zostanie przeanalizowane, a zostanie obliczone, na kt\u00f3re shardy nale\u017cy wys\u0142a\u0107 zapytanie zgodnie ze schematem shardowania. Dzia\u0142a to pod warunkiem, \u017ce dane s\u0105 rozmieszczone zgodnie z tym schematem shardowania. Je\u015bli przestawi\u0142e\u015b je r\u0119cznie, mo\u017ce doj\u015b\u0107 do zmiany zgodno\u015bci.<\/p>\n<p><\/p>\n<p>Tak wi\u0119c, to spos\u00f3b numer jeden. Czekam na twoj\u0105 odpowied\u017a, czy rozwi\u0105zanie jest odpowiednie, czy idziemy dalej.<\/p>\n<p><\/p>\n<p><strong>W\u0142odzimierz Ko\u0142obaev, g\u0142\u00f3wny administrator systemu w Avito<\/strong>: Aleksiej, ten spos\u00f3b, kt\u00f3ry wspomnia\u0142e\u015b, nie sprawdza si\u0119 zbyt dobrze, gdy trzeba roz\u0142o\u017cy\u0107 obci\u0105\u017cenie, w tym tak\u017ce obci\u0105\u017cenie odczytu. Mo\u017cemy wzi\u0105\u0107 miesi\u0119czn\u0105 partycj\u0119 i przenie\u015b\u0107 poprzedni miesi\u0105c na inn\u0105 w\u0119ze\u0142, ale kiedy przyjdzie zapytanie o te dane, b\u0119dziemy obci\u0105\u017ca\u0107 tylko t\u0119 jedn\u0105. A chcieliby\u015bmy obci\u0105\u017ca\u0107 ca\u0142y klaster, poniewa\u017c w przeciwnym razie przez jaki\u015b czas ca\u0142e obci\u0105\u017cenie odczytu b\u0119dzie obs\u0142ugiwane przez dwa shardy.<\/p>\n<p><\/p>\n<p><strong>Alieksiej Mi\u0142owidow:<\/strong> Odpowied\u017a jest dziwna \u2014 tak, \u017ale, ale mo\u017ce i si\u0119 uda. Wyja\u015bni\u0119, jak dok\u0142adnie. Warto spojrze\u0107 na scenariusz obci\u0105\u017cenia, kt\u00f3re generuje wasze dane. Je\u015bli to dane monitoruj\u0105ce, to niemal na pewno mo\u017cna powiedzie\u0107, \u017ce zdecydowana wi\u0119kszo\u015b\u0107 zapyta\u0144 dotyczy \u015bwie\u017cych danych. <\/p>\n<p><\/p>\n<p>Zainstalowali\u015bcie nowe serwery, przenie\u015bli\u015bcie stare partycje, ale r\u00f3wnie\u017c zmienili\u015bcie spos\u00f3b, w jaki s\u0105 zapisywane nowe dane. Nowe dane b\u0119d\u0105 roz\u0142o\u017cone po ca\u0142ym klastrze. W ten spos\u00f3b, ju\u017c po pi\u0119ciu minutach, zapytania za ostatnie pi\u0119\u0107 minut b\u0119d\u0105 r\u00f3wnomiernie obci\u0105\u017ca\u0107 klaster, a po dniu zapytania za dob\u0119 b\u0119d\u0105 r\u00f3wnomiernie obci\u0105\u017ca\u0107 klaster. Niestety, zapytania za poprzedni miesi\u0105c trafi\u0105 tylko na cz\u0119\u015b\u0107 serwer\u00f3w klastra.<\/p>\n<p><\/p>\n<p>Jednak cz\u0119sto nie b\u0119dziecie mieli zapyta\u0144 za luty 2019 roku. Zdecydowanie, je\u015bli zapytania dotycz\u0105 2019 roku, to b\u0119d\u0105 dotyczy\u0107 ca\u0142ego roku 2019 \u2014 du\u017cego interwa\u0142u czasu, a nie jakiego\u015b ma\u0142ego zakresu. Takie zapytania r\u00f3wnie\u017c b\u0119d\u0105 mog\u0142y r\u00f3wnomiernie obci\u0105\u017cy\u0107 klaster. Ale og\u00f3lnie macie ca\u0142kowit\u0105 racj\u0119, to ad hoc rozwi\u0105zanie, kt\u00f3re nie rozk\u0142ada danych ca\u0142kowicie r\u00f3wnomiernie.<\/p>\n<p><\/p>\n<p>Mam jeszcze kilka punkt\u00f3w na odpowied\u017a na pytanie. Jeden z nich dotyczy tego, jak od pocz\u0105tku stworzy\u0107 schemat shardowania, aby przesz\u0142o to z mniejszym b\u00f3lem. Nie zawsze jest to mo\u017cliwe.<\/p>\n<p><\/p>\n<p>Na przyk\u0142ad macie dane z monitoringu. Dane monitoringu rosn\u0105 z trzech powod\u00f3w. Pierwszy \u2014 gromadzenie danych historycznych. Drugi \u2014 wzrost ruchu. A trzeci \u2014 zwi\u0119kszona liczba rzeczy, kt\u00f3re podlegaj\u0105 monitoringowi. Pojawiaj\u0105 si\u0119 nowe mikroserwisy i metryki, kt\u00f3re trzeba zapisywa\u0107. <\/p>\n<p><\/p>\n<p>Mo\u017cliwe, \u017ce z tych powod\u00f3w najwi\u0119kszy wzrost dotyczy w\u0142a\u015bnie trzeciego powodu \u2014 zwi\u0119kszenia u\u017cycia monitoringu. W takim przypadku warto przyjrze\u0107 si\u0119 charakterowi obci\u0105\u017cenia, jakie s\u0105 podstawowe zapytania na select. G\u0142\u00f3wne zapytania na select prawdopodobnie b\u0119d\u0105 dotyczy\u0107 pewnego podzbioru metryk.<\/p>\n<p><\/p>\n<p>Na przyk\u0142ad wykorzystanie CPU na jakich\u015b serwerach przez jaki\u015b serwis. Ot\u00f3\u017c, istnieje pewien podzbi\u00f3r kluczy, na podstawie kt\u00f3rych te dane odzyskujecie. A samo zapytanie o te dane najprawdopodobniej jest do\u015b\u0107 proste i wykonuje si\u0119 w dziesi\u0105tkach milisekund. U\u017cywane jest do us\u0142ug monitorowania, do dashboard\u00f3w. Mam nadziej\u0119, \u017ce dobrze to rozumiem.<\/p>\n<p><\/p>\n<p><strong>W\u0142adimir Ko\u0142obaew:<\/strong> Chodzi o to, \u017ce bardzo cz\u0119sto odwo\u0142ujemy si\u0119 do danych historycznych, poniewa\u017c por\u00f3wnujemy bie\u017c\u0105c\u0105 sytuacj\u0119 z historycznymi w czasie rzeczywistym. Wa\u017cne jest dla nas szybkie uzyskanie dost\u0119pu do du\u017cej ilo\u015bci danych, a ClickHouse \u015bwietnie sobie z tym radzi.<\/p>\n<p><\/p>\n<p>Masz absolutnie racj\u0119, wi\u0119kszo\u015b\u0107 zapyta\u0144 odczytuj\u0105cych, kt\u00f3re mamy, pochodzi z ostatniego dnia, tak jak w ka\u017cdej systemie monitoringu. Jednak obci\u0105\u017cenie historycznymi danymi tak\u017ce jest do\u015b\u0107 du\u017ce. G\u0142\u00f3wnie pochodzi ono z systemu monitorowania, kt\u00f3ry co trzydzie\u015bci sekund pyta ClickHouse: \"Oddaj mi dane z ostatnich sze\u015bciu tygodni. A teraz zbuduj mi jak\u0105\u015b \u015bredni\u0105 ruchom\u0105 z tych danych i por\u00f3wnaj bie\u017c\u0105c\u0105 warto\u015b\u0107 z historyczn\u0105.\" <\/p>\n<p><\/p>\n<p>Chcia\u0142bym powiedzie\u0107, \u017ce mamy dla takich bardzo \u015bwie\u017cych zapyta\u0144 jeszcze jedn\u0105 ma\u0142\u0105 tabel\u0119, w kt\u00f3rej przechowujemy dane zaledwie za dwa dni, a g\u0142\u00f3wne zapytania trafiaj\u0105 do niej. Do du\u017cej rozproszonej tabeli przesy\u0142amy tylko du\u017ce zapytania historyczne.<\/p>\n<p><\/p>\n<p><strong>Alieksiej Mi\u0142owidow:<\/strong> Niestety, dla Twojego scenariusza nie ma to zastosowania, ale opisz\u0119 dwie z\u0142e i z\u0142o\u017cone schematy shardingu, kt\u00f3rych nie powinno si\u0119 stosowa\u0107, ale kt\u00f3re s\u0105 wykorzystywane w serwisie moich przyjaci\u00f3\u0142. <\/p>\n<p><\/p>\n<p>Jest g\u0142\u00f3wny klaster z wydarzeniami \u201eYandex.Metriki\u201d. Wydarzenia to ogl\u0105dania stron, klikni\u0119cia i przej\u015bcia. Wi\u0119kszo\u015b\u0107 zapyta\u0144 dotyczy konkretnej strony internetowej. Otwierasz serwis \u201eYandex.Metrika\u201d, masz stron\u0119 \u2014 avito.ru, wchodzisz w raport i zapytanie kieruje si\u0119 do Twojej strony.<\/p>\n<p><\/p>\n<p>Ale s\u0105 te\u017c inne zapytania \u2014 analityczne i globalne, kt\u00f3re wykonuj\u0105 analitycy wewn\u0119trzni. Na wszelki wypadek zaznaczam, \u017ce analitycy wewn\u0119trzni wykonuj\u0105 zapytania tylko dotycz\u0105ce serwis\u00f3w \u201eYandeksu\u201d. Jednak mimo to, serwisy \u201eYandeksu\u201d zajmuj\u0105 znaczn\u0105 cz\u0119\u015b\u0107 wszystkich danych. To s\u0105 zapytania nie do konkretnych licznik\u00f3w, ale do szerszej filtracji.<\/p>\n<p><\/p>\n<p>Jak zorganizowa\u0107 dane w taki spos\u00f3b, aby zar\u00f3wno zapytania dotycz\u0105ce jednego licznika dzia\u0142a\u0142y efektywnie, jak i globalne zapytania? Problem polega r\u00f3wnie\u017c na tym, \u017ce liczba zapyta\u0144 w ClickHouse w klastrze \u201eMetriki\u201d wynosi kilka tysi\u0119cy na sekund\u0119. Przy tym, nietrywialne zapytania, na przyk\u0142ad, kilka tysi\u0119cy na sekund\u0119, jeden serwer ClickHouse nie przetwarza.<\/p>\n<p><\/p>\n<p>Rozmiar klastra to ponad sze\u015b\u0107set serwer\u00f3w. Je\u015bli po prostu na\u0142o\u017cymy na ten klaster tabel\u0119 rozproszon\u0105 i b\u0119dziemy tam wysy\u0142a\u0107 kilka tysi\u0119cy zapyta\u0144, b\u0119dzie jeszcze gorzej ni\u017c wysy\u0142anie ich na jeden serwer. Z drugiej strony opcja, w kt\u00f3rej dane s\u0105 r\u00f3wnomiernie rozproszone, a my idziemy i pytamy ze wszystkich serwer\u00f3w, natychmiast odpada.<\/p>\n<p><\/p>\n<p>Istnieje diametralnie przeciwna opcja. Wyobra\u017amy sobie, \u017ce b\u0119dziemy szardowa\u0107 dane wed\u0142ug stron internetowych, a zapytanie dla jednej strony p\u00f3jdzie na jeden shard. Teraz klaster b\u0119dzie m\u00f3g\u0142 obs\u0142u\u017cy\u0107 dziesi\u0119\u0107 tysi\u0119cy zapyta\u0144 na sekund\u0119, ale na jednym shardzie jakie\u015b jedno zapytanie b\u0119dzie dzia\u0142a\u0107 zbyt wolno. Nie b\u0119dzie ju\u017c skalowa\u0107 si\u0119 pod wzgl\u0119dem przepustowo\u015bci. Szczeg\u00f3lnie je\u015bli chodzi o stron\u0119 avito.ru. Nie b\u0119dzie sekretu, je\u015bli powiem, \u017ce Avito to jedna z najbardziej odwiedzanych stron w Runecie. Obs\u0142ugiwanie jej na jednym shardzie by\u0142oby szale\u0144stwem.<\/p>\n<p><\/p>\n<p>Dlatego schemat szardowania jest zorganizowany w bardziej skomplikowany spos\u00f3b. Ca\u0142y klaster jest podzielony na pewn\u0105 liczb\u0119 klasterk\u00f3w, kt\u00f3re nazywamy warstwami. Wewn\u0105trz ka\u017cdego klasterka jest od dziesi\u0119ciu do kilku dziesi\u0105tek shard\u00f3w. A takich klasterk\u00f3w jest w sumie trzydzie\u015bci dziewi\u0119\u0107. <\/p>\n<p><\/p>\n<p>Jak to wszystko si\u0119 skaluje? Liczba klasterk\u00f3w si\u0119 nie zmienia \u2014 tak jak kilka lat temu by\u0142o ich trzydzie\u015bci dziewi\u0119\u0107, tak i teraz pozosta\u0142o. Ale wewn\u0105trz ka\u017cdego z nich stopniowo zwi\u0119kszamy liczb\u0119 shard\u00f3w w miar\u0119 gromadzenia danych. A schemat szardowania w zasadzie wygl\u0105da tak \u2014 podzia\u0142 na te klasterki odbywa si\u0119 wed\u0142ug stron internetowych, a aby zrozumie\u0107, kt\u00f3ra strona znajduje si\u0119 w kt\u00f3rym klastrze, u\u017cywana jest zupe\u0142nie osobna baza meta w MySQL. Jedna strona znajduje si\u0119 w jednym klasterku. A w jego wn\u0119trzu szardowanie odbywa si\u0119 wed\u0142ug identyfikator\u00f3w odwiedzaj\u0105cych.<\/p>\n<p><\/p>\n<p>Podczas rejestracji dzielimy je wed\u0142ug reszty z dzielenia identyfikatora odwiedzaj\u0105cego. Jednak przy dodawaniu nowego shardu schemat shardingowy si\u0119 zmienia, nadal dzielimy, ale wed\u0142ug reszty z dzielenia przez inn\u0105 liczb\u0119. To oznacza, \u017ce jeden odwiedzaj\u0105cy mo\u017ce znajdowa\u0107 si\u0119 na kilku serwerach, na co nie mo\u017cna si\u0119 opiera\u0107. Zosta\u0142o to zrobione wy\u0142\u0105cznie po to, aby dane lepiej si\u0119 kompresowa\u0142y. A przy zapytaniach idziemy do tabeli Distributed, kt\u00f3ra sprawdza klaster i zwraca si\u0119 do dziesi\u0105tek serwer\u00f3w. Taki absurdalny schemat.<\/p>\n<p><\/p>\n<p>Jednak moja opowie\u015b\u0107 b\u0119dzie niekompletna, je\u015bli nie powiem, \u017ce od tego schematu si\u0119 odst\u0105pili\u015bmy. W nowym schemacie wszystko zmienili\u015bmy i wszystkie dane skopiowali\u015bmy za pomoc\u0105 clickhouse-copier.<\/p>\n<p><\/p>\n<p>W nowym schemacie wszystkie strony dziel\u0105 si\u0119 na dwie kategorie - du\u017ce i ma\u0142e. Nie wiem, jak tam wybrano pr\u00f3g, ale w rezultacie du\u017ce witryny s\u0105 zapisywane na jednym klastrze, gdzie jest 120 shard\u00f3w po trzy repliki w ka\u017cdym - czyli 360 serwer\u00f3w. A schemat shardingu jest taki, \u017ce ka\u017cde zapytanie idzie od razu do wszystkich shard\u00f3w. Je\u015bli teraz w 'Yandex.Metrica' otworzysz dowoln\u0105 stron\u0119 raportu dla avito.ru, zapytanie p\u00f3jdzie do 120 serwer\u00f3w. Jest ma\u0142o du\u017cych witryn w runecie. Wi\u0119c zapyta\u0144 nie ma tysi\u0105ca na sekund\u0119, a nawet mniej ni\u017c sto. Wszystko to spokojnie przetwarza tabela Distributed, kt\u00f3r\u0105 ka\u017cdy z nich obs\u0142uguje 120 serwerami.<\/p>\n<p><\/p>\n<p>A drugi klaster - dla ma\u0142ych stron. Tutaj schemat shardingowy jest wed\u0142ug identyfikatora strony, a ka\u017cde zapytanie idzie dok\u0142adnie do jednego sharda.<\/p>\n<p><\/p>\n<h2 id=\"anchorclickhouse-copieranchorv-clickhouse-est-utilita-clickhouse-copier-mozhete-pronbspneyo-rasskazat\"><noindex><a rel=\"nofollow\" name=\"clickhouse-copier\"><\/a><\/noindex>W ClickHouse jest narz\u0119dzie clickhouse-copier. Czy mo\u017cesz o&nbsp;nim opowiedzie\u0107?<\/h2>\n<p><\/p>\n<p>Od razu powiem, \u017ce to rozwi\u0105zanie jest bardziej rozbudowane i nieco mniej wydajne. Zalet\u0105 jest to, \u017ce ca\u0142kowicie rozk\u0142ada dane zgodnie z podanym przez Ciebie schematem. Ale wad\u0105 narz\u0119dzia jest to, \u017ce nie wykonuje ponownego shardingu. Kopiuje dane z jednego schematu klastra do innego schematu klastra.<\/p>\n<p><\/p>\n<p>To oznacza, \u017ce do jej dzia\u0142ania potrzebujesz dw\u00f3ch klastr\u00f3w. Mog\u0105 by\u0107 one umieszczone na tych samych serwerach, ale mimo to dane nie b\u0119d\u0105 przenoszone inkrementalnie, lecz b\u0119d\u0105 kopiowane. <\/p>\n<p><\/p>\n<p>Na przyk\u0142ad, by\u0142o cztery serwery, a teraz jest osiem. Tworzysz now\u0105 tabel\u0119 rozproszon\u0105 oraz nowe lokalne tabele na wszystkich serwerach i uruchamiasz clickhouse-copier, wskazuj\u0105c w nim schemat dzia\u0142ania, aby mia\u0142 odczyta\u0107 stamt\u0105d, przyj\u0105\u0107 now\u0105 schemat shardowania i przenie\u015b\u0107 dane tam. Potrzebujesz na starych serwerach p\u00f3\u0142tora razy wi\u0119cej miejsca ni\u017c masz teraz, poniewa\u017c stare dane musz\u0105 tam pozosta\u0107, a dodatkowo przyjdzie na nie po\u0142owa z tych starych danych. Je\u015bli wcze\u015bniej pomy\u015bla\u0142e\u015b o tym, \u017ce dane musz\u0105 by\u0107 przeszardowane i masz miejsce, to takie rozwi\u0105zanie b\u0119dzie odpowiednie.<\/p>\n<p><\/p>\n<p>Jak dzia\u0142a clickhouse-copier wewn\u0119trznie? Dzieli ca\u0142\u0105 prac\u0119 na zestaw zada\u0144 do przetwarzania jednej partycji jednej tabeli na jednym shardzie. Wszystkie te zadania mog\u0105 by\u0107 wykonywane r\u00f3wnolegle, a clickhouse-copier mo\u017ce by\u0107 uruchomiony na r\u00f3\u017cnych maszynach w kilku egzemplarzach, ale to, co robi dla jednej partycji, to nic innego jak insert select. Dane s\u0105 odczytywane, dekompresowane, reorganizowane, potem znowu kompresowane, zapisywane gdzie indziej, przetwarzane na nowo. To bardziej skomplikowane rozwi\u0105zanie.<\/p>\n<p><\/p>\n<h2 id=\"anchorresharding-toolanchoru-vas-byla-pilotnaya-shtuka-kotoraya-nazyvalas-resharding-chto-snbspney\"><noindex><a rel=\"nofollow\" name=\"resharding-tool\"><\/a><\/noindex>Mieli\u015bcie pilota\u017cow\u0105 funkcj\u0119, kt\u00f3ra nazywa\u0142a si\u0119 resharding. Co si\u0119 z&nbsp;ni\u0105 dzieje?<\/h2>\n<p><\/p>\n<blockquote><p>Mieli\u015bcie co\u015b w 2017 roku, co nazywa\u0142o si\u0119 resharding. W ClickHouse nawet jest opcja. Rozumiem, \u017ce to nie wypali\u0142o. Mo\u017ce opowiesz, dlaczego tak si\u0119 sta\u0142o? Wydaje si\u0119 to do\u015b\u0107 aktualne.<\/p><\/blockquote>\n<p>Ca\u0142y problem polega na tym, \u017ce przy konieczno\u015bci przeszardowania danych na miejscu potrzebna jest do\u015b\u0107 skomplikowana synchronizacja, aby zrobi\u0107 to atomowo. Kiedy zacz\u0119li\u015bmy przygl\u0105da\u0107 si\u0119, jak ta synchronizacja dzia\u0142a, sta\u0142o si\u0119 jasne, \u017ce s\u0105 fundamentalne problemy. I te fundamentalne problemy nie s\u0105 tylko teoretyczne, ale od razu zacz\u0119\u0142y ujawnia\u0107 si\u0119 w praktyce w postaci tego, co mo\u017cna bardzo prosto wyja\u015bni\u0107 \u2013 nic nie dzia\u0142a.<\/p>\n<p><\/p>\n<h2 id=\"anchormove-to-slow-diskanchormozhno-li-slivat-vse-chasti-dannyh-voedino-perednbspperemescheniem-nanbspmedlennye-diski\"><noindex><a rel=\"nofollow\" name=\"move-to-slow-disk\"><\/a><\/noindex>Czy mo\u017cna po\u0142\u0105czy\u0107 wszystkie cz\u0119\u015bci danych w&nbsp;jeden element przed przeniesieniem na wolniejsze dyski?<\/h2>\n<p><\/p>\n<blockquote><p>Pytanie o TTL z opcj\u0105 przeniesienia na wolny dysk w kontek\u015bcie scalania. Czy jest spos\u00f3b, poza cronem, aby z\u0142\u0105czy\u0107 wszystkie cz\u0119\u015bci w jedn\u0105 przed przeniesieniem na wolne dyski?<\/p><\/blockquote>\n<p>Odpowied\u017a na pytanie, czy mo\u017cna automatycznie z\u0142\u0105czy\u0107 wszystkie kawa\u0142ki w jedn\u0105 przed ich przeniesieniem \u2013 nie. Uwa\u017cam, \u017ce nie ma takiej potrzeby. Mo\u017cna nie scala\u0107 wszystkich cz\u0119\u015bci w jedn\u0105, tylko po prostu liczy\u0107 na to, \u017ce b\u0119d\u0105 one automatycznie przenoszone na wolne dyski. <\/p>\n<p><\/p>\n<p>Mamy dwa kryteria regu\u0142 przenoszenia. Pierwsze \u2014 wed\u0142ug stopnia zape\u0142nienia. Je\u015bli na bie\u017c\u0105cym poziomie pami\u0119ci jest mniej ni\u017c pewien procent wolnego miejsca, wybieramy jedn\u0105 cz\u0119\u015b\u0107 i przenosimy j\u0105 na wolniejsze magazyny. A w\u0142a\u015bciwie nie na wolniejsze, lecz na nast\u0119pne \u2014 jak to ustawisz.<\/p>\n<p><\/p>\n<p>Drugie kryterium \u2014 wed\u0142ug rozmiaru. Dotyczy to przenoszenia du\u017cych fragment\u00f3w. Mo\u017cesz dostosowa\u0107 pr\u00f3g wed\u0142ug wolnego miejsca na szybkim dysku, a dane b\u0119d\u0105 przenoszone automatycznie.<\/p>\n<p><\/p>\n<h2 id=\"anchorup-to-dateanchorkak-pereezzhat-nanbspnovye-versii-clickhouse-esli-net-vozmozhnosti-zaranee-proverit-sovmestimost\"><noindex><a rel=\"nofollow\" name=\"up-to-date\"><\/a><\/noindex>Jak przechodzi\u0107 na nowe wersje ClickHouse, je\u015bli nie ma mo\u017cliwo\u015bci wcze\u015bniejszego sprawdzenia zgodno\u015bci?<\/h2>\n<p><\/p>\n<blockquote><p>Ten temat jest regularnie omawiany <noindex><a rel=\"nofollow\" href=\"https:\/\/teleg.run\/clickhouse_ru\">w czacie Telegram ClickHouse<\/a><\/noindex> z uwzgl\u0119dnieniem r\u00f3\u017cnych wersji, i mimo to. Jak bezpiecznie aktualizowa\u0107 z wersji 19.11 na 19.16 i, na przyk\u0142ad, z 19.16 na 20.3? Jak najlepiej migrowa\u0107 na nowe wersje, nie maj\u0105c mo\u017cliwo\u015bci wcze\u015bniejszego sprawdzenia kompatybilno\u015bci w piaskownicy?<\/p><\/blockquote>\n<p>Tu jest kilka \u201ez\u0142otych\u201d zasad. Pierwsza \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/ClickHouse\/ClickHouse\/blob\/master\/CHANGELOG.md\">czytaj changelog<\/a><\/noindex>. Jest obszerna, ale zawiera oddzielne punkty dotycz\u0105ce zmian niekompatybilnych wstecz. Nie traktuj tych punkt\u00f3w jako czerwonego flagi. Zazwyczaj s\u0105 to ma\u0142e niekompatybilno\u015bci zwi\u0105zane z niekt\u00f3rymi funkcjami brzegowymi, kt\u00f3re prawdopodobnie nie s\u0105 przez ciebie u\u017cywane.<\/p>\n<p><\/p>\n<p>Druga \u2014 je\u015bli nie ma mo\u017cliwo\u015bci sprawdzenia kompatybilno\u015bci w piaskownicy i chcesz zaktualizowa\u0107 od razu w produkcji, zalecenie jest takie \u2014 nie r\u00f3b tego. Najpierw stw\u00f3rz piaskownic\u0119 i sprawd\u017a. Je\u015bli nie masz \u015brodowiska testowego, to prawdopodobnie nie jeste\u015b bardzo du\u017c\u0105 firm\u0105, a wi\u0119c mo\u017cna skopiowa\u0107 cz\u0119\u015b\u0107 danych na sw\u00f3j laptop i upewni\u0107 si\u0119, \u017ce wszystko dzia\u0142a poprawnie. Mo\u017cesz nawet uruchomi\u0107 kilka replik lokalnie na swoim komputerze. Lub mo\u017cna gdzie\u015b obok uruchomi\u0107 now\u0105 wersj\u0119 i za\u0142adowa\u0107 tam cz\u0119\u015b\u0107 danych \u2014 czyli stworzy\u0107 improwizowane \u015brodowisko testowe. <\/p>\n<p><\/p>\n<p>Jeszcze jedna zasada \u2014 nie aktualizuj w ci\u0105gu tygodnia po wydaniu wersji z powodu \u0142apania b\u0142\u0119d\u00f3w w produkcji i subsequent rapid fixes. Przyjrzyjmy si\u0119 numeracji wersji ClickHouse, aby si\u0119 nie pogubi\u0107. <\/p>\n<p><\/p>\n<p>Wersja 20.3.4. Liczba 20 oznacza rok wydania \u2014 2020. Z punktu widzenia tego, co znajduje si\u0119 w \u015brodku, nie ma to \u017cadnego znaczenia, wi\u0119c nie b\u0119dziemy na to zwraca\u0107 uwagi. Nast\u0119pnie \u2014 20.3. Drug\u0105 cyfr\u0119 \u2014 w tym przypadku 3 \u2014 zwi\u0119kszamy za ka\u017cdym razem, gdy wydajemy wersj\u0119 z jak\u0105\u015b now\u0105 funkcjonalno\u015bci\u0105. Je\u015bli chcemy doda\u0107 do ClickHouse jak\u0105\u015b mo\u017cliwo\u015b\u0107, musimy zwi\u0119kszy\u0107 t\u0119 liczb\u0119. Oznacza to, \u017ce w wersji 20.4 ClickHouse b\u0119dzie dzia\u0142a\u0142 jeszcze lepiej. Trzecia cyfra \u2014 20.3.4. Tutaj 4 to liczba poprawek wersji, w kt\u00f3rych nie dodali\u015bmy nowych mo\u017cliwo\u015bci, ale naprawiali\u015bmy jakie\u015b b\u0142\u0119dy. I 4 oznacza, \u017ce zrobili\u015bmy to cztery razy.<\/p>\n<p><\/p>\n<p>Nie nale\u017cy my\u015ble\u0107, \u017ce to co\u015b strasznego. Zwykle u\u017cytkownik mo\u017ce zainstalowa\u0107 najnowsz\u0105 wersj\u0119, a ona b\u0119dzie dzia\u0142a\u0107 bez \u017cadnych problem\u00f3w z dost\u0119pno\u015bci\u0105 przez rok. Ale wyobra\u017acie sobie, \u017ce w jakiej\u015b funkcji do przetwarzania bitmap, kt\u00f3ra zosta\u0142a dodana przez naszych chi\u0144skich towarzyszy, przy przekazywaniu niepoprawnych argument\u00f3w serwer si\u0119 zawiesza. Musimy to naprawi\u0107. Wydamy now\u0105 wersj\u0119 poprawkow\u0105, a ClickHouse stanie si\u0119 bardziej stabilny.<\/p>\n<p><\/p>\n<p>Je\u015bli macie ClickHouse dzia\u0142aj\u0105cy w produkcji i pojawia si\u0119 nowa wersja ClickHouse z dodatkowymi funkcjami \u2014 na przyk\u0142ad 20.4.1 \u2014 nie spieszcie si\u0119 z wdro\u017ceniem jej do produkcji w pierwszy dzie\u0144. Po co to w og\u00f3le potrzebne? Je\u015bli jeszcze nie u\u017cywasz ClickHouse, mo\u017cesz j\u0105 zainstalowa\u0107, i prawdopodobnie wszystko b\u0119dzie w porz\u0105dku. Ale je\u015bli ClickHouse ju\u017c stabilnie dzia\u0142a, to \u015bled\u017acie poprawki i aktualizacje \u2014 jakie problemy naprawiamy.<\/p>\n<p><\/p>\n<p><strong>Kirill Shvakov:<\/strong> Chc\u0119 doda\u0107 troch\u0119 o \u015brodowiskach testowych. Wszyscy bardzo boj\u0105 si\u0119 \u015brodowisk testowych i jako\u015b uwa\u017caj\u0105, \u017ce je\u015bli masz bardzo du\u017cy klaster ClickHouse, to \u015brodowisko testowe te\u017c powinno by\u0107 co najmniej nie mniejsze albo przynajmniej dziesi\u0119\u0107 razy mniejsze. To nieprawda.<\/p>\n<p><\/p>\n<p>Mog\u0119 powiedzie\u0107 na swoim przyk\u0142adzie. Mam projekt, w kt\u00f3rym dzia\u0142a ClickHouse. Nasze \u015brodowisko testowe dla niego to ma\u0142a wirtualka w Hetzner za dwadzie\u015bcia euro, gdzie wszystko jest wdro\u017cone. Aby to zrobi\u0107, mamy pe\u0142n\u0105 automatyzacj\u0119 w Ansible, dlatego zasadniczo nie ma znaczenia, gdzie wdra\u017camy \u2014 na serwerach fizycznych czy po prostu na wirtualkach.<\/p>\n<p><\/p>\n<p>Co mo\u017cna zrobi\u0107? Dobrym pomys\u0142em by\u0142oby dostarczenie w dokumentacji ClickHouse przyk\u0142adu uruchomienia ma\u0142ego klastra \u2014 w Dockerze, w LXC, a by\u0107 mo\u017ce stworzenie playbooka Ansible, poniewa\u017c r\u00f3\u017cni ludzie maj\u0105 r\u00f3\u017cne wdro\u017cenia. To znacz\u0105co upro\u015bci\u0142oby spraw\u0119. Kiedy uruchamiasz klaster w pi\u0119\u0107 minut, znacznie \u0142atwiej jest zrozumie\u0107, co si\u0119 dzieje. To znacznie u\u0142atwia prac\u0119, poniewa\u017c wdra\u017canie wersji produkcyjnej, kt\u00f3rej nie sprawdzono, to droga donik\u0105d. Czasami dzia\u0142a, a czasami nie. Dlatego poleganie na sukcesie jest z\u0142ym pomys\u0142em.<\/p>\n<p><\/p>\n<p><strong>Maxim Kotyakov, starszy in\u017cynier backendu w Avito:<\/strong> Nieco rozszerz\u0119 temat \u015brodowisk testowych na podstawie problem\u00f3w du\u017cych firm. Mamy w pe\u0142ni funkcjonalny klaster akceptacyjny ClickHouse, w pe\u0142ni odpowiadaj\u0105cy schematom danych i konfiguracjom produkcyjnym. Ten klaster zosta\u0142 uruchomiony w do\u015b\u0107 przydomowych kontenerach z minimalnymi zasobami. Wysy\u0142amy tam pewien procent danych produkcyjnych, na szcz\u0119\u015bcie mamy mo\u017cliwo\u015b\u0107 replikacji strumienia w Kafce. Wszystko jest zsynchronizowane i dostosowane do mo\u017cliwo\u015bci oraz strumienia, a teoretycznie, przy innych r\u00f3wnych warunkach, powinno dzia\u0142a\u0107 jak produkcja w oparciu o metryki. Wszystkie potencjalnie niebezpieczne operacje s\u0105 najpierw uruchamiane na tym stanowisku i przez kilka dni dojrzewaj\u0105, a\u017c b\u0119d\u0105 gotowe. Oczywi\u015bcie, to rozwi\u0105zanie jest kosztowne, ci\u0119\u017ckie i wi\u0105\u017ce si\u0119 z pewnymi kosztami wsparcia. <\/p>\n<p><\/p>\n<p><strong>Alieksiej Mi\u0142owidow:<\/strong> Opowiem, jak wygl\u0105da testowe \u015brodowisko naszych przyjaci\u00f3\u0142 z \u201eYandex.Metrica\u201d. Jeden klaster sk\u0142ada\u0142 si\u0119 z ponad 600 serwer\u00f3w, drugi z 360, a jest jeszcze trzeci oraz kilka klastr\u00f3w. \u015arodowisko testowe dla jednego z nich to po prostu dwa shard'y z dwoma replikami w ka\u017cdym. Dlaczego dwa shard'y? \u017beby nie by\u0142o tylko jednego. I oczywi\u015bcie, \u017ceby by\u0142y te\u017c repliki. To po prostu minimalna liczba, na kt\u00f3r\u0105 mo\u017cemy sobie pozwoli\u0107.<\/p>\n<p><\/p>\n<p>To testowe \u015brodowisko pozwala sprawdzi\u0107, czy zapytania dzia\u0142aj\u0105 oraz czy nie wyst\u0105pi\u0142y powa\u017cne awarie. Jednak cz\u0119sto problemy pojawiaj\u0105 si\u0119 zupe\u0142nie innego rodzaju, gdy wszystko dzia\u0142a, ale istniej\u0105 pewne drobne zmiany obci\u0105\u017cenia.<\/p>\n<p><\/p>\n<p>Podam przyk\u0142ad. Postanowili\u015bmy zainstalowa\u0107 now\u0105 wersj\u0119 ClickHouse. Zosta\u0142a ona udost\u0119pniona na&nbsp;\u015brodowisko testowe, przesz\u0142y automatyczne testy w&nbsp;samej \u201eYandex.Metrice\u201d, kt\u00f3re por\u00f3wnuj\u0105 dane ze&nbsp;starej wersji i&nbsp;nowej, uruchamiaj\u0105c ca\u0142y proces. Oczywi\u015bcie, zielone testy naszego CI. W przeciwnym razie nawet nie zaproponowaliby\u015bmy tej wersji.<\/p>\n<p><\/p>\n<p>Wszystko jest w porz\u0105dku. Zaczynamy wdra\u017canie do&nbsp;produkcji. Dostaj\u0119 wiadomo\u015b\u0107, \u017ce obci\u0105\u017cenie na&nbsp;wykresach wzros\u0142o kilka razy. Cofamy wersj\u0119. Patrz\u0119 na&nbsp;wykres i&nbsp;widz\u0119: obci\u0105\u017cenie rzeczywi\u015bcie wzros\u0142o kilka razy w&nbsp;czasie wdra\u017cania, a nast\u0119pnie zmniejszy\u0142o si\u0119, gdy wersja zosta\u0142a wdro\u017cona. Potem zacz\u0119li\u015bmy cofa\u0107 wersj\u0119. I obci\u0105\u017cenie w tym przypadku r\u00f3wnie\u017c wzros\u0142o i tak samo spad\u0142o z powrotem. Tak wi\u0119c wnioskiem jest to, \u017ce obci\u0105\u017cenie wzros\u0142o w&nbsp;zwi\u0105zku z wdro\u017ceniem, nic niezwyk\u0142ego.<\/p>\n<p><\/p>\n<p>Potem by\u0142o trudno przekona\u0107 koleg\u00f3w, \u017ceby jednak zainstalowali now\u0105 wersj\u0119. M\u00f3wi\u0119: \u201eWszystko w porz\u0105dku, wdra\u017cajcie. Trzymajcie kciuki, wszystko b\u0119dzie dzia\u0142a\u0107. Obecnie obci\u0105\u017cenie wzros\u0142o na&nbsp;wykresach, ale wszystko jest w porz\u0105dku. Trzymajcie si\u0119\u201d. W sumie zrobili\u015bmy tak, i wszyscy \u2014 wersja wdro\u017cona do&nbsp;produkcji. Ale prawie przy&nbsp;ka\u017cdym wdro\u017ceniu pojawiaj\u0105 si\u0119 podobne problemy.<\/p>\n<p><\/p>\n<h2 id=\"anchorkill-queryanchorkill-query-dolzhen-ubivat-zaprosy-no-on-etogo-ne-delaet-pochemu\"><noindex><a rel=\"nofollow\" name=\"kill-query\"><\/a><\/noindex>Zabijanie zapyta\u0144 powinno dzia\u0142a\u0107, ale nie dzia\u0142a. Dlaczego?<\/h2>\n<p><\/p>\n<blockquote><p>Podszed\u0142 do mnie u\u017cytkownik, jaki\u015b analityk, i stworzy\u0142 zapytanie, kt\u00f3re zablokowa\u0142o m\u00f3j klaster ClickHouse. Jak\u0105\u015b nod\u0119 lub ca\u0142y klaster \u2014 w&nbsp;zale\u017cno\u015bci od tego, do&nbsp;jakiej repliki lub shardu trafi\u0142o zapytanie. Widz\u0119, \u017ce wszystkie zasoby CPU na&nbsp;tym serwerze s\u0105 obci\u0105\u017cone, wszystko na czerwono. Przy tym sam ClickHouse odpowiada na zapytania. I pisz\u0119: \u201ePoka\u017c mi, prosz\u0119, list\u0119 proces\u00f3w, kt\u00f3re zapocz\u0105tkowa\u0142y to szale\u0144stwo\u201d.<\/p>\n<p>Znajduj\u0119 to zapytanie i pisz\u0119 mu kill. I widz\u0119, \u017ce nic si\u0119 nie dzieje. M\u00f3j serwer jest obci\u0105\u017cony, ClickHouse dalej zwraca mi jakie\u015b komendy, pokazuje, \u017ce serwer dzia\u0142a, i wszystko jest w porz\u0105dku. Ale mam degradacj\u0119 we wszystkich zapytaniach u\u017cytkownik\u00f3w, zaczyna si\u0119 degradacja w&nbsp;zapisywaniu w ClickHouse, a m\u00f3j kill query nie dzia\u0142a. Dlaczego? My\u015bla\u0142em, \u017ce kill query powinien zabija\u0107 zapytania, a tak si\u0119 nie dzieje.<\/p><\/blockquote>\n<p>Teraz b\u0119dzie do\u015b\u0107 dziwna odpowied\u017a. Chodzi o to, \u017ce kill query nie zabija zapyta\u0144. <\/p>\n<p><\/p>\n<p>Kill query ustawia ma\u0142\u0105 flag\u0119 pod nazw\u0105 \"chc\u0119, aby to zapytanie zosta\u0142o zabite\". A same zapytanie podczas przetwarzania ka\u017cdego bloku sprawdza t\u0119 flag\u0119. Je\u015bli jest ustawiona, zapytanie przestaje dzia\u0142a\u0107. Okazuje si\u0119, \u017ce nikt nie zabija zapytania, ono samo musi wszystko sprawdzi\u0107 i si\u0119 zatrzyma\u0107. I to powinno dzia\u0142a\u0107 we wszystkich przypadkach, gdy zapytanie jest w stanie przetwarzania blok\u00f3w danych. Ono przetworzy nast\u0119pny blok danych, sprawdzi flag\u0119 i si\u0119 zatrzyma.<\/p>\n<p><\/p>\n<p>To nie dzia\u0142a w przypadkach, gdy zapytanie jest zablokowane na jakiej\u015b operacji. Prawda, najprawdopodobniej to nie jest tw\u00f3j przypadek, poniewa\u017c, wed\u0142ug twoich s\u0142\u00f3w, zu\u017cywa on mn\u00f3stwo zasob\u00f3w serwera. Mo\u017cliwe, \u017ce nie dzia\u0142a to w przypadku zewn\u0119trznej sortowania i kilku innych detali. Ale w og\u00f3le nie powinno tak by\u0107, to b\u0142\u0105d. I jedyne, co mog\u0119 doradzi\u0107, to zaktualizowa\u0107 ClickHouse.<\/p>\n<p><\/p>\n<h2 id=\"anchorreading-timeanchorkak-rasschitat-vremya-otveta-pri-chitayuschey-nagruzke\"><noindex><a rel=\"nofollow\" name=\"reading-time\"><\/a><\/noindex>Jak obliczy\u0107 czas odpowiedzi przy obci\u0105\u017ceniu odczytu?<\/h2>\n<p><\/p>\n<blockquote><p>Jest tabela, w kt\u00f3rej przechowywane s\u0105 agregaty po item \u2014 r\u00f3\u017cne liczniki. Liczba wierszy wynosi oko\u0142o stu milion\u00f3w. Czy mo\u017cna liczy\u0107 na przewidywalny czas odpowiedzi, je\u015bli b\u0119dzie 1K RPS przy 1K itemach? <\/p><\/blockquote>\n<p>S\u0105dz\u0105c po kontek\u015bcie, mowa o obci\u0105\u017ceniu do odczytu, poniewa\u017c nie ma \u017cadnych problem\u00f3w z zapisem \u2014 mo\u017cna wstawia\u0107 tysi\u0105c, sto tysi\u0119cy, a czasem nawet kilka milion\u00f3w wierszy. <\/p>\n<p><\/p>\n<p>Zapytania do odczytu s\u0105 bardzo r\u00f3\u017cnorodne. W select 1 ClickHouse mo\u017ce wykonywa\u0107 oko\u0142o dziesi\u0105tek tysi\u0119cy zapyta\u0144 na sekund\u0119, wi\u0119c nawet zapytania po jednym kluczu b\u0119d\u0105 wymaga\u0142y pewnych zasob\u00f3w. A takie zapytania punktowe b\u0119d\u0105 trudniejsze ni\u017c w jakichkolwiek bazach danych typu key-value, poniewa\u017c na ka\u017cde odczytanie trzeba przeczyta\u0107 blok danych zgodnie z indeksem. Indeks adresuje nie ka\u017cdy zapis, ale ka\u017cdy zakres. To znaczy, \u017ce trzeba b\u0119dzie przeczyta\u0107 ca\u0142y zakres \u2014 domy\u015blnie to 8192 wiersze. I trzeba b\u0119dzie rozpakowa\u0107 skompresowany blok danych z 64 Kb do 1 Mb. Zwykle takie zapytania punktowe zajmuj\u0105 od kilku milisekund. Ale to najprostszy wariant.<\/p>\n<p><\/p>\n<p>Spr\u00f3bujmy wykona\u0107 prost\u0105 arytmetyk\u0119. Je\u015bli pomno\u017cymy kilka milisekund przez tysi\u0105c, otrzymamy kilka sekund. Jakby nie da\u0142o si\u0119 utrzyma\u0107 tysi\u0105ca zapyta\u0144 na sekund\u0119, ale tak naprawd\u0119 mo\u017cna, poniewa\u017c mamy kilka rdzeni procesora. Zasadniczo ClickHouse czasami mo\u017ce obs\u0142u\u017cy\u0107 1000 RPS, ale tylko dla kr\u00f3tkich zapyta\u0144, takich jak zapytania punktowe.<\/p>\n<p><\/p>\n<p>Je\u015bli trzeba skalowa\u0107 klaster ClickHouse pod wzgl\u0119dem liczby prostych zapyta\u0144, polecam najprostsze rozwi\u0105zanie \u2014 zwi\u0119kszy\u0107 liczb\u0119 replik i wysy\u0142a\u0107 zapytania do losowej repliki. Je\u015bli jedna replika obs\u0142uguje pi\u0119\u0107set zapyta\u0144 na sekund\u0119, co jest ca\u0142kowicie realne, to trzy repliki obs\u0142u\u017c\u0105 p\u00f3\u0142torej tysi\u0105ca.<\/p>\n<p><\/p>\n<p>Czasami, oczywi\u015bcie, mo\u017cna dostroi\u0107 ClickHouse do maksymalnej liczby odczyt\u00f3w punktowych. Co trzeba zrobi\u0107? Po pierwsze \u2014 zmniejszy\u0107 granularno\u015b\u0107 indeksu. Przy tym zmniejsza\u0107 j\u0105 nale\u017cy nie do jedno\u015bci, ale bior\u0105c pod uwag\u0119, \u017ce liczba rekord\u00f3w w indeksie wyniesie kilka milion\u00f3w lub dziesi\u0105tki milion\u00f3w na serwerze. Je\u015bli w tabeli znajduje si\u0119 sto milion\u00f3w wierszy, to jako granularno\u015b\u0107 mo\u017cna ustawi\u0107 64.<\/p>\n<p><\/p>\n<p>Mo\u017cna zmniejszy\u0107 rozmiar skompresowanego bloku. Istniej\u0105 na to ustawienia. <strong>min compress block size<\/strong>, <strong>max compress block size<\/strong>Mo\u017cna je zmniejszy\u0107, ponownie przetransferowa\u0107 dane, a wtedy zapytania punktowe b\u0119d\u0105 szybsze. Ale mimo to ClickHouse nie jest baz\u0105 danych key-value. Du\u017ca liczba ma\u0142ych zapyta\u0144 to antypattern obci\u0105\u017cenia.<\/p>\n<p><\/p>\n<p><strong>Kirill Shvakov:<\/strong> Mam rad\u0119 na wypadek, je\u015bli s\u0105 tam zwyk\u0142e liczniki. To do\u015b\u0107 standardowa sytuacja, gdy w ClickHouse przechowuje si\u0119 jaki\u015b licznik. Mam u\u017cytkownika, pochodzi z takiego a takiego kraju, jakie\u015b trzecie pole i trzeba co\u015b inkrementalnie zwi\u0119ksza\u0107. Bierzemy MySQL, robimy unikalny klucz \u2014 w MySQL to klucz duplikuj\u0105cy, a w PostgreSQL to konflikt \u2014 i dodajemy plusikiem. To b\u0119dzie dzia\u0142a\u0107 znacznie lepiej. <\/p>\n<p><\/p>\n<p>Kiedy masz ma\u0142o danych, nie ma sensu u\u017cywa\u0107 ClickHouse. Istniej\u0105 zwyk\u0142e bazy danych i dobrze sobie z tym radz\u0105. <\/p>\n<p><\/p>\n<h2 id=\"anchorpimp-my-clickhouseanchorchto-podtyunit-v-clickhouse-chtoby-bolshe-dannyh-bylo-vnbspkeshe\"><noindex><a rel=\"nofollow\" name=\"pimp-my-clickhouse\"><\/a><\/noindex>Co dostroi\u0107 w ClickHouse, \u017ceby wi\u0119cej danych znajdowa\u0142o si\u0119 w cache'u?<\/h2>\n<p><\/p>\n<blockquote><p>Wyobra\u017amy sobie sytuacj\u0119 \u2014 na serwerach jest 256 GB RAM, w codziennej rutynie ClickHouse zajmuje oko\u0142o 60\u201480 GB, w szczytowych momentach \u2014 do 130. Co mo\u017cna w\u0142\u0105czy\u0107 i dostroi\u0107, aby wi\u0119cej danych by\u0142o w cache'u, a zatem mniej dost\u0119pu do dysku?<\/p><\/blockquote>\n<p>Zazwyczaj pami\u0119\u0107 podr\u0119czna systemu operacyjnego radzi sobie z tym zadaniem dobrze. Je\u015bli otwierasz po prostu stron\u0119 g\u0142\u00f3wn\u0105, sprawd\u017a, czy tam jest cached lub free \u2014 tam r\u00f3wnie\u017c znajduje si\u0119 informacja, ile pami\u0119ci zosta\u0142o zbuforowanej \u2014 mo\u017cna zauwa\u017cy\u0107, \u017ce ca\u0142a wolna pami\u0119\u0107 zosta\u0142a wykorzystana na pami\u0119\u0107 podr\u0119czn\u0105. Te dane przy odczycie b\u0119d\u0105 czytane nie z dysku, a z pami\u0119ci operacyjnej. Mog\u0119 powiedzie\u0107, \u017ce pami\u0119\u0107 podr\u0119czna jest wykorzystywana efektywnie, poniewa\u017c buforowane s\u0105 dok\u0142adnie skompresowane dane.<\/p>\n<p><\/p>\n<p>Mimo to, je\u015bli chcesz przyspieszy\u0107 niekt\u00f3re proste zapytania jeszcze bardziej, istnieje mo\u017cliwo\u015b\u0107 w\u0142\u0105czenia wewn\u0119trznej pami\u0119ci podr\u0119cznej w ClickHouse dla danych dekompresowanych. Nazywa si\u0119 to <strong>uncompressed cache<\/strong>. W pliku konfiguracyjnym config.xml ustawiasz rozmiar pami\u0119ci podr\u0119cznej dla danych niekompresowanych na po\u017c\u0105dan\u0105 warto\u015b\u0107 \u2014 zalecam nie wi\u0119cej ni\u017c po\u0142ow\u0119 wolnej pami\u0119ci operacyjnej, poniewa\u017c reszta p\u00f3jdzie na pami\u0119\u0107 podr\u0119czn\u0105 strony. <\/p>\n<p><\/p>\n<p>Ponadto istniej\u0105 dwa ustawienia na poziomie zapytania. Pierwsze ustawienie \u2014 <strong>use uncompressed cache<\/strong> \u2014 w\u0142\u0105cza jej u\u017cycie. Zaleca si\u0119 j\u0105 w\u0142\u0105cza\u0107 dla wszystkich zapyta\u0144, z wyj\u0105tkiem ci\u0119\u017ckich, kt\u00f3re mog\u0105 w og\u00f3le odczyta\u0107 wszystkie dane i w ten spos\u00f3b usun\u0105\u0107 t\u0119 pami\u0119\u0107 podr\u0119czn\u0105. A drugie ustawienie to co\u015b w rodzaju maksymalnej liczby wierszy do u\u017cywania pami\u0119ci podr\u0119cznej. Automatycznie ogranicza du\u017ce zapytania, aby omija\u0142y pami\u0119\u0107 podr\u0119czn\u0105.<\/p>\n<p><\/p>\n<h2 id=\"anchorstorage-configurationanchorkak-mozhno-nastroit-storage_configuration-dlya-hraneniya-v-operativke\"><noindex><a rel=\"nofollow\" name=\"storage-configuration\"><\/a><\/noindex>Jak mo\u017cna skonfigurowa\u0107 storage_configuration do przechowywania w pami\u0119ci operacyjnej?<\/h2>\n<p><\/p>\n<blockquote><p>W nowej dokumentacji ClickHouse znalaz\u0142em sekcj\u0119 zwi\u0105zan\u0105 <noindex><a rel=\"nofollow\" href=\"https:\/\/clickhouse.tech\/docs\/en\/single\/#table_engine-mergetree-multiple-volumes\">z przechowywaniem danych<\/a><\/noindex>. W opisie znajduje si\u0119 przyk\u0142ad z szybkim dyskiem SSD. <\/p>\n<p>Interesuj\u0105ce, jak mo\u017cna skonfigurowa\u0107 to samo z wolumenem pami\u0119ci hot. I jeszcze jedno pytanie. Jak dzia\u0142a select z tak\u0105 organizacj\u0105 danych, czy b\u0119dzie on czyta\u0142 ca\u0142y zbi\u00f3r, czy tylko te dane, kt\u00f3re le\u017c\u0105 na dysku, i czy te dane s\u0105 kompresowane w pami\u0119ci? I jak dzia\u0142a sekcja prewhere przy takiej organizacji danych?<\/p><\/blockquote>\n<p>To ustawienie wp\u0142ywa na przechowywanie fragment\u00f3w danych, a ich format w \u017caden spos\u00f3b si\u0119 nie zmienia.<br \/>\nZobaczmy to bli\u017cej. <\/p>\n<p><\/p>\n<p>Mo\u017cna skonfigurowa\u0107 przechowywanie danych w pami\u0119ci operacyjnej. Wszystko, co jest konfigurowane dla dysku \u2014 to jego \u015bcie\u017cka. Tworzysz partycj\u0119 tmpfs, kt\u00f3ra jest zamontowana w jakiej\u015b lokalizacji w systemie plik\u00f3w. Wskazujesz t\u0119 \u015bcie\u017ck\u0119 jako lokalizacj\u0119 do przechowywania danych dla najbardziej gor\u0105cej partycji, tam zaczynaj\u0105 nap\u0142ywa\u0107 i by\u0107 zapisywane fragmenty danych, wszystko dzia\u0142a dobrze. <\/p>\n<p><\/p>\n<p>Nie polecam tego robi\u0107 z powodu niskiej niezawodno\u015bci, chocia\u017c je\u015bli masz przynajmniej trzy kopie w r\u00f3\u017cnych centrach danych, to jest to mo\u017cliwe. W razie czego dane zostan\u0105 przywr\u00f3cone. Wyobra\u017amy sobie, \u017ce serwer nagle si\u0119 wy\u0142\u0105czy\u0142 i w\u0142\u0105czy\u0142 ponownie. Sekcja zamontowa\u0142a si\u0119 z powrotem, ale jest pusta. Serwer ClickHouse przy starcie widzi, \u017ce te fragmenty s\u0105 niedost\u0119pne, chocia\u017c zgodnie z metadanymi ZooKeeper powinny by\u0107. Sprawdza, na kt\u00f3rych replikach s\u0105 dost\u0119pne, prosi o nie i pobiera je. W ten spos\u00f3b dane zostan\u0105 przywr\u00f3cone. <\/p>\n<p><\/p>\n<p>W tym sensie przechowywanie danych w pami\u0119ci operacyjnej nie r\u00f3\u017cni si\u0119 zasadniczo od ich przechowywania na dysku, poniewa\u017c podczas zapisywania danych na dysk r\u00f3wnie\u017c najpierw trafiaj\u0105 one do pami\u0119ci cache strony i s\u0105 fizycznie zapisywane z op\u00f3\u017anieniem. Zale\u017cy to od opcji montowania systemu plik\u00f3w. Ale na wszelki wypadek powiem, \u017ce ClickHouse nie wykonuje fsync podczas wstawiania.<\/p>\n<p><\/p>\n<p>Dane w pami\u0119ci operacyjnej s\u0105 przechowywane w dok\u0142adnie tym samym formacie, co na dysku. Zapytanie select dzia\u0142a w taki sam spos\u00f3b, wybieraj\u0105c fragmenty, kt\u00f3re trzeba odczyta\u0107, wybiera potrzebne zakresy danych w fragmentach i je odczytuje. Dzia\u0142anie prewhere jest dok\u0142adnie takie samo, niezale\u017cnie od tego, czy dane by\u0142y w pami\u0119ci operacyjnej, czy na dysku.<\/p>\n<p><\/p>\n<h2 id=\"anchorlow-cardinalityanchordo-kakogo-kolichestva-unikalnyh-znacheniy-effektiven-low-cardinality\"><noindex><a rel=\"nofollow\" name=\"low-cardinality\"><\/a><\/noindex>Do jakiej liczby unikalnych warto\u015bci Low Cardinality jest efektywny?<\/h2>\n<p><\/p>\n<p>Low Cardinality jest sprytnie skonstruowane. Tworzy s\u0142owniki danych, ale s\u0105 one lokalne. Po pierwsze, ka\u017cdy fragment ma swoje w\u0142asne s\u0142owniki, a po drugie, nawet wewn\u0105trz jednego fragmentu mog\u0105 one by\u0107 r\u00f3\u017cne dla ka\u017cdego zakresu. Gdy liczba unikalnych warto\u015bci osi\u0105ga pr\u00f3g \u2014 wydaje mi si\u0119, \u017ce to milion \u2014 s\u0142ownik po prostu si\u0119 odk\u0142ada, a tworzy si\u0119 nowy.<\/p>\n<p><\/p>\n<p>Odpowied\u017a w skr\u00f3cie: dla ka\u017cdego lokalnego zakresu \u2014 powiedzmy, dla ka\u017cdego dnia \u2014 Low Cardinality jest efektywny przy liczbie unikalnych warto\u015bci do oko\u0142o miliona. Po tym nast\u0119puje fallback, w kt\u00f3rym u\u017cywane s\u0105 r\u00f3\u017cne s\u0142owniki, a nie jeden. Dzia\u0142a to mniej wi\u0119cej jak zwyk\u0142a kolumna typu string, mo\u017ce nieco mniej efektywnie, ale nie dojdzie do powa\u017cnej degradacji wydajno\u015bci. <\/p>\n<p><\/p>\n<h2 id=\"anchorfulltext-searchanchorkakie-luchshie-praktiki-ponbsppolnotekstovomu-poisku-ponbsptablice-snbsppyatyu-milliardami-strok\"><noindex><a rel=\"nofollow\" name=\"fulltext-search\"><\/a><\/noindex>Jakie s\u0105 najlepsze praktyki w&nbsp;pe\u0142notekstowym wyszukiwaniu w&nbsp;tablicy zawieraj\u0105cej pi\u0119\u0107 miliard\u00f3w wierszy?<\/h2>\n<p><\/p>\n<p>S\u0105 r\u00f3\u017cne opcje odpowiedzi. Pierwsza \u2014 powiedzie\u0107, \u017ce ClickHouse to nie system do pe\u0142notekstowego przeszukiwania. Istniej\u0105 do tego specjalne systemy, na przyk\u0142ad, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.elastic.co\/enterprise-search\">Elasticsearch<\/a><\/noindex> i <noindex><a rel=\"nofollow\" href=\"http:\/\/sphinxsearch.com\/\">Sphinx<\/a><\/noindex>. Niemniej jednak coraz cz\u0119\u015bciej spotykam ludzi, kt\u00f3rzy m\u00f3wi\u0105, \u017ce przechodz\u0105 z Elasticsearch na ClickHouse.<\/p>\n<p><\/p>\n<p>Dlaczego to si\u0119 dzieje? Wyja\u015bniaj\u0105 to tym, \u017ce Elasticsearch przestaje radzi\u0107 sobie z obci\u0105\u017ceniem przy niekt\u00f3rych wolumenach, pocz\u0105wszy od tego, co dotyczy budowy indeks\u00f3w. Indeksy staj\u0105 si\u0119 zbyt rozbudowane, a je\u015bli po prostu przeniesiemy dane do ClickHouse, oka\u017ce si\u0119, \u017ce s\u0105 one przechowywane wielokrotnie efektywniej pod wzgl\u0119dem obj\u0119to\u015bci. Przy tym zapytania wyszukuj\u0105ce cz\u0119sto nie polega\u0142y na znalezieniu w ca\u0142ej obj\u0119to\u015bci danych jakiej\u015b frazy z uwzgl\u0119dnieniem morfologii, a zupe\u0142nie innych. Na przyk\u0142ad, musimy znale\u017a\u0107 w logach z ostatnich kilku godzin jak\u0105\u015b podsekwencj\u0119 bajt\u00f3w.<\/p>\n<p><\/p>\n<p>W takim przypadku w ClickHouse tworzysz indeks, kt\u00f3rego pierwszym polem b\u0119dzie data z czasem. A najwi\u0119ksze ograniczenie danych b\u0119dzie w\u0142a\u015bnie wed\u0142ug zakresu dat. W obr\u0119bie wybranego zakresu dat zazwyczaj mo\u017cna przeprowadzi\u0107 pe\u0142notekstowe wyszukiwanie nawet metod\u0105 brute force za pomoc\u0105 like. Operator like w ClickHouse to najefektywniejszy operator like, jaki mo\u017cesz znale\u017a\u0107. Je\u015bli znajdziesz lepszy \u2014 daj mi zna\u0107. <\/p>\n<p><\/p>\n<p>Jednak nadal like to pe\u0142ne skanowanie. A pe\u0142ne skanowanie mo\u017ce by\u0107 wolne nie tylko z powodu CPU, ale i z powodu dysk\u00f3w. Je\u015bli nagle masz jeden terabajt danych dziennie, a w ci\u0105gu jednego dnia szukasz jakiego\u015b s\u0142owa, b\u0119dziesz musia\u0142 przeskanowa\u0107 terabajt. Z pewno\u015bci\u0105 znajduje si\u0119 on na zwyk\u0142ych dyskach twardych, a w rezultacie b\u0119d\u0105 one obci\u0105\u017cone tak, \u017ce nie wejdziesz na ten serwer przez SSH.<\/p>\n<p><\/p>\n<p>W tym przypadku jestem got\u00f3w zaproponowa\u0107 jeszcze jeden ma\u0142y trik. Jest on z kategorii eksperymentalnych \u2014 mo\u017ce zadzia\u0142a, a mo\u017ce nie. W ClickHouse istniej\u0105 pe\u0142notekstowe indeksy w postaci trigramowych filtr\u00f3w Bloom. Nasi koledzy z firmy Arenadata ju\u017c wypr\u00f3bowali te indeksy i cz\u0119sto dzia\u0142aj\u0105 one dok\u0142adnie tak, jak zamierzono.<\/p>\n<p><\/p>\n<p>Aby poprawnie je wykorzysta\u0107, nale\u017cy dobrze zrozumie\u0107, jak dok\u0142adnie dzia\u0142aj\u0105: co z siebie przedstawia trigramowy filtr Bloom i jak dobra\u0107 jego rozmiar. Mog\u0119 powiedzie\u0107, \u017ce pomog\u0105 w zapytaniach dotycz\u0105cych rzadkich fraz, podci\u0105g\u00f3w, kt\u00f3re rzadko wyst\u0119puj\u0105 w danych. W takim przypadku na podstawie indeks\u00f3w zostan\u0105 wybrane podzakresy, a odczytanych zostanie mniej danych.<\/p>\n<p><\/p>\n<p>Niedawno w ClickHouse pojawi\u0142y si\u0119 jeszcze bardziej zaawansowane funkcje wyszukiwania pe\u0142notekstowego. Po pierwsze, to wyszukiwanie wielu podci\u0105g\u00f3w w jednym przej\u015bciu, w tym opcje uwzgl\u0119dniaj\u0105ce wielko\u015b\u0107 liter, nieuwzgl\u0119dniaj\u0105ce wielko\u015bci liter, z obs\u0142ug\u0105 UTF-8 lub tylko dla ASCII. Wybierz najbardziej efektywn\u0105, kt\u00f3ra jest Ci potrzebna. <\/p>\n<p><\/p>\n<p>Pojawi\u0142o si\u0119 r\u00f3wnie\u017c wyszukiwanie kilku wyra\u017ce\u0144 regularnych w jednym przej\u015bciu. Nie musisz pisa\u0107 X like jeden podci\u0105g or X like inny podci\u0105g. Wystarczy, \u017ce napiszesz i wszystko odbywa si\u0119 maksymalnie efektywnie.<\/p>\n<p><\/p>\n<p>Po trzecie, teraz dost\u0119pne jest przybli\u017cone wyszukiwanie regex\u00f3w oraz przybli\u017cone wyszukiwanie podci\u0105g\u00f3w. Je\u015bli kto\u015b wpisa\u0142 s\u0142owo z liter\u00f3wk\u0105, b\u0119dzie ono wyszukiwane wed\u0142ug maksymalnego dopasowania.<\/p>\n<p><\/p>\n<h2 id=\"anchorhello-and-welcomeanchorkak-luchshe-organizovat-dostup-vnbspclickhouse-dlyanbspbolshogo-kolichestva-polzovateley\"><noindex><a rel=\"nofollow\" name=\"hello-and-welcome\"><\/a><\/noindex>Jak najlepiej zorganizowa\u0107 dost\u0119p do ClickHouse dla du\u017cej liczby u\u017cytkownik\u00f3w?<\/h2>\n<p><\/p>\n<blockquote><p>Powiedz, jak najlepiej zorganizowa\u0107 dost\u0119p dla du\u017cej liczby u\u017cytkownik\u00f3w i analityk\u00f3w. Jak utworzy\u0107 kolejk\u0119, priorytetyzowa\u0107 zapytania max concurrent queries, i jakich narz\u0119dzi u\u017cywa\u0107?<\/p><\/blockquote>\n<p>Je\u015bli klaster jest wystarczaj\u0105co du\u017cy, dobrym rozwi\u0105zaniem mo\u017ce by\u0107 uruchomienie dodatkowych dw\u00f3ch serwer\u00f3w, kt\u00f3re stan\u0105 si\u0119 punktem dost\u0119pu dla analityk\u00f3w. To znaczy, \u017ce nie wpuszczasz analityk\u00f3w do konkretnych shard\u00f3w klastra, a po prostu tworzysz dwa puste serwery, bez danych, a na nich ju\u017c ustawiasz prawa dost\u0119pu. Przy tym ustawienia u\u017cytkownik\u00f3w przy rozproszonych zapytaniach s\u0105 przekazywane na zdalne serwery. To znaczy, \u017ce konfigurujesz wszystko na tych dw\u00f3ch serwerach, a ustawienia maj\u0105 wp\u0142yw na ca\u0142y klaster.<\/p>\n<p><\/p>\n<p>W zasadzie te serwery s\u0105 bez danych, ale ilo\u015b\u0107 pami\u0119ci RAM na nich jest bardzo wa\u017cna dla realizacji zapyta\u0144. Dysk mo\u017ce by\u0107 r\u00f3wnie\u017c u\u017cywany do danych tymczasowych, je\u015bli w\u0142\u0105czona jest zewn\u0119trzna agregacja lub zewn\u0119trzne sortowanie.<\/p>\n<p><\/p>\n<p>Wa\u017cne jest, aby spojrze\u0107 na ustawienia zwi\u0105zane ze wszystkimi mo\u017cliwymi limitami. Je\u015bli teraz wejd\u0119 na klaster 'Yandex.Metrica' jako analityk i zadam zapytanie <strong>select count from hits<\/strong>, to od razu dostan\u0119 wyj\u0105tek, \u017ce nie mog\u0119 wykona\u0107 zapytania. Maksymalna liczba wierszy, kt\u00f3re mog\u0119 skanowa\u0107, to sto miliard\u00f3w, a w ca\u0142ym klastrze jest ich pi\u0119\u0107dziesi\u0105t bilion\u00f3w w jednej tabeli. To pierwsze ograniczenie. <\/p>\n<p><\/p>\n<p>Za\u0142\u00f3\u017cmy, \u017ce usun\u0119 ograniczenie dotycz\u0105ce liczby wierszy i wykonam zapytanie ponownie. Wtedy zobacz\u0119 nast\u0119pny wyj\u0105tek \u2014 w\u0142\u0105czona jest konfiguracja <strong>force index by date<\/strong>Nie mog\u0119 zrealizowa\u0107 zapytania, je\u015bli nie poda\u0142em zakresu dat. Nie mo\u017cna polega\u0107 na tym, \u017ce analitycy b\u0119d\u0105 to podawa\u0107 r\u0119cznie. Typowy przypadek&nbsp;\u2013 napisany zakres dat where event date between tydzie\u0144. A potem po prostu b\u0142\u0105d w nawiasach, i zamiast and wysz\u0142o or \u2014 or URL match. Je\u015bli nie ma ogranicze\u0144, zacznie skanowa\u0107 kolumn\u0119 URL i po prostu zu\u017cyje ogromne zasoby.<\/p>\n<p><\/p>\n<p>Ponadto, w ClickHouse istniej\u0105 dwie ustawienia priorytet\u00f3w. Niestety, s\u0105 one bardzo prymitywne. Jedno nazywa si\u0119 po prostu <strong>priority<\/strong>. Je\u015bli priority&nbsp;\u2260&nbsp;0, i s\u0105 realizowane zapytania z&nbsp;jakim\u015b priorytetem, ale w tym samym czasie realizowane jest zapytanie z&nbsp;priorytetem, kt\u00f3ry ma warto\u015b\u0107 mniejsz\u0105, co oznacza wy\u017cszy priorytet, to zapytanie o wy\u017cszym priorytecie, co oznacza ni\u017cszy priorytet, po prostu zostanie wstrzymane i w og\u00f3le nie b\u0119dzie dzia\u0142a\u0107 przez ten czas.<\/p>\n<p><\/p>\n<p>To bardzo surowe ustawienie, i nie nadaje si\u0119 dla przypadk\u00f3w, gdy na klastrze jest sta\u0142e obci\u0105\u017cenie. Ale je\u015bli masz kr\u00f3tkie, impulsywne zapytania wa\u017cne, a w wi\u0119kszo\u015bci klaster jest bezczynny, takie ustawienie b\u0119dzie odpowiednie.<\/p>\n<p><\/p>\n<p>Nast\u0119pne ustawienie priorytet\u00f3w nazywa si\u0119 <strong>priorytet w\u0105tku OS<\/strong>. Po prostu ustawia dla wszystkich w\u0105tk\u00f3w wykonania zapytania warto\u015b\u0107 nice dla scheduler\u2019a Linux. Dzia\u0142a do\u015b\u0107 przeci\u0119tnie, ale jednak dzia\u0142a. Je\u015bli ustawisz najmniejsz\u0105 warto\u015b\u0107 nice&nbsp;\u2014 jest to najwi\u0119ksza warto\u015b\u0107, co oznacza najni\u017cszy priorytet&nbsp;\u2014 a dla zapyta\u0144 z wysokim priorytetem ustawisz -19, to CPU b\u0119dzie wykorzystywa\u0107 niskoprioritetowe zapytania oko\u0142o cztery razy mniej ni\u017c wysokoprioritetowe. <\/p>\n<p><\/p>\n<p>Trzeba te\u017c ustawi\u0107 maksymalny czas realizacji zapytania&nbsp;\u2014 powiedzmy, pi\u0119\u0107 minut. Minimalna pr\u0119dko\u015b\u0107 realizacji zapytania&nbsp;\u2014 to najlepsze. To ustawienie istnieje od dawna i jest potrzebne, aby nie tylko twierdzi\u0107, \u017ce ClickHouse nie spowalnia, ale by to wymusi\u0107.<\/p>\n<p><\/p>\n<p>Wyobra\u017a sobie, \u017ce ustawiasz: je\u015bli jakie\u015b zapytanie przetwarza mniej ni\u017c milion wierszy na sekund\u0119&nbsp;\u2014 tego nie mo\u017cna robi\u0107. To szarga nasze dobre imi\u0119, nasz\u0105 dobr\u0105 baz\u0119 danych. Po prostu zr\u00f3bmy to zakazane. W rzeczywisto\u015bci s\u0105 tam dwa ustawienia. Jedno nazywa si\u0119 <strong>min execution speed<\/strong> \u2014 w&nbsp;linijkach na&nbsp;sekund\u0119, a druga nazywa si\u0119 timeout przed sprawdzeniem minimalnej pr\u0119dko\u015bci wykonania&nbsp;\u2014 domy\u015blnie pi\u0119tna\u015bcie sekund. To znaczy, \u017ce mo\u017cna pi\u0119tna\u015bcie sekund, a potem, je\u015bli wolno, to po prostu rzuci\u0107 wyj\u0105tek \u2014 przerwa\u0107 zapytanie.<\/p>\n<p><\/p>\n<p>Trzeba te\u017c skonfigurowa\u0107 limity. W&nbsp;ClickHouse jest wbudowana mo\u017cliwo\u015b\u0107 limit\u00f3w, kt\u00f3ra liczy zu\u017cycie zasob\u00f3w. Ale, niestety, nie zasob\u00f3w fizycznych, takich jak CPU czy dyski, a logicznych&nbsp;\u2014 liczba przetworzonych zapyta\u0144, wierszy i przeczytanych bajt\u00f3w. Mo\u017cna ustawi\u0107 na przyk\u0142ad maksimum sto zapyta\u0144 w&nbsp;ci\u0105gu pi\u0119ciu minut i tysi\u0105c zapyta\u0144 na&nbsp;godzin\u0119.<\/p>\n<p><\/p>\n<p>Dlaczego to jest wa\u017cne? Poniewa\u017c cz\u0119\u015b\u0107 zapyta\u0144 analitycznych b\u0119dzie wykonywana r\u0119cznie bezpo\u015brednio z&nbsp;klienta ClickHouse. I wszystko b\u0119dzie w porz\u0105dku. Ale je\u015bli w&nbsp;twojej firmie s\u0105 zaawansowani analitycy, to napisz\u0105 skrypt, a w&nbsp;skrypcie mo\u017ce by\u0107 b\u0142\u0105d. I ten b\u0142\u0105d spowoduje, \u017ce zapytanie zostanie wykonane w&nbsp;niesko\u0144czonej p\u0119tli. Przed tym nale\u017cy si\u0119 chroni\u0107.<\/p>\n<p><\/p>\n<h2 id=\"anchorsmorgasbordanchormozhno-li-otdat-rezultaty-odnogo-zaprosa-desyati-klientam\"><noindex><a rel=\"nofollow\" name=\"smorgasbord\"><\/a><\/noindex>Czy mo\u017cna przekaza\u0107 wyniki jednego zapytania dziesi\u0119ciu klientom?<\/h2>\n<p><\/p>\n<blockquote><p>Mamy kilku u\u017cytkownik\u00f3w, kt\u00f3rzy lubi\u0105 przychodzi\u0107 z&nbsp;bardzo du\u017cymi zapytaniami w&nbsp;jeden i ten sam moment. Zapytanie jest du\u017ce, zasadniczo wykonuje si\u0119 szybko, ale przez to, \u017ce takich zapyta\u0144 jest du\u017co jednocze\u015bnie, jest bardzo uci\u0105\u017cliwe. Czy mo\u017cna to samo zapytanie, kt\u00f3re przychodzi dziesi\u0119\u0107 razy z rz\u0119du, wykona\u0107 tylko raz, a wynik zwr\u00f3ci\u0107 dziesi\u0119ciu klientom?<\/p><\/blockquote>\n<p>Problem w tym, \u017ce nie mamy wynik\u00f3w z cache'a ani cache'a danych po\u015brednich. Jest pami\u0119\u0107 stron operacyjnego systemu, kt\u00f3ra pozwoli nie czyta\u0107 danych z&nbsp;dysku ponownie, ale, niestety, dane i tak b\u0119d\u0105 musia\u0142y by\u0107 dekompresowane, deserializowane i ponownie przetwarzane. <\/p>\n<p><\/p>\n<p>Chcia\u0142bym w jaki\u015b spos\u00f3b tego unikn\u0105\u0107, albo cache'uj\u0105c dane po\u015brednie, albo uk\u0142adaj\u0105c podobne zapytania w jak\u0105\u015b kolejk\u0119 i dodaj\u0105c cache wynik\u00f3w. Obecnie mamy w&amp;nbsprozwoju jeden pull request, kt\u00f3ry dodaje cache zapyta\u0144, ale tylko dla podzapyta\u0144 w sekcji in i join \u2014 to znaczy rozwi\u0105zanie jest niepe\u0142ne.<\/p>\n<p><\/p>\n<p>Mimo to, zdarza si\u0119, \u017ce r\u00f3wnie\u017c mamy tak\u0105 sytuacj\u0119. Szczeg\u00f3lnie kanoniczny przyk\u0142ad to zapytania z paginacj\u0105. Jest raport, w nim jest kilka stron i nast\u0119puje zapytanie limit 10. Potem to samo, ale limit 10,10. Nast\u0119pnie kolejna strona. I rodzi si\u0119 pytanie, dlaczego za ka\u017cdym razem to wszystko obliczamy? Ale w tej chwili nie ma rozwi\u0105zania i nie mo\u017cna tego unikn\u0105\u0107.<\/p>\n<p><\/p>\n<p>Istnieje alternatywne rozwi\u0105zanie, kt\u00f3re jest instalowane obok ClickHouse jako sidecar \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/Vertamedia\/chproxy\">ClickHouse Proxy<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><strong>Kirill Shvakov:<\/strong> W ClickHouse Proxy jest wbudowany limiter szybko\u015bci i wbudowany cache wynik\u00f3w. Zrobiono tam bardzo wiele ustawie\u0144, poniewa\u017c rozwi\u0105zano podobny problem. Proxy pozwala na limitowanie zapyta\u0144, uk\u0142adaj\u0105c je w kolejk\u0119, i ustawienie, jak d\u0142ugo \u017cyje cache zapyta\u0144. Je\u015bli zapytania by\u0142y naprawd\u0119 identyczne, Proxy zwr\u00f3ci je wielokrotnie, a do ClickHouse uda si\u0119 tylko raz.<\/p>\n<p><\/p>\n<p>W Nginx r\u00f3wnie\u017c jest cache w wersji darmowej i to tak\u017ce b\u0119dzie dzia\u0142a\u0107. W Nginx s\u0105 nawet ustawienia, kt\u00f3re w przypadku jednoczesnych zapyta\u0144 b\u0119d\u0105 op\u00f3\u017ania\u0107 inne, dop\u00f3ki jedno nie zostanie wykonane. Ale w\u0142a\u015bnie w ClickHouse Proxy ustawienie jest znacznie lepsze. Zosta\u0142o zaprojektowane specjalnie dla ClickHouse, w\u0142a\u015bnie pod te zapytania, dlatego bardziej odpowiada. No i \u0142atwo si\u0119 instaluje. <\/p>\n<p><\/p>\n<h2 id=\"anchorasynchronousanchorkak-byt-snbspasinhronnymi-operaciyami-i-materializovannymi-predstavleniyami\"><noindex><a rel=\"nofollow\" name=\"asynchronous\"><\/a><\/noindex>Co zrobi\u0107 z&nbsp;operacjami asynchronicznymi i materializowanymi widokami?<\/h2>\n<p><\/p>\n<blockquote><p>Jest pewien problem, poniewa\u017c operacje z silnikiem replace'uj\u0105cym s\u0105 asynchroniczne \u2014 najpierw zapisywane s\u0105 dane, potem nast\u0119puje ich zwin\u0119cie. Je\u015bli pod tabel\u0105 istnieje zmaterializowana tabela z r\u00f3\u017cnymi agregatami, to duplikaty zostan\u0105 w niej zapisane. I je\u015bli nie ma jakiej\u015b z\u0142o\u017conej logiki, to dane b\u0119d\u0105 zdublowane. Co mo\u017cna z tym zrobi\u0107?<\/p>\n<p>Jest oczywiste rozwi\u0105zanie \u2014 zrealizowa\u0107 trigger na okre\u015blon\u0105 klas\u0119 materializowanych widok\u00f3w przy asynchronicznej operacji zwijania. Czy istniej\u0105 jakie\u015b \u201esrebrne pociski\u201d, plany wprowadzenia podobnych funkcjonalno\u015bci?<\/p><\/blockquote>\n<p>Nale\u017cy zrozumie\u0107, jak dzia\u0142a deduplikacja. To, o czym teraz opowiem, nie odnosi si\u0119 bezpo\u015brednio do pytania, ale dla pewno\u015bci warto o tym wspomnie\u0107.<\/p>\n<p><\/p>\n<p>W przypadku wstawiania do replikowanej tabeli dochodzi do deduplikacji ca\u0142ych wstawionych blok\u00f3w. Je\u015bli ponownie wstawisz ten sam blok, zawieraj\u0105cy t\u0119 sam\u0105 liczb\u0119 tych samych wierszy w tej samej kolejno\u015bci, dane zostan\u0105 deduplikowane. Otrzymasz \"Ok\" w odpowiedzi na insert, ale w rzeczywisto\u015bci zostanie zapisana tylko jedna paczka danych, bez duplikacji.<\/p>\n<p><\/p>\n<p>Jest to potrzebne dla pewno\u015bci. Je\u015bli podczas wstawiania otrzyma\u0142e\u015b \"Ok\", oznacza to, \u017ce twoje dane zosta\u0142y wstawione. Je\u015bli otrzyma\u0142e\u015b b\u0142\u0105d od ClickHouse, oznacza to, \u017ce nie zosta\u0142y one wstawione i nale\u017cy powt\u00f3rzy\u0107 wstawienie. Je\u015bli jednak w trakcie wstawiania po\u0142\u0105czenie zosta\u0142o zerwane, nie wiesz, czy dane zosta\u0142y wstawione, czy nie. Jedyn\u0105 opcj\u0105 jest ponowne wstawienie. Je\u015bli dane by\u0142y rzeczywi\u015bcie wstawione i wstawiasz je ponownie, wyst\u0119puje deduplikacja blok\u00f3w. Jest to konieczne w celu unikni\u0119cia duplikat\u00f3w. <\/p>\n<p><\/p>\n<p>Wa\u017cne jest r\u00f3wnie\u017c, jak to dzia\u0142a dla materializowanych widok\u00f3w. Je\u015bli dane zosta\u0142y deduplikowane przy wstawianiu do g\u0142\u00f3wnej tabeli, nie trafi\u0105 r\u00f3wnie\u017c do materializowanego widoku.<\/p>\n<p><\/p>\n<p>Teraz w sprawie pytania. Masz bardziej skomplikowan\u0105 sytuacj\u0119, poniewa\u017c zapisujesz duplikaty pojedynczych wierszy. Oznacza to, \u017ce nie ca\u0142a paczka zosta\u0142a zdublowana, ale konkretne wiersze, kt\u00f3re s\u0105 nast\u0119pnie zaginane. Rzeczywi\u015bcie, dane zostan\u0105 zagi\u0119te w g\u0142\u00f3wnej tabeli, a do materializowanego widoku trafi\u0105 niezg\u0142adzone, i podczas po\u0142\u0105cze\u0144 nic nie wydarzy si\u0119 z materializowanymi widokami. Poniewa\u017c materializowany widok to nic innego jak wyzwalacz dla insert. Przy innych operacjach nie dzieje si\u0119 z nim nic dodatkowego.<\/p>\n<p><\/p>\n<p>I tutaj niestety nie mog\u0119 pocieszy\u0107. Nale\u017cy tylko szuka\u0107 konkretnego rozwi\u0105zania dla tej sytuacji. Na przyk\u0142ad, czy mo\u017cna r\u00f3wnie\u017c w materializowanym widoku przeprowadzi\u0107 jego zast\u0105pienie, a spos\u00f3b deduplikacji mo\u017ce r\u00f3wnie\u017c dzia\u0142a\u0107 w ten sam spos\u00f3b. Niestety, nie zawsze to si\u0119 udaje. Je\u015bli jest agreguj\u0105cy, to nie zadzia\u0142a. <\/p>\n<p><\/p>\n<p><strong>Kirill Shvakov:<\/strong> U&nbsp;nas te\u017c kostylestworzenie w&nbsp;sw\u00f3j czas by\u0142o naprawd\u0119 trudne. By\u0142 problem, \u017ce s\u0105 pokazy reklam i s\u0105 pewne dane, kt\u00f3re mo\u017cemy pokazywa\u0107 w&nbsp;czasie rzeczywistym \u2014 to s\u0105 po prostu pokazy. Rzadko si\u0119 powtarzaj\u0105, ale je\u015bli ju\u017c si\u0119 to stanie, to i tak je potem zredukujemy. I by\u0142y rzeczy, kt\u00f3rych nie mo\u017cna by\u0142o powiela\u0107 \u2014 klikni\u0119cia i wszystkie te historie. Ale chcia\u0142o si\u0119 je pokaza\u0107 praktycznie od razu.<\/p>\n<p><\/p>\n<p>Jak zosta\u0142y zrobione materializowane widoki? By\u0142y widoki, do kt\u00f3rych dane by\u0142y wpisywane bezpo\u015brednio&nbsp;\u2014 odbywa\u0142 si\u0119 zapis do&nbsp;surowych danych i pisano do&nbsp;widok\u00f3w. Tam w&nbsp;jakim\u015b momencie dane nie by\u0142y do ko\u0144ca poprawne, powiela\u0142y si\u0119 i tak dalej. I jest druga cz\u0119\u015b\u0107 tabeli, gdzie wygl\u0105daj\u0105 one dok\u0142adnie tak samo jak materializowane widoki, to znaczy pod wzgl\u0119dem struktury s\u0105 absolutnie identyczne. Co pewien czas przeliczamy dane, doszczelamy dane bez&nbsp;duplikat\u00f3w, wpisujemy do tych tabel. <\/p>\n<p><\/p>\n<p>Chodzili\u015bmy przez API \u2014 w&nbsp;ClickHouse r\u0119cznie to nie zadzia\u0142a. I API patrzy: kiedy mam dat\u0119 ostatniego dodania do&nbsp;tabeli, gdzie gwarantowane s\u0105 ju\u017c poprawne dane, policzone, to wykonuje zapytanie do&nbsp;jednej tabeli i do&nbsp;drugiej tabeli. Z&nbsp;jednej wybiera dane do&nbsp;okre\u015blonego czasu, a z&nbsp;drugiej dobiera to, co jeszcze nie zosta\u0142o policzone. I to dzia\u0142a, ale nie za pomoc\u0105 jednego ClickHouse.<\/p>\n<p><\/p>\n<p>Je\u015bli macie jakie\u015b API&nbsp;\u2014 dla&nbsp;analityk\u00f3w, dla&nbsp;u\u017cytkownik\u00f3w \u2014 to w&nbsp;zasadzie to jest opcja. Zawsze przeliczacie, zawsze ponownie obliczacie. Mo\u017cna to robi\u0107 raz dziennie lub w&nbsp;jakim\u015b innym czasie. Sami wybieracie zakres, kt\u00f3rego nie potrzebujecie i kt\u00f3ry nie jest krytyczny.<\/p>\n<p><\/p>\n<h2 id=\"anchordashboardanchorv-clickhouse-mnogo-logov-kak-ya-mogu-videt-vsyo-chto-proishodit-s-serverom-vnbspmomente\"><noindex><a rel=\"nofollow\" name=\"dashboard\"><\/a><\/noindex>W ClickHouse jest wiele log\u00f3w. Jak mog\u0119 zobaczy\u0107 wszystko, co si\u0119 dzieje z serwerem w&nbsp;tym momencie?<\/h2>\n<p><\/p>\n<blockquote><p>W ClickHouse jest bardzo du\u017ca liczba r\u00f3\u017cnych log\u00f3w i ta liczba ro\u015bnie. W&nbsp;nowych wersjach niekt\u00f3re z&nbsp;nich s\u0105 wr\u0119cz domy\u015blnie w\u0142\u0105czone, w&nbsp;starych wersjach trzeba je w\u0142\u0105cza\u0107 przy&nbsp;aktualizacji. Niemniej jednak, ich jest coraz wi\u0119cej. Chcia\u0142bym w&nbsp;ko\u0144cu widzie\u0107, co aktualnie dzieje si\u0119 z moim serwerem, mo\u017ce na jakim\u015b podsumowuj\u0105cym dashboardzie. <\/p>\n<p>Czy nie macie w&nbsp;zespole ClickHouse lub w&nbsp;zespo\u0142ach swoich znajomych, kt\u00f3rzy wspieraj\u0105 pewn\u0105 funkcjonalno\u015b\u0107 gotowych pulpit\u00f3w, kt\u00f3re wy\u015bwietlaj\u0105 te logi w&nbsp;formie gotowego produktu? W&nbsp;ko\u0144cu, po prostu patrze\u0107 na logi w&nbsp;ClickHouse \u2014 to \u015bwietne. Ale bardzo fajnie by\u0142oby, gdyby by\u0142o to ju\u017c przygotowane w&nbsp;postaci pulpitu. Sprawi\u0142oby mi to rado\u015b\u0107. <\/p><\/blockquote>\n<p>Pulpity s\u0105, ale nie s\u0105 ustandaryzowane. W&nbsp;naszej firmie oko\u0142o 60&nbsp;zespo\u0142\u00f3w korzysta z ClickHouse, a najdziwniejsze jest to, \u017ce wiele z&nbsp;nich ma pulpity, kt\u00f3re sami stworzyli i s\u0105 one troch\u0119 r\u00f3\u017cne. Niekt\u00f3re zespo\u0142y u\u017cywaj\u0105 wewn\u0119trznej instalacji \u201eYandex.Cloud\u201d. Tam s\u0105 pewne gotowe raporty, chocia\u017c nie wszystkie potrzebne. Inne zespo\u0142y maj\u0105 swoje w\u0142asne. <\/p>\n<p><\/p>\n<p>Moi koledzy z&nbsp;\u201eMetryki\u201d maj\u0105 sw\u00f3j pulpit w&nbsp;Grafana, a ja mam sw\u00f3j na ich klastrze. Patrz\u0119 tam na takie rzeczy jak hit cache. Jeszcze trudniejsze jest to, \u017ce u\u017cywamy r\u00f3\u017cnych narz\u0119dzi. M\u00f3j pulpit stworzy\u0142em na bardzo starym narz\u0119dziu, kt\u00f3re nazywa si\u0119 Graphite-web. Jest on zupe\u0142nie nieestetyczny. I tak korzystam z niego do&nbsp;tej pory, cho\u0107 Grafana prawdopodobnie by\u0142aby wygodniejsza i \u0142adniejsza. <\/p>\n<p><\/p>\n<p>Podstawowe rzeczy w&nbsp;pulpitach s\u0105 takie same. To metryki systemowe dotycz\u0105ce klastra: CPU, pami\u0119\u0107, dysk, sie\u0107. Inne to liczba jednoczesnych zapyta\u0144, liczba jednoczesnych scal\u0144, liczba zapyta\u0144 na sekund\u0119, maksymalna liczba kawa\u0142k\u00f3w dla partycji tabel MergTree, op\u00f3\u017anienie replikacji, rozmiar kolejki replikacji, liczba wstawionych wierszy na sekund\u0119, liczba wstawionych blok\u00f3w na sekund\u0119. To wszystko pochodzi nie z&nbsp;log\u00f3w, a z&nbsp;metryk.<\/p>\n<p><\/p>\n<p><strong>W\u0142adimir Ko\u0142obaew:<\/strong> Aleksiej, chcia\u0142bym troch\u0119 skorygowa\u0107. Jest Grafana. Grafana ma \u017ar\u00f3d\u0142o danych, kt\u00f3rym jest ClickHouse. To znaczy, \u017ce mog\u0119 z&nbsp;Grafana wykonywa\u0107 zapytania bezpo\u015brednio do&nbsp;ClickHouse. W&nbsp;ClickHouse jest tabela z&nbsp;logami, kt\u00f3ra jest taka sama dla wszystkich. Chc\u0119, aby w wyniku w&nbsp;Grafana odwo\u0142ywa\u0107 si\u0119 do&nbsp;tej tabeli log\u00f3w i widzie\u0107 te zapytania, kt\u00f3re wysy\u0142a m\u00f3j serwer. Fajnie by\u0142oby mie\u0107 taki pulpit.<\/p>\n<p><\/p>\n<p>Sama go posk\u0142ada\u0142em. Ale pojawia si\u0119 pytanie \u2014 je\u015bli wszystko jest ustandaryzowane, a Grafana jest u\u017cywana przez wszystkich, dlaczego w&nbsp;\u201eYandexie\u201d nie ma takiego oficjalnego pulpitu?<\/p>\n<p><\/p>\n<p><strong>Kirill Shvakov:<\/strong> W rzeczywisto\u015bci datasource, kt\u00f3ry \u0142\u0105czy si\u0119 z ClickHouse, obecnie wspiera Altinity. Chc\u0119 tylko wskaza\u0107 kierunek, gdzie szuka\u0107 i kogo popchn\u0105\u0107. Mo\u017cna ich o to zapyta\u0107, poniewa\u017c \u201eYandex\u201d w ko\u0144cu tworzy ClickHouse, a nie histori\u0119 wok\u00f3\u0142 niego. Altinity to g\u0142\u00f3wna firma, kt\u00f3ra obecnie promuje ClickHouse. Nie zrezygnuj\u0105 z niego, a b\u0119d\u0105 go wspiera\u0107. Poniewa\u017c zasadniczo, aby za\u0142adowa\u0107 pulpit nawigacyjny na stronie Grafana, wystarczy si\u0119 zarejestrowa\u0107 i go przes\u0142a\u0107 \u2014 nie ma wi\u0119kszych problem\u00f3w. <\/p>\n<p><\/p>\n<p><strong>Alieksiej Mi\u0142owidow:<\/strong> W ci\u0105gu ostatniego roku do ClickHouse dodano wiele mo\u017cliwo\u015bci profilowania zapyta\u0144. S\u0105 metryki dla ka\u017cdego zapytania dotycz\u0105ce wykorzystania zasob\u00f3w. Ostatnio dodano jeszcze bardziej niskopoziomowy profiler zapyta\u0144, aby zobaczy\u0107, gdzie zapytanie sp\u0119dza ka\u017cd\u0105 milisekund\u0119. Ale \u017ceby skorzysta\u0107 z tej funkcjonalno\u015bci, musz\u0119 otworzy\u0107 konsolowego klienta i wpisa\u0107 zapytanie, kt\u00f3re ci\u0105gle zapominam. Gdzie\u015b je zapisa\u0142em i ci\u0105gle zapominam, gdzie dok\u0142adnie. <\/p>\n<p><\/p>\n<p>Chcia\u0142bym, aby istnia\u0142 narz\u0119dzie, w kt\u00f3rym po prostu napisano by \u2014 oto twoje ci\u0119\u017ckie zapytania, pogrupowane wed\u0142ug klas zapyta\u0144. Klikam na jakie\u015b, a powiedziano by mi, \u017ce jest ci\u0119\u017ckie z tego powodu. Obecnie takie rozwi\u0105zanie nie istnieje. I rzeczywi\u015bcie jest do\u015b\u0107 dziwne, \u017ce gdy ludzie mnie pytaj\u0105: \u201ePowiedzcie, czy s\u0105 jakie\u015b gotowe pulpity nawigacyjne dla Grafana?\u201d m\u00f3wi\u0119: \u201eWejd\u017acie na stron\u0119 Grafana, tam jest spo\u0142eczno\u015b\u0107 \u201ePulpity nawigacyjne\u201d, a tam jest pulpit od Dymka, jest pulpit od Kostyana. Co to jest, nie wiem, sam nie korzysta\u0142em\u201d.<\/p>\n<p><\/p>\n<h2 id=\"anchorzenanchorkak-vozdeystvovat-na-merdzhi-chtoby-server-ne-padal-vnbspoom\"><noindex><a rel=\"nofollow\" name=\"zen\"><\/a><\/noindex>Jak wp\u0142ywa\u0107 na \u0142\u0105czenia, aby serwer nie pada\u0142 w OOM?<\/h2>\n<p><\/p>\n<blockquote><p>Mam tabel\u0119, kt\u00f3ra ma tylko jedn\u0105 partycj\u0119, to ReplacingMergeTree. Pisz\u0119 do niej dane przez cztery lata. Musia\u0142em zrobi\u0107 w niej alter i usun\u0105\u0107 pewne dane.<\/p>\n<p>Zrobi\u0142em to i w trakcie przetwarzania tego zapytania ca\u0142a pami\u0119\u0107 na wszystkich serwerach klastra zosta\u0142a zu\u017cyta, a wszystkie serwery klastra jednog\u0142o\u015bnie przesz\u0142y w OOM. Potem znowu wsta\u0142y, zacz\u0119\u0142y wykonywa\u0107 \u0142\u0105czenie tej samej operacji, tego bloku danych, i ponownie pad\u0142y w OOM. Potem znowu wsta\u0142y i znowu pad\u0142y. I ta sytuacja nie ust\u0119powa\u0142a.<\/p>\n<p>Okaza\u0142o si\u0119, \u017ce to tak naprawd\u0119 by\u0142 b\u0142\u0105d, kt\u00f3ry ch\u0142opaki naprawili. To bardzo mi\u0142e, dzi\u0119kuj\u0119 bardzo. Ale wra\u017cenie pozosta\u0142o. I teraz, gdy my\u015bl\u0119 o tym, co zrobi\u0107 z pewnym mergem w tabeli, pojawia si\u0119 pytanie \u2014 dlaczego nie mog\u0119 jako\u015b wp\u0142ywa\u0107 na te merge'e? Na przyk\u0142ad, ograniczy\u0107 je pod wzgl\u0119dem wymaganego RAM-u, albo w og\u00f3le pod wzgl\u0119dem ich liczby, kt\u00f3re b\u0119d\u0105 przetwarza\u0107 t\u0119 konkretn\u0105 tabel\u0119.<\/p>\n<p>Mam tabel\u0119, kt\u00f3ra nazywa si\u0119 \u201eMetryki\u201d, przetw\u00f3rz j\u0105 prosz\u0119 w dwa w\u0105tki. Nie tw\u00f3rz dziesi\u0119ciu ani pi\u0119ciu merge'y r\u00f3wnocze\u015bnie, zr\u00f3b to w dwa. My\u015bl\u0119, \u017ce w dwa mam wystarczaj\u0105co pami\u0119ci, a do przetwarzania dziesi\u0119ciu mo\u017ce by\u0107 niewystarczaj\u0105co. Dlaczego pozosta\u0142 strach? Poniewa\u017c tabela ro\u015bnie, i pewnego dnia natkn\u0119 si\u0119 na sytuacj\u0119, \u017ce ju\u017c nie z powodu b\u0142\u0119du, ale z powodu tego, \u017ce dane b\u0119d\u0105 si\u0119 zmienia\u0107 w tak du\u017cej ilo\u015bci, \u017ce po prostu pami\u0119ci na serwerze nie wystarczy. I wtedy serwer padnie z powodu OOM przy mergach. Przy czym mutacj\u0119 mog\u0119 cofn\u0105\u0107, a merge'y ju\u017c nie.<\/p><\/blockquote>\n<p>Wiesz, przy merge'ach serwer nie padnie z powodu OOM, poniewa\u017c podczas merge'u u\u017cywane jest tylko tyle pami\u0119ci, ile potrzeba na jeden ma\u0142y zakres danych. Tak \u017ce wszystko b\u0119dzie w porz\u0105dku niezale\u017cnie od obj\u0119to\u015bci danych.<\/p>\n<p><\/p>\n<p><strong>W\u0142adimir Ko\u0142obaew:<\/strong> Dobrze. Chodzi o to, \u017ce po tym, jak dokonano naprawy b\u0142\u0119du, pobra\u0142em now\u0105 wersj\u0119 i na innej, mniejszej tabeli, gdzie jest wiele partycji, wykona\u0142em podobn\u0105 operacj\u0119. W trakcie merge'u na serwerze spali\u0142o oko\u0142o 100 GB pami\u0119ci RAM. Mia\u0142em 150 zaj\u0119tej, 100 wykorzystane, i zosta\u0142o okno na 50 GB, wi\u0119c nie wpad\u0142em w OOM.<\/p>\n<p><\/p>\n<p>Co w tej chwili chroni mnie przed wpadni\u0119ciem w OOM, je\u015bli naprawd\u0119 zu\u017cywa po 100 GB pami\u0119ci RAM? Co robi\u0107 w sytuacji, gdy nagle pami\u0119\u0107 RAM podczas merge'y si\u0119 sko\u0144czy?<\/p>\n<p><\/p>\n<p><strong>Alieksiej Mi\u0142owidow:<\/strong> Istnieje taki problem, \u017ce wydajno\u015b\u0107 pami\u0119ci operacyjnej podczas&nbsp;merge&#039;\u00f3w nie jest ograniczona. A problem drugi jest taki, \u017ce je\u015bli jaki\u015b merge zosta\u0142 zaplanowany, to trzeba go wykona\u0107, poniewa\u017c jest zapisany w&nbsp;logu replikacji. Log replikacji to te dzia\u0142ania, kt\u00f3re s\u0105 potrzebne do przywr\u00f3cenia replikacji do&nbsp;sp\u00f3jnego stanu. Je\u015bli nie wykona si\u0119 r\u0119cznych operacji, kt\u00f3re cofn\u0105 ten log replikacji, merge b\u0119dzie musia\u0142 zosta\u0107 zrealizowany, tak czy inaczej.<\/p>\n<p><\/p>\n<p>Oczywi\u015bcie, by\u0142oby nieco korzystne mie\u0107 ograniczenie pami\u0119ci operacyjnej, kt\u00f3re 'na wszelki wypadek' chroni przed&nbsp;OOM. Nie pomo\u017ce to w zrealizowaniu merge&#039;u, on zacznie si\u0119 ponownie, dotrze do&nbsp;jakiego\u015b progu, zg\u0142osi wyj\u0105tek, a potem zn\u00f3w si\u0119 zacznie - nic dobrego z&nbsp;tego nie wyjdzie. Ale w&nbsp;zasadzie wprowadzenie takiego ograniczenia by\u0142oby przydatne.<\/p>\n<p><\/p>\n<h2 id=\"anchorgoanchorkak-budet-proishodit-razrabotka-golang-drayvera-dlya-clickhouse\"><noindex><a rel=\"nofollow\" name=\"go\"><\/a><\/noindex>Jak b\u0119dzie przebiega\u0107 rozw\u00f3j sterownika Golang dla ClickHouse?<\/h2>\n<p><\/p>\n<blockquote><p>Sterownik Golang, kt\u00f3ry napisa\u0142 Kirill Shvakov, teraz oficjalnie wydaje si\u0119 by\u0107 wspierany przez zesp\u00f3\u0142 ClickHouse. On <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/ClickHouse\/clickhouse-go\">jest w repozytorium ClickHouse<\/a><\/noindex>, teraz jest du\u017cy i prawdziwy.<\/p>\n<p>Ma\u0142a uwaga. Jest wspania\u0142e i przez wszystkich uwielbiane repozytorium normatywnych form niesko\u0144czonego porz\u0105dku \u2013 to Vertica. Maj\u0105 r\u00f3wnie\u017c sw\u00f3j oficjalny sterownik Python, kt\u00f3ry jest wspierany przez programist\u00f3w Vertica. I wielokrotnie zdarza\u0142o si\u0119, \u017ce wersje repozytorium i wersje sterownika znacznie si\u0119 rozje\u017cd\u017ca\u0142y, a sterownik w pewnym momencie przestawa\u0142 dzia\u0142a\u0107. I drugi punkt. Wsparcie dla tego oficjalnego sterownika, wydaje mi si\u0119, jest prowadzone w systemie \u201enipple\u201d \u2013 piszesz im zg\u0142oszenie, a ono wisi wiecznie.<\/p>\n<p>Mam dwa pytania. Aktualnie sterownik Golang Kirilla to niemal domy\u015blny spos\u00f3b komunikacji z ClickHouse z Golang. Chyba \u017ce kto\u015b wci\u0105\u017c komunikuje poprzez interfejs http, bo tak mu pasuje. Jak b\u0119dzie przebiega\u0142 rozw\u00f3j tego sterownika? Czy b\u0119dzie zsynchronizowany z jakimi\u015b breaking changes w samym repozytorium? I jak wygl\u0105da proces rozpatrywania zg\u0142osze\u0144? <\/p><\/blockquote>\n<p><strong>Kirill Shvakov:<\/strong> Pierwsze - jak to wszystko dzia\u0142a biurokratycznie. Ten aspekt nie by\u0142 omawiany, wi\u0119c nie ma na to odpowiedzi.<\/p>\n<p><\/p>\n<p>Aby odpowiedzie\u0107 na&nbsp;pytanie dotycz\u0105ce&nbsp;issue, potrzebna jest kr\u00f3tka historia dotycz\u0105ca drivera. Pracowa\u0142em w&nbsp;firmie, w&nbsp;kt\u00f3rej by\u0142o wiele danych. By\u0142 to system reklamowy w&nbsp;kt\u00f3rym rejestrowano ogromn\u0105 ilo\u015b\u0107 zdarze\u0144, kt\u00f3re trzeba by\u0142o gdzie\u015b przechowywa\u0107. I w&nbsp;pewnym momencie pojawi\u0142 si\u0119 ClickHouse. Wprowadzili\u015bmy tam dane, i przez pierwszy czas wszystko dzia\u0142a\u0142o dobrze, a potem ClickHouse si\u0119 zatrzyma\u0142. W\u00f3wczas zdecydowali\u015bmy, \u017ce to nam nie jest potrzebne. <\/p>\n<p><\/p>\n<p>Rok p\u00f3\u017aniej wr\u00f3cili\u015bmy do pomys\u0142u u\u017cywania ClickHouse, i musieli\u015bmy jako\u015b wprowadza\u0107 dane. Wprowadzenie by\u0142o takie - sprz\u0119t by\u0142 bardzo s\u0142aby, zasoby by\u0142y ograniczone. Ale zawsze pracowali\u015bmy w&nbsp;taki spos\u00f3b, wi\u0119c spojrzeli\u015bmy w stron\u0119 protoko\u0142u natywnego.<\/p>\n<p><\/p>\n<p>Poniewa\u017c pracowali\u015bmy w&nbsp;Go, by\u0142o jasne, \u017ce potrzebny jest driver na Go. Pracowa\u0142em nad nim praktycznie w&nbsp;pe\u0142nym wymiarze godzin - to by\u0142o moje zadanie. Do&nbsp;jakiego\u015b momentu uda\u0142o nam si\u0119 go doprowadzi\u0107 do ko\u0144ca, i w zasadzie nikt nie przypuszcza\u0142, \u017ce kto\u015b poza nami b\u0119dzie go u\u017cywa\u0107. Potem przyszed\u0142 CloudFlare z&nbsp;takim samym problemem, i przez jaki\u015b czas wsp\u00f3\u0142pracowali\u015bmy z&nbsp;nimi bardzo r\u00f3wno, poniewa\u017c mieli te same zadania. Zreszt\u0105 robili\u015bmy to zar\u00f3wno w ClickHouse, jak i w driverze. <\/p>\n<p><\/p>\n<p>W pewnym momencie po prostu przesta\u0142em si\u0119 tym zajmowa\u0107, poniewa\u017c moja aktywno\u015b\u0107 zwi\u0105zana z ClickHouse i z prac\u0105 troch\u0119 si\u0119 zmieni\u0142a. Dlatego nie zamykam zg\u0142osze\u0144. Okazjonalnie do repozytorium pisz\u0105 ludzie, kt\u00f3rym co\u015b jest potrzebne. Wtedy patrz\u0119 na pull request i czasami sam co\u015b poprawiam, ale to si\u0119 zdarza rzadko.<\/p>\n<p><\/p>\n<p>Chc\u0119 wr\u00f3ci\u0107 do sterownika. Kilka lat temu, kiedy to wszystko si\u0119 zaczyna\u0142o, ClickHouse r\u00f3wnie\u017c by\u0142 inny i mia\u0142 inne mo\u017cliwo\u015bci. Teraz jest ju\u017c zrozumienie, jak przerobi\u0107 sterownik, aby by\u0142o dobrze. Je\u015bli to si\u0119 wydarzy, wersja 2 z pewno\u015bci\u0105 b\u0119dzie niekompatybilna z powodu nagromadzonych problem\u00f3w. <\/p>\n<p><\/p>\n<p>Nie wiem, jak to zorganizowa\u0107. Sam mam niewiele czasu. Je\u015bli kto\u015b zdecyduje si\u0119 na poprawianie sterownika, mog\u0119 im pomaga\u0107 i m\u00f3wi\u0107, co robi\u0107. Ale aktywne uczestnictwo \u201eYandeksi\u201d w rozwoju projektu jak na razie nie by\u0142o omawiane. <\/p>\n<p><\/p>\n<p><strong>Alieksiej Mi\u0142owidow:<\/strong> Tak naprawd\u0119 nie ma jeszcze \u017cadnej biurokracji dotycz\u0105cej tych sterownik\u00f3w. Jedyn\u0105 rzecz\u0105 jest to, \u017ce zosta\u0142y one przeniesione do oficjalnej organizacji, wi\u0119c ten sterownik jest uznawany za oficjalne rozwi\u0105zanie domy\u015blne dla Go. Istniej\u0105 inne sterowniki, ale s\u0105 one oddzielne. <\/p>\n<p><\/p>\n<p>Nie mamy wewn\u0119trznych prac nad tymi sterownikami. Pytanie brzmi, czy b\u0119dziemy w stanie zatrudni\u0107 osob\u0119, nie tylko do tego konkretnego sterownika, ale tak\u017ce do rozwoju wszystkich sterownik\u00f3w spo\u0142eczno\u015bciowych, czy te\u017c znajdziemy kogo\u015b z zewn\u0105trz. <\/p>\n<p><\/p>\n<h2 id=\"anchorlazy-loadanchorvneshniy-slovar-ne-podnimaetsya-posle-perezagruzki-snbspvklyuchennoy-nastroykoy-lazy_load-chto-delat\"><noindex><a rel=\"nofollow\" name=\"lazy-load\"><\/a><\/noindex>Zewn\u0119trzny s\u0142ownik nie \u0142aduje si\u0119 po restarcie z w\u0142\u0105czon\u0105 opcj\u0105 lazy_load. Co robi\u0107?<\/h2>\n<p><\/p>\n<blockquote><p>Mamy w\u0142\u0105czon\u0105 opcj\u0119 lazy_load, i po restarcie serwera s\u0142ownik nie \u0142aduje si\u0119 sam. \u0141aduje si\u0119 tylko wtedy, gdy u\u017cytkownik zwr\u00f3ci si\u0119 do tego s\u0142ownika. A przy pierwszym zapytaniu wy\u015bwietla b\u0142\u0105d. Czy mo\u017cemy jako\u015b automatycznie za pomoc\u0105 ClickHouse \u0142adowa\u0107 s\u0142owniki, czy musimy zawsze kontrolowa\u0107 ich gotowo\u015b\u0107, aby u\u017cytkownicy nie dostawali b\u0142\u0119d\u00f3w?<\/p>\n<p>Mo\u017cliwe, \u017ce mamy star\u0105 wersj\u0119 ClickHouse, dlatego s\u0142ownik nie by\u0142 automatycznie \u0142adowany. Czy to mo\u017cliwe?<\/p><\/blockquote>\n<p>Po pierwsze, s\u0142owniki mo\u017cna wymusi\u0107 za pomoc\u0105 zapytania. <strong>system reload dictionaries<\/strong>Po drugie, je\u015bli chodzi o b\u0142\u0105d \u2014 je\u017celi s\u0142ownik zosta\u0142 ju\u017c za\u0142adowany, wtedy zapytania b\u0119d\u0105 dzia\u0142a\u0107 na tych danych, kt\u00f3re zosta\u0142y za\u0142adowane. Je\u015bli s\u0142ownik nie zosta\u0142 jeszcze za\u0142adowany, to zostanie za\u0142adowany w momencie zapytania.<\/p>\n<p><\/p>\n<p>Dla ci\u0119\u017ckich s\u0142ownik\u00f3w to nie jest zbyt wygodne. Na przyk\u0142ad, trzeba pobra\u0107 milion wierszy z MySQL. Kto\u015b wykonuje prosty select, ale ten select b\u0119dzie czeka\u0142 na te w\u0142a\u015bnie milion wierszy. Istniej\u0105 tutaj dwa rozwi\u0105zania. Pierwsze \u2014 wy\u0142\u0105czy\u0107 lazy_load. Drugie \u2014 kiedy serwer jest uruchamiany, przed obci\u0105\u017ceniem go, nale\u017cy wykona\u0107 <strong>system reload dictionary<\/strong> lub po prostu wykona\u0107 zapytanie, kt\u00f3re korzysta ze s\u0142ownika. W\u00f3wczas s\u0142ownik zostanie za\u0142adowany. Nale\u017cy samodzielnie kontrolowa\u0107 dost\u0119pno\u015b\u0107 s\u0142ownik\u00f3w przy w\u0142\u0105czonym ustawieniu lazy_load, poniewa\u017c ClickHouse nie \u0142aduje ich automatycznie.<\/p>\n<p><\/p>\n<p>Na ostatnie pytanie odpowied\u017a brzmi \u2014 albo wersja jest stara, albo trzeba debugowa\u0107. <\/p>\n<p><\/p>\n<h2 id=\"anchorreload-dictionariesanchorkak-byt-snbsptem-chto-system-reload-dictionaries-ne-podgruzhaet-ni-odin-iznbspmnozhestva-slovarey-esli-hotya-by-odin-iznbspnih-padaet-snbsposhibkoy\"><noindex><a rel=\"nofollow\" name=\"reload-dictionaries\"><\/a><\/noindex>Co zrobi\u0107, gdy system reload dictionaries nie \u0142aduje \u017cadnego z&nbsp;licznych s\u0142ownik\u00f3w, je\u015bli cho\u0107 jeden z&nbsp;nich ko\u0144czy si\u0119 b\u0142\u0119dem?<\/h2>\n<p><\/p>\n<blockquote><p>Jest jeszcze pytanie dotycz\u0105ce system reload dictionaries. Mamy dwa s\u0142owniki \u2014 jeden si\u0119 nie \u0142adowa\u0142, drugi si\u0119 \u0142adowa\u0142. W takim przypadku system reload dictionaries nie \u0142aduje \u017cadnego s\u0142ownika i trzeba punktowo \u0142adowa\u0107 konkretny po jego nazwie przy pomocy system reload dictionary. Czy to te\u017c ma zwi\u0105zek z wersj\u0105 ClickHouse?<\/p><\/blockquote>\n<p>Chc\u0119 was pocieszy\u0107. To zachowanie si\u0119 zmienia\u0142o. Oznacza to, \u017ce je\u015bli zaktualizujesz ClickHouse, to r\u00f3wnie\u017c si\u0119 to zmieni. Je\u015bli nie odpowiada ci obecne zachowanie <strong>system reload dictionaries<\/strong>, zaktualizuj si\u0119, i miejmy nadziej\u0119, \u017ce zmieni si\u0119 na lepsze.<\/p>\n<p><\/p>\n<h2 id=\"anchorconnectionanchorest-li-sposob-konfigurirovat-rekvizity-vnbspkonfige-clickhouse-no-ne-svetit-ih-prinbsposhibkah\"><noindex><a rel=\"nofollow\" name=\"connection\"><\/a><\/noindex>Czy jest spos\u00f3b na skonfigurowanie danych w konfiguracji ClickHouse, \u017ceby nie ujawnia\u0107 ich w przypadku b\u0142\u0119d\u00f3w?<\/h2>\n<p><\/p>\n<blockquote><p>Kolejne pytanie dotyczy b\u0142\u0119d\u00f3w zwi\u0105zanych ze s\u0142ownikiem, a konkretnie danymi uwierzytelniaj\u0105cymi. Zapisa\u0142y\u015bmy dane uwierzytelniaj\u0105ce po\u0142\u0105czenia w konfiguracji ClickHouse do s\u0142ownika, i przy wyst\u0105pieniu b\u0142\u0119du otrzymujemy te dane uwierzytelniaj\u0105ce oraz has\u0142o w odpowiedzi. <\/p>\n<p>Rozwi\u0105zali\u015bmy ten b\u0142\u0105d poprzez przeniesienie danych uwierzytelniaj\u0105cych do konfiguracji sterownika ODBC. Czy istnieje jaki\u015b spos\u00f3b, aby skonfigurowa\u0107 dane uwierzytelniaj\u0105ce w konfiguracji ClickHouse, ale nie ujawnia\u0107 tych danych przy b\u0142\u0119dach?<\/p><\/blockquote>\n<p>W tym przypadku rozwi\u0105zaniem jest wskazanie tych danych w pliku odbc.ini, a w samym ClickHouse wskazywanie tylko nazwy \u017ar\u00f3d\u0142a danych ODBC. Dla innych \u017ar\u00f3de\u0142 s\u0142ownik\u00f3w tego nie b\u0119dzie \u2014 ani dla s\u0142ownika z MySQL, ani dla innych, nie powiniene\u015b widzie\u0107 has\u0142a w komunikacie o b\u0142\u0119dzie. R\u00f3wnie\u017c sprawdz\u0119 dla ODBC \u2014 je\u015bli co\u015b takiego istnieje, nale\u017cy to po prostu usun\u0105\u0107.<\/p>\n<p><\/p>\n<h2 id=\"anchorzoom-backgroundsanchorbonus-fony-dlya-zuma-snbspposidelok\"><noindex><a rel=\"nofollow\" name=\"zoom-backgrounds\"><\/a><\/noindex>Bonus: t\u0142a na Zoom z naszych spotka\u0144<\/h2>\n<p><\/p>\n<p>Klikaj\u0105c na&nbsp;obrazek, dla&nbsp;najbardziej wytrwa\u0142ych czytelnik\u00f3w otworz\u0105 si\u0119 bonusowe t\u0142a z&nbsp;spotka\u0144. Gasimy po\u017car razem z&nbsp;maskotkami technologii Avito, rozmawiamy z&nbsp;kole\u017cankami z&nbsp;pokoju systemowego lub starej szko\u0142y komputerowego klubu i prowadzimy codzienne spotkania pod&nbsp;mostem w&nbsp;tle grafiti.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/amp.gs\/KvUr\"><img decoding=\"async\" alt=\"ClickHouse dla zaawansowanych u\u017cytkownik\u00f3w w pytaniach i odpowiedziach\" src=\"\/wp-content\/uploads\/2020\/05\/38b2ea076283285d934913c395863eb1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/avito\/blog\/500678\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u0430\u043f\u0440\u0435\u043b\u0435 \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u044b \u0410\u0432\u0438\u0442\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0438\u0441\u044c \u043d\u0430&nbsp;\u043e\u043d\u043b\u0430\u0439\u043d-\u043f\u043e\u0441\u0438\u0434\u0435\u043b\u043a\u0438 \u0441 \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c ClickHouse \u0410\u043b\u0435\u043a\u0441\u0435\u0435\u043c \u041c\u0438\u043b\u043e\u0432\u0438\u0434\u043e\u0432\u044b\u043c \u0438 \u041a\u0438\u0440\u0438\u043b\u043b\u043e\u043c \u0428\u0432\u0430\u043a\u043e\u0432\u044b\u043c, Golang-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c \u0438\u0437&nbsp;\u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Integros. \u041e\u0431\u0441\u0443\u0436\u0434\u0430\u043b\u0438, \u043a\u0430\u043a \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0431\u0430\u0437\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043a\u0430\u043a\u0438\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0443&nbsp;\u043d\u0430\u0441 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442. \u041f\u043e&nbsp;\u043c\u043e\u0442\u0438\u0432\u0430\u043c \u0432\u0441\u0442\u0440\u0435\u0447\u0438 \u043c\u044b \u0441\u043e\u0431\u0440\u0430\u043b\u0438 \u0441\u0442\u0430\u0442\u044c\u044e \u0441&nbsp;\u043e\u0442\u0432\u0435\u0442\u0430\u043c\u0438 \u044d\u043a\u0441\u043f\u0435\u0440\u0442\u043e\u0432 \u043d\u0430&nbsp;\u043d\u0430\u0448\u0438 \u0438 \u0437\u0440\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u043f\u0440\u043e&nbsp;\u0431\u044d\u043a\u0430\u043f\u044b, \u0440\u0435\u0448\u0430\u0440\u0434\u0438\u043d\u0433 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432\u043d\u0435\u0448\u043d\u0438\u0435 \u0441\u043b\u043e\u0432\u0430\u0440\u0438, Golang-\u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u0441\u0438\u0439 ClickHouse. \u041e\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":80776,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-80775","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412 \u0430\u043f\u0440\u0435\u043b\u0435 \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u044b \u0410\u0432\u0438\u0442\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u043e\u043d\u043b\u0430\u0439\u043d-\u043f\u043e\u0441\u0438\u0434\u0435\u043b\u043a\u0438 \u0441 \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c ClickHouse \u0410\u043b\u0435\u043a\u0441\u0435\u0435\u043c \u041c\u0438\u043b\u043e\u0432\u0438\u0434\u043e\u0432\u044b\u043c \u0438 \u041a\u0438\u0440\u0438\u043b\u043b\u043e\u043c \u0428\u0432\u0430\u043a\u043e\u0432\u044b\u043c, Golang-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c \u0438\u0437 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Integros.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/clickhouse-dlya-prodvinutyh-polzovatelej-v-voprosah-i-otvetah\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47ClickHouse \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u0432\u043e\u043f\u0440\u043e\u0441\u0430\u0445 \u0438 \u043e\u0442\u0432\u0435\u0442\u0430\u0445 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412 \u0430\u043f\u0440\u0435\u043b\u0435 \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u044b \u0410\u0432\u0438\u0442\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u043e\u043d\u043b\u0430\u0439\u043d-\u043f\u043e\u0441\u0438\u0434\u0435\u043b\u043a\u0438 \u0441 \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c ClickHouse \u0410\u043b\u0435\u043a\u0441\u0435\u0435\u043c \u041c\u0438\u043b\u043e\u0432\u0438\u0434\u043e\u0432\u044b\u043c \u0438 \u041a\u0438\u0440\u0438\u043b\u043b\u043e\u043c \u0428\u0432\u0430\u043a\u043e\u0432\u044b\u043c, Golang-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c \u0438\u0437 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Integros.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/clickhouse-dlya-prodvinutyh-polzovatelej-v-voprosah-i-otvetah\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-05-08T11:42:47+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-08T11:42:47+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47ClickHouse dla zaawansowanych u\u017cytkownik\u00f3w w pytaniach i odpowiedziach | ProHoster","description":"W kwietniu in\u017cynierowie Avito planowali wirtualne spotkania z g\u0142\u00f3wnym programist\u0105 ClickHouse, Aleksejem Milowidowem, oraz Kirillem Shwakovem, programist\u0105 Golang z firmy Integros.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/clickhouse-dlya-prodvinutyh-polzovatelej-v-voprosah-i-otvetah","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47ClickHouse \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u0432\u043e\u043f\u0440\u043e\u0441\u0430\u0445 \u0438 \u043e\u0442\u0432\u0435\u0442\u0430\u0445 | ProHoster","og:description":"\u0412 \u0430\u043f\u0440\u0435\u043b\u0435 \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u044b \u0410\u0432\u0438\u0442\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u043e\u043d\u043b\u0430\u0439\u043d-\u043f\u043e\u0441\u0438\u0434\u0435\u043b\u043a\u0438 \u0441 \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c ClickHouse \u0410\u043b\u0435\u043a\u0441\u0435\u0435\u043c \u041c\u0438\u043b\u043e\u0432\u0438\u0434\u043e\u0432\u044b\u043c \u0438 \u041a\u0438\u0440\u0438\u043b\u043b\u043e\u043c \u0428\u0432\u0430\u043a\u043e\u0432\u044b\u043c, Golang-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c \u0438\u0437 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Integros.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/clickhouse-dlya-prodvinutyh-polzovatelej-v-voprosah-i-otvetah","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-05-08T11:42:47+00:00","article:modified_time":"2020-05-08T11:42:47+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"80775","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 16:11:22","updated":"2022-09-28 05:48:13","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/80775","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=80775"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/80775\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/80776"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=80775"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=80775"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=80775"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}