Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Так як ClickHouse з'яўляецца спецыялізаванай сістэмай, пры ім выкарыстанні важна ўлічваць асаблівасці яго архітэктуры. У гэтым дакладзе Аляксей раскажа пра прыклады тыповых памылак пры выкарыстанні ClickHouse, якія могуць прывесці да неэфектыўнай працы. На прыкладах з практыкі будзе паказана, як выбар той ці іншай схемы апрацоўкі даных можа змяніць прадукцыйнасць на парадкі.

Ўсім прывітанне! Мяне клічуць Аляксей, я раблю ClickHouse.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Па-першае, адразу спяшаюся вас узрадаваць, я не буду сёння вам расказваць, што такое ClickHouse. Калі сапраўды, мне гэта надакучыла. Я кожны раз расказваю, што гэта. І, мусіць, усё ўжо ведаюць.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Замест гэтага я буду расказваць, якія ёсць магчымыя граблі, г. зн. як можна няправільна выкарыстоўваць ClickHouse. На самой справе баяцца не варта, таму што мы распрацоўваем ClickHouse як сістэму, якая простая, зручная, працуе са скрынкі. Паставіў і ўсё, ніякіх праблем.

Але ўсё ж такі трэба ўлічваць, што сістэма гэтая спецыялізаваная і можна лёгка натыкнуцца на незвычайны сцэнар выкарыстання, які выведзе гэтую сістэму з зоны камфорту.

Дык вось, якія ёсць граблі? У асноўным я буду казаць пра відавочныя рэчы. Усім усё відавочна, усе ўсё разумеюць і могуць парадавацца, што яны такія разумныя, а хто не разумеюць, тыя даведваюцца нешта новае.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Першы самы просты прыклад, які, на жаль, часта сустракаецца, гэта вялікая колькасць inserts з маленькімі batches, т. е. вялікая колькасць маленькіх inserts.

Калі разглядаць, як ClickHouse выконвае insert, тыя вы можаце за адзін запыт адправіць хоць струмень дадзеных на тэрабайт. Гэта не праблема.

І давайце паглядзім, якая тыповая будзе прадукцыйнасць. Напрыклад, табліца ў нас з даных Яндекс.Метрики. Хіты. 105 нейкіх слупкоў. 700 байт у несціснутым выглядзе. І будзем устаўляць па-добраму батчамі па адным мільёне радкоў.

Устаўляемы ў табліцу MergeTree, атрымліваецца паўмільёна радкоў у секунду. Выдатна. У рэплікаваную табліцу - крыху менш будзе, прыкладна 400 000 радкоў у секунду.

І калі ўключыць кворумную ўстаўку, тое атрымліваецца крыху менш, але ўсё роўна прыстойная прадукцыйнасць, 250 000 тэрмін у секунду. Кворумная ўстаўка - гэта недакументаваная магчымасць у ClickHouse *.

* па стане на 2020 год, ужо дакументавана.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Што будзе, калі рабіць кепска? Устаўляемы па адным радку ў табліцу MergeTree і атрымліваецца 59 радкоў у секунду. Гэта ў 10 000 разоў марудна. У ReplicatedMergeTree - 6 радкоў у секунду. А калі яшчэ кворум уключыцца, тое атрымліваецца 2 радкі ў секунду. Па-мойму, гэта нейкі апраметны адстой. Як можна так тармазіць? У мяне нават на футболцы напісана, што ClickHouse не павінен тармазіць. Але тым не менш бывае часам.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Насамрэч - гэта наш недахоп. Мы маглі б зрабіць так, каб усё працавала нармальна, але не зрабілі. І мы гэта не зрабілі, таму што для нашага сцэнара - гэта не патрабавалася. У нас і так былі батчы. Проста да нас на ўваход паступалі батчы, і ніякіх праблем. Устаўляемы і ўсё нармальна працуе. Але, вядома, магчымыя ўсякія сцэнары. Напрыклад, калі ў вас куча сервераў, на якіх дадзеныя генеруюцца. І яны ўстаўляюць дадзеныя не так часта, але ўсё роўна атрымліваюцца частыя ўстаўкі. І трэба гэтага неяк пазьбегнуць.

З тэхнічнага пункта гледжання іста ў тым, што калі вы робіце insert у ClickHouse, то дадзеныя не пападаюць ні ў які memtable. У нас нават не сапраўдны log structure MergeTree, а проста MergeTree, таму што няма ні log'а, ні memTable. Мы проста адразу запісваем дадзеныя ў файлавую сістэму, ужо раскладзеныя па слупках. І калі ў вас 100 слупкоў, то больш за 200 файлаў трэба будзе запісаць у асобную дырэкторыю. Усё гэта вельмі грувастка.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

І ўзнікае пытанне: "Як рабіць правільна?", калі такая сітуацыя, што трэба ўсё ж такі неяк запісваць дадзеныя ў ClickHouse.

Спосаб 1. Гэта самы просты спосаб. Выкарыстоўваць якую-небудзь размеркаваную чаргу. Напрыклад, Kafka. Проста вымаеце дадзеныя з Kafka, батчым раз у секунду. І ўсё будзе нармальна, вы запісваеце, усё нармальна працуе.

Недахопы ў тым, што Kafka гэта яшчэ адна грувасткая размеркаваная сістэма. Я яшчэ разумею, калі ў вас у кампаніі ўжо ёсць Kafka. Гэта добра, гэта зручна. Але калі яе няма, то варта тройчы падумаць перад тым, як цягнуць яшчэ адну размеркаваную сістэму сабе ў праект. І таму варта разгледзець альтэрнатывы.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Спосаб 2. Вось такая олдскульная альтэрнатыва і пры гэтым вельмі простая. Ёсць у вас нейкі сервер, які генеруюць вашыя логі. І ён проста запісвае вашыя логі ў файл. І раз у секунду, напрыклад, гэты файл пераназываем, адрываем новы. І асобны скрыпт альбо па cron, альбо нейкі daemon бярэ самы стары файл і запісвае ў ClickHouse. Калі запісваць логі раз у секунду, тое ўсё будзе выдатна.

Але недахоп гэтага спосабу ў тым, што калі ў вас сервер, на якім генеруюцца логі кудысьці знік, то і дадзеныя таксама знікнуць.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Спосаб 3. Ёсць яшчэ адзін цікавы спосаб, які ўвогуле без часовых файлаў. Напрыклад, у вас якая-небудзь рэкламная круцілка ці яшчэ які-небудзь цікавы daemon, які генеруе дадзеныя. І вы можаце назапашваць пачак дадзеных прама ў аператыўцы, у буферы. І калі праходзіць дастатковая колькасць часу, вы гэты буфер адкладаеце ў бок, ствараеце новы, а ў асобным струмені тое, што ўжо назапасілася, устаўляеце ў ClickHouse.

З іншага боку дадзеныя таксама пры kill-9 знікаюць. Калі ваш сервер упадзе, то вы гэтыя дадзеныя страціце. І яшчэ праблема ў тым, што калі вы не змаглі запісаць у базу, то ў вас дадзеныя будуць назапашвацца ў аператыўцы. І альбо скончыцца аператыўка, альбо проста страціце дадзеныя.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Спосаб 4. Яшчэ адзін цікавы спосаб. Ёсць у вас нейкі серверны працэс. І ён можа адпраўляць дадзеныя ў ClickHouse адразу, але рабіць гэта ў адным злучэнні. Напрыклад, адправіў http-запыт з transfer-encoding: chunked з insert'ам. І генеруе чанкі ўжо не занадта рэдка, можна кожны радок адпраўляць, хоць будзе overhead на фрэймінг гэтых дадзеных.

Але тым не менш у гэтым выпадку дадзеныя будуць адпраўленыя ў ClickHouse адразу. І ClickHouse сам іх будзе буферызаваць.

Але таксама ўзнікаюць праблемы. Цяпер вы страціце дадзеныя, у тым ліку, калі ваш працэс заб'ецца і, калі працэс ClickHouse заб'ецца, таму што гэта будзе незавершаны insert. А ў ClickHouse inserts атамарныя да некаторага названага парога ў памеры радкоў. У прынцыпе, гэта цікавы спосаб. Таксама можна выкарыстоўваць.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Спосаб 5. Вось яшчэ адзін цікавы спосаб. Гэта нейкі распрацаваны community - сервер для батчынгу дадзеных. Я на яго сам не глядзеў, таму нічога гарантаваць не магу. Зрэшты, і для самога ClickHouse ніякіх гарантый не прадастаўляецца. Гэта таксама open source, але з іншага боку, вы маглі абвыкнуць да некаторага стандарту якасці, які мы імкнемся забяспечваць. А вось для гэтай штукі - я не ведаю, зайдзіце на GitHub, паглядзіце код. Можа, нешта нармальнае напісалі.

* па стане на 2020 год, варта таксама дадаць у разгляд KittenHouse.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Спосаб 6. Яшчэ адзін спосаб - гэта выкарыстанне Buffer табліц. Добрыя якасці гэтага спосабу ў тым, што гэта вельмі проста пачаць выкарыстоўваць. Ствараеце Buffer табліцу і ўстаўляеце ў яе.

А недахоп у тым, што праблема вырашаецца не поўнасцю. Калі пры ў стаўцы тыпу MergeTree вы павінны групаваць дадзеныя па адным батчу ў секунду, то пры ў стаўцы ў buffer табліцу, вам трэба групаваць хаця б да некалькі тысяч у секунду. Калі будзе больш за 10 000 у секунду, то ўсё роўна будзе дрэнна. А калі ўстаўляць батчамі, то вы бачылі, што там атрымліваецца сотня тысяч радкоў за секунду. І гэта ўжо на дастаткова цяжкіх дадзеных.

І таксама buffer табліцы не маюць лога. І калі з вашым серверам нешта не так, то дадзеныя будуць страчаныя.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

І ў якасці бонуса нядаўна ў нас у ClickHouse з'явілася магчымасць забіраць дадзеныя з Kafka. Існуе рухавічок табліц - Kafka. Вы проста ствараеце. І на яго можна навесіць матэрыялізаваныя ўяўленні. У гэтым выпадку ён будзе сам вымаць дадзеныя з Kafka і ўстаўляць у патрэбныя вам табліцы.

І асабліва радуе ў гэтай магчымасці тое, што яе рабілі не мы. Гэта community фіча. І калі я кажу "community фича", я кажу без усялякай пагарды. Код мы чыталі, рэўю рабілі, павінна працаваць нармальна.

* па стане на 2020 год, з'явілася аналагічная падтрымка для RabbitMQ.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Што яшчэ можа быць нязручнага ці нечаканага пры ўстаўцы дадзеных? Калі вы робіце запыт insert values ​​і ў values ​​пішыце нейкія вылічаныя выразы. Напрыклад, now() - гэта таксама вылічае выраз. І ў гэтым выпадку ClickHouse змушаны на кожны радок запускаць інтэрпрэтатар гэтых выразаў, і прадукцыйнасць просядзе на парадкі. Лепш гэтага пазбягаць.

* на дадзены момант, праблема цалкам вырашана, рэгрэсіі прадукцыйнасці пры выкарыстанні выразаў у VALUES больш няма.

Іншы прыклад, калі могуць быць некаторыя праблемы, калі ў вас на адным батчы дадзеныя адносяцца да кучы партыцый. Па змаўчанні ў ClickHouse партыцыі па месяцах. І калі вы ўстаўляеце батч з мільёна радкоў, а там дадзеныя за некалькі гадоў, то ў вас тамака будзе некалькі дзясяткаў партыцый. І гэта эквівалентна таму, што будуць батчы ў некалькі дзясяткаў разоў меншага памеру, таму што ўсярэдзіне яны заўсёды спачатку разбіваюцца па партыцыях.

* нядаўна ў ClickHouse у эксперыментальным рэжыме дададзена падтрымка кампактнага фармату кавалкаў і кавалкаў у аператыўнай памяці з write-ahead log, што амаль цалкам вырашае праблему.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Зараз разгледзім другі від праблемы - гэта тыпізацыя дадзеных.

Тыпізацыі дадзеных бывае строгая, а бывае радковая. Радковая - гэта, калі вы проста ўзялі і абвясцілі, што ў вас усе палі тыпу string. Гэта адстой. Дык рабіць не трэба.

Давайце разбяромся, як рабіць правільна ў тых выпадках, калі хочацца сказаць, што нейкае поле ў нас, радок, і няхай ClickHouse сам разбярэцца, а я парыцца не буду. Але ўсё ж варта прыкладаць некаторыя намаганні.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Напрыклад, у нас ёсць IP-адрас. У адным выпадку мы яго захавалі як радок. Напрыклад, 192.168.1.1. А ў іншым выпадку - гэта будзе лік тыпу UInt32 *. 32 біт дастаткова для IPv4 адрасы.

Па-першае, як не дзіўна, дадзеныя сціснуцца прыкладна аднолькава. Тамака будзе розніца, вядома, але не такая вялікая. Так што па дыскаваму ўводу-вываду асаблівых праблем няма.

Але ёсць сур'ёзная розніца па працэсарным часе і па часе выканання запыту.

Палічым колькасць унікальных IP-адрасоў, калі яны захоўваюцца ў выглядзе лікаў. Атрымліваецца 137 мільёнаў радкоў за секунду. Калі тое ж самае ў выглядзе радкоў, то 37 мільёнаў радкоў у секунду. Я ня ведаю, чаму такое супадзеньне атрымалася. Я сам выконваў гэтыя запыты. Але тым не менш прыкладна ў 4 разы больш павольна.

А калі палічыць розніцу ў месцы на дыску, то розніца таксама ёсць. І розніца дзесьці на адну чвэрць, таму што ўнікальных IP-адрасоў дастаткова шмат. І калі б тут былі радкі з невялікай колькасцю розных значэнняў, то яны б спакойна сціснуліся па слоўніку прыкладна ў аднолькавы аб'ём.

І чатырохразовая розніца ў часе на дарозе не валяецца. Можа быць, вам, вядома, па дулях, але калі я бачу такую ​​розніцу, мне становіцца сумна.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Разгледзім розныя выпадкі.

1. Адзін выпадак, калі ў вас розных унікальных значэнняў няшмат. У гэтым выпадку выкарыстоўваем простую практыку, якую вы, мусіць, ведаеце і можаце выкарыстоўваць для любых СКБД. Гэта ўсё мае сэнс не толькі для ClickHouse. Проста запісваеце ў базу лікавыя ідэнтыфікатары. А канвертаваць у радкі і назад можна ўжо на баку вашага дадатку.

Вось, напрыклад, ёсць у вас рэгіён. І вы яго спрабуеце захаваць у выглядзе радка. І там напісана будзе: Масква і МА. І калі я бачу, што там напісана "Масква", то гэта яшчэ нічога, а калі і МА, то неяк зусім сумна становіцца. Гэта ж колькі байт.

Замест гэтага мы проста запісваем лік Ulnt32 і 250. У нас 250 у Яндэксе, а ў вас, можа быць, па-іншаму. На ўсякі выпадак скажу, што ў ClickHouse ёсць убудаваная магчымасць працы з геабаза. Вы проста запісваеце даведнік з рэгіёнамі, у тым ліку і іерархічны, т. е. тамака будзе і Масква, і МО, і ўсё, што вам трэба. І можна канвертаваць на ўзроўні запыту.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Другі варыянт прыкладна такі ж, але ўжо з падтрымкай усярэдзіне ClickHouse. Гэта тып дадзеных Enum. Вы проста ўнутры Enum прапісваеце ўсе патрэбныя вам значэнні. Напрыклад, тып прылады і тамака пішыце: дэсктоп, мабільны, планшэт, тэлевізар. Усяго 4 варыянты.

Недахоп у тым, што трэба перыядычна алтэрыць. Дадалі ўсяго толькі адзін варыянт. Які робіцца alter table. На самой справе alter table у ClickHouse бясплатны. Асабліва бясплатны для Enum, таму што дадзеныя на дыску не мяняюцца. Але тым не менш alter захоплівае блакаванне* на табліцу і павінен пачакаць, пакуль выканаюцца ўсе selects. І толькі пасля гэтага alter выканаецца, т. е. усёткі некаторыя нязручнасці прысутнічаюць.

* у свежых версіях ClickHouse, ALTER зроблены цалкам неблакіруючым.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Яшчэ адзін варыянт дастаткова унікальны для ClickHouse - гэта падлучэнне знешніх слоўнікаў. Вы можаце пісаць у ClickHouse колькасці, а вашыя даведнікі трымаць у любой зручнай вам сістэме. Напрыклад, можна выкарыстоўваць: MySQL, Mongo, Postgres. Можна нават свой мікрасэрвіс запілаваць, які будзе па http аддаваць гэтыя дадзеныя. І на ўзроўні ClickHouse вы пішыце функцыю, якая будзе гэтыя дадзеныя пераўтвараць з лікаў у радкі.

Гэта спецыялізаваны, але вельмі эфектыўны спосаб выканаць join са знешняй табліцай. Прычым ёсць два варыянты. У адным варыянце гэтыя дадзеныя будуць цалкам закэшаваныя, цалкам прысутнічаць у аператыўцы і абнаўляцца з некаторай перыядычнасцю. А ў іншым варыянце, калі гэтыя дадзеныя ў аператыўку не змяшчаюцца, то можна іх часткова кэшаваць.

Вось прыклад. Ёсць Яндэкс.Дырэкт. І там ёсць рэкламная кампанія і банеры. Рэкламных кампаній, напэўна, каля дзясятка мільёнаў. І прыкладна змяшчаюцца ў аператыўку. А банэраў - мільярды, яны не змяшчаюцца. І мы выкарыстоўваем які кэшуецца слоўнік з MySQL.

Адзіная праблема ў тым, што які кэшуецца слоўнік будзе працаваць нармальна, калі hit rate блізкі да 100 %. Калі паменш, то пры апрацоўцы запытаў на кожны пачак дадзеных трэба будзе рэальна браць якія адсутнічаюць ключы і хадзіць забіраць дадзеныя з MySQL. Пра ClickHouse я яшчэ магу заручыцца, што так, не тармозіць, пра іншыя сістэмы казаць не буду.

А ў якасці бонуса тое, што слоўнікі - гэта вельмі просты спосаб абнаўляць дадзеныя ў ClickHouse заднім лікам. Т. е. была ў вас справаздача па рэкламнай кампаніям, карыстач проста памяняў рэкламную кампанію і ва ўсіх старых дадзеных, ва ўсіх справаздачах гэтыя дадзеныя таксама памяняліся. Калі пісаць радкі непасрэдна ў табліцу, тое абнаўляць іх будзе немагчыма.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Яшчэ адзін спосаб, калі вы не ведаеце, адкуль вам узяць ідэнтыфікатары для вашых радкоў. можна проста захэшаваць. Прычым самы просты варыянт - гэта браць 64 бітны хэш.

Адзіная праблема ў тым, што калі хэш 64-х бітны, то калізіі ў вас абавязкова будуць амаль напэўна. Бо калі там мільярд радкоў, то верагоднасць ужо становіцца адчувальнай.

І не вельмі добра было б так хэшаваць імёны рэкламных кампаній. Калі рэкламныя кампаніі ў розных кампаній пераблытаюцца, то будзе нешта незразумелае.

І ёсць просты трук. Праўда, для сур'ёзных дадзеных таксама не вельмі падыходзіць, але калі нешта не вельмі сур'ёзнае, то проста дадайце ў ключ слоўніка яшчэ ідэнтыфікатар кліента. І тады калізіі ў вас будуць, але толькі ў межах аднаго кліента. І такі спосаб у нас выкарыстоўваецца для карты спасылак у Яндэкс.Метрыцы. Ёсць у нас тамака урлы, мы захоўваем хэшы. І мы ведаем, што калізіі, канешне, ёсць. Але калі адлюстроўваецца старонка, то верагоднасць таго, што менавіта на адной старонцы ў аднаго карыстача нейкія урлы зліпліся і гэта яшчэ заўважаць, то гэтым можна занядбаць.

У якасці бонуса - для многіх аперацый дастаткова адных хэшаў і самі радкі можна нідзе не захоўваць.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Іншы прыклад, калі радкі кароткія, напрыклад, дамены сайтаў. Іх можна захоўваць як ёсць. Ці, напрыклад, мова браўзэра be - 2 байта. Мне вядома, вельмі шкада байтыкі, але не хвалюйцеся, 2 байта не шкада. Калі ласка, захоўвайце як ёсць, не парцеся.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Іншы выпадак, калі, наадварот, радкоў вельмі шмат і ў іх пры гэтым вельмі шмат унікальных, ды яшчэ і мноства патэнцыйна не абмежавана. Тыповы прыклад - гэта пошукавыя фразы або урлы. Пошукавыя фразы, у тым ліку з-за памылак друку. Паглядзім, колькі ўнікальных пошукавых фраз за суткі. І атрымліваецца, што іх ці не палова ад усіх падзей. І ў гэтым выпадку вы маглі б падумаць, што трэба дадзеныя нармалізаваць, лічыць ідэнтыфікатары, складаць у асобную табліцу. Але рабіць так ня трэба. Проста захоўвайце гэтыя радкі як ёсць.

Лепш - нічога не прыдумляйце, таму што калі асобна захоўваць, то запатрабуецца рабіць join. А гэты join - гэта ў лепшым выпадку выпадковы доступ у памяць, калі яшчэ ў памяць змесціцца. Калі не змесціцца, то ўвогуле будуць праблемы.

А калі дадзеныя захоўваюцца ў in place, то яны проста вычытваюцца ў патрэбным парадку з файлавай сістэмы і ўсё нармальна.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Калі ў вас ёсць урлы ці яшчэ нейкі складаны доўгі радок, то варта задумацца аб тым, што можна палічыць нейкую выцісканне загадзя і запісаць у асобны слупок.

Для урлаў, напрыклад, можна асобна захоўваць дамен. І калі вам насамрэч патрэбен дамен, то проста выкарыстоўвайце гэты слупок, а урлы будуць ляжаць, і вы да іх нават дакранацца не будзеце.

Давайце паглядзім, якая атрымоўваецца розніца. У ClickHouse ёсць спецыялізаваная функцыя, якая вылічае дамен. Яна вельмі хуткая, мы яе аптымізавалі. І, шчыра скажу, яна нават не адпавядае RFC, але тым не менш лічыць, усё, што нам трэба.

І ў адным выпадку мы будзем проста даставаць урлы і вылічаць дамен. Атрымліваецца 166 мілісекунд. А калі ўзяць гатовы дамен, то атрымліваецца ўсяго толькі 67 мілісекунд, т. е. амаль у тры разы хутчэй. Прычым хутчэй не праз тое, што нам трэба рабіць нейкія вылічэнні, а праз тое, што мы чытаем менш дадзеных.

Вось чамусьці ў аднаго запыту, які павольней, атрымліваецца большая хуткасць гігабайтаў у секунду. Таму што ён чытае больш за гігабайт. Гэта зусім лішнія дадзеныя. Запыт працуе хутчэй, але выконваецца за больш працяглы час.

А калі паглядзець аб'ём дадзеных на дыску, тое атрымліваецца, што урл 126 мегабайтаў, а дамен усяго толькі 5 мегабайтаў. Атрымліваецца ў 25 разоў менш. Але тым не менш запыт выконваецца ўсяго толькі ў 4 разы хутчэй. Але гэта таму, што дадзеныя гарачыя. А калі было б халодныя, то напэўна было ў 25 разоў хутчэй з-за дыскавага ўводу-высновы.

Дарэчы, калі ацаніць, наколькі дамен менш за урл, то атрымліваецца дзесьці разы ў 4. Але чамусьці на дыску дадзеныя займаюць у 25 разоў менш. Чаму? З-за сціску. І урл сціскаецца, і дамен сціскаецца. Але часта урл змяшчае кучу смецця.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

І, вядома, варта выкарыстоўваць правільныя тыпы дадзеных, якія прызначаны спецыяльна для патрэбных значэнняў ці, якія падыходзяць. Калі вы ў IPv4, то захоўваеце UInt32*. Калі IPv6, то FixedString(16), таму што IPv6 адрас - гэта 128 біт, т. е. захоўваеце прама ў бінарным фармаце.

А што рабіць, калі ў вас часам IPv4 адраса, а часам IPv6? Так, можна захоўваць абодва. Адзін слупок для IPv4, іншы для IPv6. Вядома, ёсць варыянт IPv4 адлюстроўваць у IPv6. Гэта таксама будзе працаваць, але калі вам у запытах часта патрэбен менавіта IPv4 адрас, тое нядрэнна б засунуць у асобны слупок.

* зараз у ClickHouse ёсць асобныя тыпы дадзеных IPv4, IPv6, якія захоўваюць дадзеныя гэтак жа эфектыўна, як лікі, але ўяўляюць іх гэтак жа зручна, як радкі.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Яшчэ важна заўваж, што варта дадзеныя прадапрацаваць загадзя. Напрыклад, паступаюць да вас нейкія волкія логі. І, магчыма, варта не адразу іх засоўваць у ClickHouse, хоць вельмі прывабна нічога не рабіць і ўсё будзе працаваць. Але варта ўсё ж такі правесці тыя вылічэнні, якія можна.

Напрыклад, версія браўзэра. У некаторым суседнім аддзеле, на які мне не жадаецца паказваць пальцам, тамака версія браўзэра захоўваецца вось так, т. е. як радок: 12.3. А потым, каб зрабіць справаздачу, яны бяруць гэты радок і дзеляць на масіў, а потым на першы элемент масіва. Натуральна, усё тармозіць. Я пытаўся, чаму яны так робяць. Яны мне адказалі, што не любяць дачасную аптымізацыю. А я не люблю заўчасную песімізацыю.

Так што ў гэтым выпадку правільней будзе падзяліць на 4 слупкі. Тут не бойцеся, таму што гэта ClickHouse. ClickHouse - гэта столбцовая база дадзеных. І чым больш акуратных маленькіх слупкоў, тым лепш. Будзе 5 BrowserVersion, рабіце 5 слупкоў. Гэта нармальна.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Цяпер разгледзім, што рабіць, калі ў вас шмат вельмі доўгіх радкоў, вельмі доўгіх масіваў. Іх не трэба захоўваць у ClickHouse наогул. Замест гэтага вы можаце захаваць у ClickHouse толькі нейкі ідэнтыфікатар. А гэтыя доўгія радкі засуньце іх у якую-небудзь іншую сістэму.

Напрыклад, у адным з нашых аналітычных сервісаў ёсць некаторыя параметры падзей. І калі на падзеі прыходзяць шмат параметраў, мы проста захоўваем першыя якія трапілі 512. Таму што 512 - не шкада.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

А калі вы не можаце вызначыцца з вашымі тыпамі дадзеных, тыя вы можаце таксама запісаць дадзеныя ў ClickHouse, але ў часавую табліцу тыпу Log, адмысловую для часавых дадзеных. Пасля гэтага вы можаце прааналізаваць, якое ў вас тамака размеркаванне значэнняў, што наогул ёсць і скласці правільныя тыпы.

* зараз у ClickHouse ёсць тып дадзеных LowCardinality які дазваляе эфектыўна захоўваць радкі з меншымі працавыдаткамі.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Цяпер разгледзім яшчэ адзін цікавы выпадак. Часам у людзей усё неяк дзіўна працуе. Я заходжу і бачу такое. І адразу ўяўляецца, што гэта рабіў нейкі вельмі дасведчаны, разумны адмін, у якога вялікі досвед налады MySQL версіі 3.23.

Тут мы бачым тысячу табліц, у кожнай з якой запісаны астатак ад дзялення незразумела чаго на тысячу.

У прынцыпе, я паважаю чужы досвед, у тым ліку разумею, якімі пакутамі гэты досвед можа быць напрацаваны.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

І прычыны больш-менш зразумелыя. Гэта старыя стэрэатыпы, якія маглі назапасіцца пры працы з іншымі сістэмамі. Напрыклад, у MyISAM табліцах няма кластарнага першаснага ключа. І такі спосаб падзелу дадзеных можа быць адчайнай спробай атрымаць тую ж функцыянальнасць.

Іншая прычына - гэта тое, што ўсякія аперацыі тыпу alter над вялікімі табліцамі рабіць цяжка. Усё будзе блакавацца. Хоць у сучасных версіях MySQL гэтая праблема ўжо не гэтак сур'ёзная.

Ці, напрыклад, мікрашардзіраванне, але пра гэта крыху пазней.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

У ClickHouse так рабіць не трэба, таму што, па-першае, першасны ключ кластарны, дадзеныя спарадкаваны па першасным ключы.

І часам мяне пытаюцца: "Як змяняецца прадукцыйнасць дыяпазонных запытаў у ClickHouse ад памеру табліцы?". Я кажу, што яна ніяк не мяняецца. Напрыклад, у вас табліца ў мільярд радкоў і праглядаеце дыяпазон адзін мільён радкоў. Усё нармальна. Калі ў табліцы трыльён радкоў і вы праглядаеце адзін мільён радкоў, то будзе амаль тое ж самае.

І, па-другое, усякіх штук тыпу ручных партыцый не патрабуецца. Калі вы зойдзеце і паглядзіце, што там на файлавай сістэме, вы ўбачыце, што табліца - гэта досыць сур'ёзная рэч. І там унутры ёсць нешта тыпу партыцый. Т. е. ClickHouse усё робіць за вас і вам не трэба пакутаваць.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Alter у ClickHouse бясплатны, калі alter add/drop column.

І маленькія табліцы рабіць не варта, таму што калі ў вас у табліцы 10 радкоў ці 10 000 радкоў, тое гэта здзейснена ўсё роўна. ClickHouse - гэта сістэма, якая аптымізуе throughput, а не latency, так што 10 радкоў апрацоўваць не мець сэнсу.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Правільна выкарыстоўваць адну вялікую табліцу. Пазбаўцеся ад старых стэрэатыпаў, усё будзе добра.

А ў якасці бонуса ў нас у апошняй версіі з'явілася магчымасць рабіць адвольны ключ партыцыянавання для таго, каб выконваць усялякія maintenance аперацыі над асобнымі партыямі.

Напрыклад, вам трэба шмат маленькіх табліц, напрыклад, калі бывае запатрабаванне ў апрацоўцы нейкіх прамежкавых дадзеных, вам паступаюць чанкі і вам трэба выконваць пераўтварэнне над імі перад запісам у фінальную табліцу. Для гэтага выпадку ёсць выдатны рухавічок табліцы - StripeLog. Гэта прыкладна як TinyLog, толькі лепш.

* зараз у ClickHouse ёсць яшчэ і таблічная функцыя input.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Яшчэ адзін антыпатэрн - гэта мікрашардынг. Напрыклад, вам дадзеныя трэба шаліць і ў вас ёсць 5 сервераў, а заўтра будзе 6 сервераў. І вы думаеце, як гэтыя дадзеныя перабалансаваць. І замест гэтага вы разбіваеце не на 5 шардаў, а на 1 000 шардаў. І далей адлюстроўваеце кожны з гэтых мікрашардаў на асобны сервер. І ў вас атрымаецца на адным серверы, напрыклад, 200 ClickHouse, напрыклад. Асобныя instance на асобных партах ці асобныя базы дадзеных.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Але ў ClickHouse гэта не вельмі добрае. Таму што нават адзін instance ClickHouse імкнецца выкарыстоўваць усе даступныя рэсурсы сервера для апрацоўкі аднаго запыту. Т. е. ёсць у вас сервер які-небудзь і тамака, напрыклад, 56 працэсарных ядраў. Вы выконваеце запыт, які выконваецца адну секунду, і ен будзе выкарыстоўваць 56 ядраў. А калі вы размясцілі там 200 ClickHouse на адным серверы, тое атрымліваецца, што запусціцца 10 000 струменяў. Увогуле ўсё будзе вельмі дрэнна.

Іншая прычына ў тым, што размеркаванне працы па гэтых instances будзе нераўнамернае. Нейкі скончыць раней, нейкі скончыць пазней. Калі б усё гэта адбывалася ў адным instance, то ClickHouse сам бы разабраўся як размеркаваць правільна дадзеныя па патоках.

І яшчэ адна прычына ў тым, што будзе ў вас міжпрацэсарнае ўзаемадзеянне па TCP. Дадзеныя прыйдзецца серыялізоўваць, дэсерыялізоўваць і гэтая велізарная колькасць мікрашардаў. Проста неэфектыўна будзе працаваць.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Яшчэ адзін антыпатэрн, хоць яго цяжка назваць антыпатэрнам. Гэта вялікая колькасць перадагрэгацыі.

Наогул, перадагрэгацыя - гэта добра. Было ў вас мільярд радкоў, вы яго сагрэгавалі і стала 1 радкоў, і зараз запыт выконваецца імгненна. Усё выдатна. Так можна рабіць. І для гэтага нават у ClickHouse ёсць спецыяльны тып табліцы AggregatingMergeTree, які робіць інкрыментальную агрэгацыю па меры ўстаўцы дадзеных.

Але бываюць выпадкі, калі вы думаеце, што мы будзем вось так агрэгаваць дадзеныя і яшчэ так агрэгаваць дадзеныя. І ў некаторым суседнім аддзеле, таксама не жадаецца казаць у якім, выкарыстоўваюць табліцы SummingMergeTree для сумавання па першасным ключы, а ў якасці першаснага ключа выкарыстоўваюць штук 20 нейкіх слупкоў. Я на ўсялякі выпадак змяніў імёны некаторых слупкоў для канспірацыі, але прыкладна так і ёсць.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

І ўзнікаюць такія праблемы. Па-першае, аб'ём дадзеных у вас памяншаецца не занадта моцна. Напрыклад, памяншаецца ў тры разы. Тры разы - гэта было б добрай цаной, каб дазволіць сабе неабмежаваныя магчымасці па аналітыцы, якія ўзнікаюць, калі дадзеныя ў вас неагрэгаваныя. Калі дадзеныя агрэгаваныя, то вы замест аналітыкі атрымліваеце ўсяго толькі нікчэмную статыстыку.

І што асабліва дастае? Тое, што гэтыя людзі з суседняга аддзела, ходзяць і просяць часам дадаць яшчэ адзін слупок у першасны ключ. Т. е. мы вось дык вось агрэгавалі дадзеныя, а зараз жадаем крыху больш. Але ў ClickHouse няма alter першаснага ключа. Таму даводзяцца пісаць нейкія скрыпты на C++. А я не кахаю скрыпты, нават калі яны на C++.

І калі паглядзець для чаго ствараўся ClickHouse, то неагрэгаваныя дадзеныя - гэта прама той сцэнар, для якога ён народжаны. Калі вы выкарыстоўваеце ClickHouse для неагрэгаваных дадзеных, то вы ўсё робіце правільна. Калі вы агрэгуеце, то гэта часам даравальна.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Яшчэ адзін цікавы выпадак - гэта запыты ў бясконцым цыкле. Я часам заходжу на які-небудзь production сервер і гляджу тамака show processlist. І кожны раз выяўляю, што адбываецца нешта жудаснае.

Напрыклад, вось такое. Тут адразу зразумела, што можна было ўсё выканаць у адным запыце. Проста пішыце тамака url in і спіс.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Чаму шмат такіх запытаў у бясконцым цыкле - гэта дрэнна? Калі індэкс не выкарыстоўваецца, то ў вас будзе шмат праходаў па адных і тых жа дадзеных. Але калі індэкс выкарыстоўваецца, напрыклад, у вас есць першасны ключ па ru і вы пішаце url = чаму-то там. І вы думаеце, што будзе кропкава чытацца з табліцы XNUMX url, будзе ўсё нармальна. Але насамрэч няма. Таму што ClickHouse усё робіць па пачках.

Калі яму трэба прачытаць нейкі дыяпазон дадзеных, ён чытае крыху больш, таму што індэкс у ClickHouse разрэджаны. Гэты індэкс не дазваляе знайсці ў табліцы адзін індывідуальны радок, толькі дыяпазон нейкі. І дадзеныя сціскаюцца блокамі. Для таго каб прачытаць адзін радок, трэба ўзяць цэлы блок і расціснуць яго. І калі вы выконваеце кучу запытаў, у вас будзе шмат скрыжаванняў такіх, і куча працы ў вас будзе выконвацца зноў і зноў.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

І ў якасці бонуса можна заўважыць, што ў ClickHouse не варта баяцца перадаваць нават мегабайты і нават сотні мегабайт у секцыю IN. Я памятаю з нашай практыкі, што калі ў MySQL перадаем кучу значэнняў у секцыю IN, напрыклад, перадаем туды 100 мегабайт нейкіх лікаў, то MySQL з'ядае 10 гігабайт памяці і больш з гэтым нічога не адбываецца, усё працуе дрэнна.

А другое - гэта тое, што ў ClickHouse, калі ў вас запыты выкарыстоўваюць індэкс, то гэта заўсёды не павольней, чым full scan, т. е. калі прачытаць трэба амаль усю табліцу, ён будзе ісці паслядоўна і чытаць усю табліцу. Карацей, сам разбярэцца.

Але тым не менш ёсць некаторыя складанасці. Напрыклад, тое, што IN з подзапросов індэкс не выкарыстоўвае. Але гэта нашая праблема і нам трэба гэта выпраўляць. Нічога фундаментальнага тут няма. Будзем правіць*.

І яшчэ адна цікавая рэч - гэта тое, што калі ў вас вельмі доўгі запыт і размеркаваная апрацоўка запытаў ідзе, то гэты вельмі доўгі запыт будзе адпраўлены на кожны сервер без сціску. Напрыклад, 100 мегабайтаў і 500 сервераў. І, адпаведна, у вас па сетцы будзе перададзена 50 гігабайт. Будзе перададзена і потым усё паспяхова выканаецца.

* ужо выкарыстоўвае; усё паправілі, як абяцана.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

І даволі часты выпадак, калі запыты прыходзяць з API. Напрыклад, вы зрабілі нейкі свой сервіс. І калі ваш сэрвіс камусьці патрэбен, тыя вы адкрылі API і ўжо літаральна праз два дні бачыце, што адбываецца нешта незразумелае. Усё перагружана і нейкія жахлівыя запыты прыходзяць, якія ніколі не павінны былі быць.

І рашэнне тут адно. Калі вы адкрылі API, то вам яго давядзецца рэзаць. Напрыклад, уводзіць квоты якія-небудзь. Іншых нармальных варыянтаў няма. Інакш адразу напішуць скрыпт і будуць праблемы.

І ў ClickHouse ёсць спецыяльная магчымасць - гэта падлік квот. Прычым можна перадаваць свой ключ квоты. Гэта, напрыклад, унутраны ідэнтыфікатар карыстальніка. І квоты будуць лічыць незалежна для кожнага з іх.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Цяпер яшчэ адна цікавая рэч. Гэта рэплікацыя на ручным прывадзе.

Я ведаю шмат выпадкаў, калі, нягледзячы на ​​тое, што ў ClickHouse ёсць убудаваная падтрымка рэплікацыі, людзі рэплікуюць ClickHouse уручную.

Прынцып які? У вас ёсць pipeline апрацоўкі даных. І ён працуе незалежна, напрыклад, у розных дата-цэнтрах. Вы аднолькавыя дадзеныя аднолькавым чынам запісваеце ў ClickHouse як бы. Праўда, практыка паказвае, што дадзеныя ўсё роўна будуць разыходзіцца з-за нейкіх асаблівасцяў у вашым кодзе. Спадзяюся, што ў вашым.

І перыядычна вам усё роўна давядзецца ўручную сінхранізаваць. Напрыклад, раз у месяц адміны робяць rsync.

Насамрэч значна прасцей выкарыстоўваць убудаваную ў ClickHouse рэплікацыю. Але тут могуць быць некаторыя супрацьпаказанні, бо для гэтага трэба выкарыстоўваць ZooKeeper. Я нічога дрэннага пра ZooKeeper казаць не буду, у прынцыпе, сістэма працоўная, але бывае, што людзі не выкарыстоўваюць яго з-за java-фобіі, таму што ClickHouse - гэта такая добрая сістэма, напісаная на C++, якой можна карыстацца і будзе ўсё выдатна . А ZooKeeper на java. І неяк нават не хочацца глядзець, але тады можаце рэплікацыю на ручным прывадзе выкарыстоўваць.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

ClickHouse - гэта практычная сістэма. Яна ўлічвае вашыя патрэбныя. Калі ў вас рэплікацыя на ручным прывадзе, тыя вы можаце стварыць Distributed табліцу, якая глядзіць на вашыя ручныя рэплікі і сама робіць паміж імі failover. І ёсць нават спецыяльная опцыя, якая дазваляе пазбегнуць флапаў, нават калі вашыя рэплікі сістэматычна разыходзяцца.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Далей могуць быць праблемы, калі вы карыстаецеся прымітыўныя table engines. ClickHouse - гэта такі канструктар, у якім ёсць куча розных рухавічкоў табліц. Для ўсіх сур'ёзных выпадкаў, як напісана ў дакументацыі, выкарыстоўвайце табліцы сямейства MergeTree. А ўсе астатнія - гэта так, для асобных выпадкаў або для тэстаў.

У табліцы MergeTree не абавязкова, каб у вас былі нейкая дата і час. Усё роўна можаце выкарыстоўваць. Калі няма даты і часу, пішыце, што default - 2000 год. Гэта будзе працаваць і рэсурсаў не будзе патрабаваць.

І ў новай версіі сервера можна нават паказаць, каб у вас было кастамнае партыцыянаванне без ключа партыцыі. Гэта будзе тое самае.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

З іншага боку, можна выкарыстоўваць прымітыўныя рухавічкі табліц. Напрыклад, заліць дадзеныя адзін раз і паглядзець, пакруціць і выдаліць. Можаце выкарыстоўваць Log.

Або захоўванне маленькіх аб'ёмаў для прамежкавай апрацоўкі - гэта StripeLog або TinyLog.

Memory можна выкарыстоўваць, калі маленькі аб'ём дадзеных і проста пакруціць што-небудзь у аператыўцы.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

ClickHouse не вельмі любіць перанармалізаваныя дадзеныя.

Вось тыповы прыклад. Гэта вялізная колькасць урлаў. Вы іх засунулі ў суседнюю табліцу. А потым вырашылі з імі рабіць JOIN, але гэта працаваць не будзе, як правіла, таму што ClickHouse падтрымлівае толькі Hash JOIN. Калі аператыўкі бракуе для мноства дадзеных, з якімі трэба злучаць, то JOIN выканаць не атрымаецца*.

Калі дадзеныя вялікай кардынальнасці, то не парцеся, захоўвайце іх у дэнармалізаваным выглядзе, урлы прама inplace ў асноўнай табліцы.

* а цяпер у ClickHouse ёсць і merge join таксама, і ён працуе ва ўмовах, калі прамежкавыя дадзеныя не змяшчаюцца ў аператыўку. Але гэта неэфектыўна і рэкамендацыя застаецца ў сіле.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Яшчэ парачка прыкладаў, але я ўжо сумняваюся антыпатэрныя яны ці не.

У ClickHouse ёсць адзін вядомы недахоп. Ён не ўмее апдэйты. У некаторым сэнсе гэта нават добра. Калі ў вас нейкія важныя дадзеныя, напрыклад, бухгалтэрыя, то ніхто іх адправіць не зможа, бо апдэйтаў няма.

* ужо даўно дададзеная падтрымка update і delete у batch рэжыме.

Але ёсць некаторыя асаблівыя спосабы, якія дазваляюць апдэйты як бы ў фоне. Напрыклад, табліцы тыпу ReplaceMergeTree. Яны робяць апдэйты падчас фонавых merges. Вы можаце гэта фарсіраваць з дапамогай optimize table. Але не рабіце гэта занадта часта, бо гэта будзе поўным перазапісам партыцыі.

Размеркаваныя JOIN у ClickHouse - гэта таксама дрэнна апрацоўваецца планавальнікам запытаў.

Дрэнна, але часам Ок.

Выкарыстанне ClickHouse толькі для таго, каб прачытаць дадзеныя зваротна з дапамогай select*.

Я б не рэкамендаваў выкарыстоўваць ClickHouse для грувасткіх вылічэнняў. Але гэта не зусім так, бо мы ўжо адыходзім ад гэтай рэкамендацыі. І ў нас нядаўна дадалася магчымасць ужываць мадэлі машыннага навучання ў ClickHouse - Catboost. І гэта мяне непакоіць, бо я думаю: “Які жах. Гэта колькі ж тактаў на байт атрымліваецца!». Мне вельмі шкада такты на байты пускаць.

Эфектыўнае выкарыстанне ClickHouse. Аляксей Мілавідаў (Яндэкс)

Але не бойцеся, стаўце ClickHouse, усё будзе добра. Калі што, у нас ёсць супольнасць. Дарэчы, супольнасць - гэта вы. І калі ў вас нейкія праблемы, вы можаце хаця б зайсці ў наш чат, і, спадзяюся, што вам дапамогуць.

пытанні

Дзякуй за даклад! Куды скардзіцца на падзенне ClickHouse?

Можна скардзіцца мне асабіста зараз.

Я нядаўна стаў выкарыстоўваць ClickHouse. Адразу выпусціў cli інтэрфейс.

Вам пашанцавала.

Крыху пазней я выпусціў сервер маленькім select'ам.

У вас талент.

Я адкрыў баг GitHub, але яго праігнаравалі.

Паглядзім.

Аляксей падманам зацягнуў мяне на даклад, паабяцаўшы расказаць, як вы дадзеныя ўнутры цісне.

Вельмі проста.

Гэта я яшчэ ўчора зразумеў. Больш канкрэтыкі.

Там няма ніякіх хітрасцяў жахлівых. Тамака проста сціск па блоках. Па змаўчанні выкарыстоўваецца LZ4, можна ўключыць ZSTD*. Блокі ад 64 кілабайт да 1 мегабайта.

* таксама ёсць падтрымка спецыялізаваных кодэкаў сціску, якія можна выкарыстоўваць у ланцужку з іншымі алгарытмамі.

У блоках проста волкія дадзеныя?

Не зусім волкія. Там масівы. Калі ў вас слупок лікавы, то там лікі запар выкладзены ў масіў.

Зразумела.

Аляксей, прыклад, які быў з uniqExact над айпішнікамі, г. зн. тое, што uniqExact па радках даўжэй лічыцца, чым па ліках і гэтак далей. А калі мы прыменім фінт вушамі і будзем кастываць у момант вычытвання? Т. е. вы, накшталт бы сказалі, што на дыску яно ў нас не моцна адрозніваецца. Калі мы будзем чытаць з дыска радкі, кастыць, то тады хутчэй у нас агрэгаты будуць ці не? Ці мы ўсё ж такі нязначна тут выйграем? Мне здаецца, што вы гэта тэставалі, але чамусьці не ўказалі ў бенчмарку.

Я думаю, што яно будзе павольней, чым без касты. У гэтым выпадку IP-адрас трэба з радка распарсіць. У нас, вядома, у ClickHouse парсінг IP-адрасоў таксама аптымізаваны. Мы вельмі пастараліся, але там жа ў вас лічбы запісаны ў дзесяцітысячнай форме. Вельмі няёмка. З іншага боку функцыя uniqExact будзе на радках працаваць павольней не толькі таму што гэта радкі, але яшчэ і таму што выбіраецца іншая спецыялізацыя алгарытму. Радкі проста апрацоўваюцца па-іншаму.

А калі ўзяць больш прымітыўны тып даных? Напрыклад, запісалі user id, які ў нас in, запісалі яго радком, а потым скасцілі, будзе весялей ці не?

Я сумняваюся. Я думаю, што будзе нават сумней, таму што ўсё ж такі парсіць лічбы - гэта сур'ёзная праблема. Мне здаецца, што вось у гэтага калегі быў нават даклад на тэму таго, як складана парсіць лічбы ў дзесяцітысячнай форме, а, можа, і не.

Аляксей, вялікі дзякуй за даклад! І яшчэ вялікі дзякуй за ClickHouse! У мяне пытанне наконт планаў. Ці ёсць у планах фіча для апдэйта слоўнікаў не цалкам?

Т. е. частковая перазагрузка?

Так так. Тыпу магчымасць задаць там поле MySQL, т. е. апдэйціць after, каб загружаліся толькі гэтыя дадзеныя, калі слоўнік вельмі вялікі.

Вельмі цікавая фіча. І, мне здаецца, нейкі чалавек прапанаваў яе ў нашым чаце. Можа, гэта нават былі вы.

Ня думаю, што я.

Выдатна, зараз атрымліваецца, што два запыты. І можна не спяшаючыся пачынаць рабіць. Але адразу вас жадаю папярэдзіць, што гэтая фіча даволі простая для рэалізацыі. Т. е. па ідэі трэба проста ў табліцу напісаць нумар версіі і далей пісаць: версія менш вось такой. А гэта значыць, што, хутчэй за ўсё, мы прапануем гэта зрабіць энтузіястам. Вы энтузіяст?

Так, але, нажаль, не ў C++.

Калегі вашыя на C++ умеюць пісаць?

Знайду каго-небудзь.

Выдатна*.

* магчымасць была дададзена праз два месяцы пасля дакладу – яе распрацаваў аўтар пытання і адправіў свой запыт цягнуць.

Дзякуй!

Добры дзень! Дзякуй за даклад! Вы згадвалі, што ClickHouse вельмі добра спажывае ўсе рэсурсы, даступныя яму. І дакладчык суседні з Люксафт расказваў пра сваё рашэнне для Пошты Расіі. Ён сказаў, што ім вельмі спадабаўся ClickHouse, але яны не выкарыстоўвалі яго замест свайго асноўнага канкурэнта менавіта таму, што ён зжыраў увесь працэсар. І яны не змаглі ўторкнуць яго ў сваю архітэктуру, у свой ZooKeeper з докерамі. Ці ёсць магчымасць неяк абмежаваць ClickHouse, каб ён не спажываў усё-ўсё, што яму становіцца даступным?

Так, можна і вельмі лёгка. Калі хочаце, каб менш ядраў спажываў, то проста пішыце set max_threads = 1. І ўсё, будзе ў адно ядро ​​выконваць запыт. Прычым можна розным карыстальнікам паказаць розную гэтую настройку. Так што ніякіх праблем. І калегам з Люксафт перадайце, што не добра, што яны не знайшлі гэтую настройку ў дакументацыі.

Аляксей, добры дзень! Жадаў бы пацікавіцца такім пытаннем. Ужо не першы раз чую, што многія пачынаюць выкарыстоўваць ClickHouse як сховішча для логаў. На дакладзе вы казалі, каб так не рабіць, т. е. не трэба захоўваць доўгія радкі. Як вы да гэтага ставіцеся?

Па-першае, логі - гэта, як правіла, не доўгія радкі. Бывае, вядома, выключэнні. Напрыклад, які-небудзь сэрвіс, напісаны на java, кідаюць exception, ён лагіруецца. І так у бясконцым цыкле, і сканчаецца месца на цвёрдай кружэлцы. Рашэнне вельмі простае. Калі радкі вельмі доўгія, то рэжце іх. А што значыць доўгія? Дзесяткі кілабайт - гэта дрэнна *.

* у свежых версіях ClickHouse, уключаная "адаптыўная грануляванасць індэкса", што здымае праблему захоўвання доўгіх радкоў па большай частцы.

А кілабайт - гэта нармальна?

Нармальна.

Добры дзень! Дзякуй за даклад! Я ўжо пра гэта ў чаце пытаўся, але не памятаю, ці атрымаў адказ. Ці плануецца неяк пашыраць секцыю WITH на манер CTE?

Пакуль няма. Секцыя WITH у нас некалькі несур'ёзная. Яна ў нас як маленькая фіча.

Я зразумеў. Дзякуй!

Дзякуй за даклад! Вельмі цікава! Глабальнае пытанне. Ці плануецца рабіць, магчыма, у выглядзе нейкіх заглушак мадыфікацыю выдалення дадзеных?

Абавязкова. Гэта наша першая задача ў нашай чарзе. Мы зараз актыўна прадумалі, як усё рабіць правільна. І варта пачынаць націскаць на клавіятуру*.

* панаціскалі кнопкі на клавіятуры і ўсё зрабілі.

Ці паўплывае гэта неяк на прадукцыйнасць сістэмы ці не? Устаўка будзе такая ж хуткая, як і зараз?

Магчыма, самі deletes, самі updates будуць вельмі цяжкімі, але затое гэта ніяк не паўплывае на прадукцыйнасць selects і прадукцыйнасць inserts.

І яшчэ маленькае пытанне. На прэзентацыі вы казалі пра primary key. Адпаведна, у нас ёсць партыцыянаванне, якое па змаўчанні месячнае, правільнае? І калі мы задаем дыяпазон дат, які ўкладваецца ў месяц, то ў нас счытваецца толькі гэтая партыцыя, праўда?

Да.

Такое пытанне. Калі мы не можам вылучыць які-небудзь primary key, то ці правільна яго рабіць менавіта па полі "Дата" для таго, каб у фонавым рэжыме была меншая перабудова гэтых дадзеных, каб яны ўклаліся больш спарадкавана? Калі ў вас няма дыяпазонных запытаў і вы нават не можаце абраць ніякі першасны ключ, то ці варта засунуць у першасны ключ дату?

Да.

Можа быць, ёсць сэнс пакласці ў першасны ключ такое поле, па якім дадзеныя будуць лепш сціскацца, калі яны будуць адсартаваны па гэтым полі. Напрыклад, ідэнтыфікатар user'а. User, напрыклад, ходзіць на адзін і той жа сайт. У гэтым выпадку кладзяце user id і час. І тады ў вас дадзеныя будуць лепш сціскацца. Наконт даты, калі ў вас сапраўды няма і ніколі не бывае дыяпазонных запытаў па датах, то можна не класці дату ў першасны ключ.

Добра, дзякуй вялікі!

Крыніца: habr.com

Дадаць каментар