Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Dahil ang ClickHouse ay isang dalubhasang sistema, kapag ginagamit ito, mahalagang isaalang-alang ang mga tampok ng arkitektura nito. Sa ulat na ito, si Alexey ay magsasalita tungkol sa mga halimbawa ng mga karaniwang pagkakamali kapag gumagamit ng ClickHouse, na maaaring humantong sa hindi epektibong trabaho. Ipapakita ng mga praktikal na halimbawa kung paano maaaring baguhin ng pagpili ng isa o isa pang pamamaraan sa pagpoproseso ng data ang pagganap ayon sa mga order ng magnitude.

Kamusta kayong lahat! Ang pangalan ko ay Alexey, gumagawa ako ng ClickHouse.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Una, nagmamadali akong pasayahin ka kaagad, ngayon hindi ko sasabihin sa iyo kung ano ang ClickHouse. To be honest, pagod na ako. Sa tuwing sasabihin ko sa iyo kung ano ito. At malamang alam na ng lahat.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Sa halip, sasabihin ko sa iyo kung ano ang mga posibleng pagkakamali, iyon ay, kung paano mo magagamit ang ClickHouse nang hindi tama. Sa katunayan, hindi kailangang matakot, dahil binubuo namin ang ClickHouse bilang isang sistema na simple, maginhawa, at gumagana nang wala sa kahon. Na-install ko ito, walang problema.

Ngunit kailangan mo pa ring isaalang-alang na ang system na ito ay dalubhasa at madali kang makakatagpo ng isang hindi pangkaraniwang kaso ng paggamit na mag-aalis sa system na ito mula sa comfort zone nito.

Kaya, anong uri ng kalaykay ang naroon? Karamihan ay magsasalita ako tungkol sa mga halatang bagay. Ang lahat ay halata sa lahat, naiintindihan ng lahat ang lahat at maaaring matuwa na sila ay napakatalino, at ang mga hindi nakakaintindi ay matututo ng bago.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ang una at pinakasimpleng halimbawa, na, sa kasamaang-palad, ay madalas na nangyayari, ay isang malaking bilang ng mga pagsingit na may maliliit na batch, ibig sabihin, isang malaking bilang ng mga maliliit na pagsingit.

Kung isasaalang-alang namin kung paano gumaganap ang ClickHouse ng insert, maaari kang magpadala ng kahit isang terabyte ng data sa isang kahilingan. Hindi ito problema.

At tingnan natin kung ano ang magiging karaniwang pagganap. Halimbawa, mayroon kaming talahanayan mula sa data ng Yandex.Metrica. Mga hit. 105 ilang column. 700 bytes na hindi na-compress. At ipasok namin sa isang mahusay na paraan sa mga batch ng isang milyong mga hilera.

Ipinasok namin ang MergeTree sa talahanayan, lumalabas ang kalahating milyong mga hilera bawat segundo. Malaki. Sa isang kinokopyang talahanayan, magiging mas maliit ito, humigit-kumulang 400 row bawat segundo.

At kung ie-enable mo ang quorum insertion, makakakuha ka ng kaunti, ngunit disenteng performance pa rin, 250 termino kada segundo. Ang paglalagay ng korum ay isang hindi dokumentadong tampok sa ClickHouse*.

* noong 2020, dokumentado na.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ano ang mangyayari kung gumawa ka ng masama? Nagpasok kami ng isang row sa MergeTree table at nakakakuha ng 59 row bawat segundo. Iyan ay 10 beses na mas mabagal. Sa ReplicatedMergeTree – 000 na hilera bawat segundo. At kung naka-on ang korum, 6 linya bawat segundo ang lalabas. Sa aking opinyon, ito ay isang uri ng ganap na crap. Paano ka magbabagal ng ganyan? May nakasulat pa nga sa T-shirt ko na hindi dapat bumagal ang ClickHouse. Ngunit gayunpaman nangyayari ito kung minsan.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Sa katunayan, ito ang ating pagkukulang. Madali sana naming gawing maayos ang lahat, ngunit hindi namin ginawa. At hindi namin ginawa dahil hindi kailangan ng script namin. Nagkaroon na kami ng butches. Nakatanggap lang kami ng mga batch sa aming pasukan, at walang problema. Ipinasok namin ito at lahat ay gumagana nang maayos. Ngunit, siyempre, lahat ng uri ng mga senaryo ay posible. Halimbawa, kapag mayroon kang isang grupo ng mga server kung saan nabuo ang data. At hindi sila naglalagay ng data nang madalas, ngunit nauuwi pa rin sila sa madalas na pagsingit. At kailangan nating iwasan ito kahit papaano.

Mula sa isang teknikal na punto ng view, ang punto ay na kapag gumawa ka ng isang insert sa ClickHouse, ang data ay hindi napupunta sa anumang memtable. Wala kaming totoong log structure na MergeTree, ngunit isang MergeTree lang, dahil walang log o memTable. Agad naming isulat ang data sa file system, na nakaayos na sa mga hanay. At kung mayroon kang 100 mga hanay, pagkatapos ay higit sa 200 mga file ay kailangang isulat sa isang hiwalay na direktoryo. Ang lahat ng ito ay napakahirap.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

At ang tanong ay lumitaw: "Paano ito gagawin nang tama?" Kung ang sitwasyon ay tulad na kailangan mo pa ring mag-record ng data sa ClickHouse.

Paraan 1. Ito ang pinakamadaling paraan. Gumamit ng ilang uri ng distributed queue. Halimbawa, Kafka. I-extract mo lang ang data mula sa Kafka at i-batch ito minsan sa isang segundo. At magiging maayos ang lahat, magre-record ka, gumagana nang maayos ang lahat.

Ang mga disadvantages ay ang Kafka ay isa pang bulky distributed system. Naiintindihan ko rin kung mayroon ka nang Kafka sa iyong kumpanya. Mabuti naman, maginhawa. Ngunit kung wala ito, dapat kang mag-isip nang tatlong beses bago mag-drag ng isa pang distributed system sa iyong proyekto. At kaya sulit na isaalang-alang ang mga alternatibo.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Paraan 2. Ito ay isang alternatibong lumang paaralan at sa parehong oras ay napakasimple. Mayroon ka bang ilang uri ng server na bumubuo ng iyong mga log. At isinusulat lang nito ang iyong mga log sa isang file. At minsan sa isang segundo, halimbawa, pinapalitan namin ang pangalan ng file na ito at pinuputol ang bago. At isang hiwalay na script, alinman sa pamamagitan ng cron o ilang daemon, ang kumukuha ng pinakamatandang file at isusulat ito sa ClickHouse. Kung magre-record ka ng mga log minsan sa isang segundo, magiging maayos ang lahat.

Ngunit ang kawalan ng pamamaraang ito ay kung ang iyong server kung saan nabuo ang mga log ay nawala sa isang lugar, pagkatapos ay mawawala din ang data.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Paraan 3. May isa pang kawili-wiling paraan, na hindi nangangailangan ng pansamantalang mga file sa lahat. Halimbawa, mayroon kang ilang uri ng advertising spinner o ilang iba pang kawili-wiling daemon na bumubuo ng data. At maaari kang makaipon ng isang bungkos ng data nang direkta sa RAM, sa buffer. At kapag lumipas na ang sapat na oras, isasantabi mo ang buffer na ito, lumikha ng bago, at sa isang hiwalay na thread, ipasok ang naipon na sa ClickHouse.

Sa kabilang banda, nawawala rin ang data na may kill -9. Kung nag-crash ang iyong server, mawawala ang data na ito. At ang isa pang problema ay kung hindi ka makapagsulat sa database, ang iyong data ay maipon sa RAM. At maaaring maubusan ang RAM, o mawawalan ka lang ng data.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Paraan 4. Isa pang kawili-wiling paraan. Mayroon ka bang ilang uri ng proseso ng server. At maaari itong magpadala kaagad ng data sa ClickHouse, ngunit gawin ito sa isang koneksyon. Halimbawa, nagpadala ako ng http request na may transfer-encoding: chunked with insert. At ito ay bumubuo ng mga chunks na hindi masyadong bihira, maaari mong ipadala ang bawat linya, kahit na magkakaroon ng overhead para sa pag-frame ng data na ito.

Gayunpaman, sa kasong ito ang data ay ipapadala kaagad sa ClickHouse. At ang ClickHouse ay buffer sa kanila mismo.

Ngunit lumitaw din ang mga problema. Ngayon ay mawawalan ka ng data, kabilang ang kapag ang iyong proseso ay pinatay at kung ang proseso ng ClickHouse ay pinatay, dahil ito ay isang hindi kumpletong insert. At sa ClickHouse insert ay atomic hanggang sa isang tiyak na tinukoy na threshold sa laki ng mga row. Sa prinsipyo, ito ay isang kawili-wiling paraan. Pwede ring gamitin.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Paraan 5. Narito ang isa pang kawili-wiling paraan. Ito ay isang uri ng server na binuo ng komunidad para sa pag-batch ng data. Hindi ko pa tinitingnan ang sarili ko, kaya wala akong masisiguro. Gayunpaman, walang mga garantiya na ibinigay para sa ClickHouse mismo. Open source din ito, ngunit sa kabilang banda, maaari kang masanay sa ilang pamantayan ng kalidad na sinusubukan naming ibigay. Ngunit para sa bagay na ito - hindi ko alam, pumunta sa GitHub, tingnan ang code. Baka normal lang ang sinulat nila.

* sa 2020, dapat ding idagdag sa pagsasaalang-alang KutingBahay.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Paraan 6. Ang isa pang paraan ay ang paggamit ng mga Buffer table. Ang bentahe ng pamamaraang ito ay napakadaling simulan ang paggamit. Gumawa ng Buffer table at ipasok ito dito.

Ang kawalan ay ang problema ay hindi ganap na nalutas. Kung, sa isang rate tulad ng MergeTree, kailangan mong magpangkat ng data sa pamamagitan ng isang batch bawat segundo, pagkatapos ay sa isang rate sa isang buffer table, kailangan mong magpangkat ng hindi bababa sa ilang libo bawat segundo. Kung ito ay higit sa 10 bawat segundo, ito ay magiging masama pa rin. At kung ipasok mo ito sa mga batch, pagkatapos ay nakita mo na ito ay lumalabas na isang daang libong linya bawat segundo. At ito ay nasa medyo mabigat na data.

At ang mga buffer table ay walang log. At kung may mali sa iyong server, mawawala ang data.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

At bilang isang bonus, nakakuha kami kamakailan ng pagkakataon sa ClickHouse na kunin ang data mula sa Kafka. May isang table engine - Kafka. Lumikha ka lang. At maaari kang magsabit ng mga materialized na representasyon dito. Sa kasong ito, ito mismo ang kukuha ng data mula sa Kafka at ipasok ito sa mga talahanayan na kailangan mo.

At ang nakatutuwa sa pagkakataong ito ay hindi kami ang gumawa nito. Ito ay isang tampok ng komunidad. At kapag sinabi kong "tampok sa komunidad," ang ibig kong sabihin ay walang anumang paghamak. Binasa namin ang code, gumawa ng pagsusuri, dapat itong gumana nang maayos.

* noong 2020, lumitaw ang katulad na suporta para sa Kuneho MQ.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ano pa ang maaaring hindi maginhawa o hindi inaasahan kapag naglalagay ng data? Kung gumawa ka ng isang kahilingan sa pagpasok ng mga halaga at sumulat ng ilang kinakalkula na mga expression sa mga halaga. Halimbawa, ang now() ay isa ring kinakalkulang expression. At sa kasong ito, ang ClickHouse ay napipilitang ilunsad ang interpreter ng mga expression na ito sa bawat linya, at ang pagganap ay bababa sa mga order ng magnitude. Mas mabuting iwasan ito.

* sa ngayon, ang problema ay ganap na nalutas, wala nang anumang pagbabalik ng pagganap kapag gumagamit ng mga expression sa VALUES.

Ang isa pang halimbawa ay kapag maaaring may ilang mga problema kapag mayroon kang data sa isang batch na kabilang sa isang grupo ng mga partisyon. Bilang default, ang mga partisyon ng ClickHouse ay ayon sa buwan. At kung magpasok ka ng isang batch ng isang milyong mga hilera, at mayroong data sa loob ng maraming taon, magkakaroon ka ng ilang dosenang mga partisyon doon. At ito ay katumbas ng katotohanan na magkakaroon ng mga batch ng ilang sampu-sampung beses na mas maliit sa laki, dahil sa loob sila ay palaging nahahati sa mga partisyon.

* Kamakailan, sa experimental mode, ang ClickHouse ay nagdagdag ng suporta para sa compact na format ng mga chunks at chunks sa RAM na may write-ahead log, na halos ganap na nalulutas ang problema.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ngayon tingnan natin ang pangalawang uri ng problema - ang pag-type ng data.

Maaaring mahigpit o string ang pag-type ng data. Ang string ay kapag kinuha mo lang ito at ipinahayag na ang lahat ng iyong mga patlang ay may uri ng string. Nakakahiya ito. Hindi na kailangang gawin ito.

Alamin natin kung paano ito gagawin nang tama sa mga kasong iyon kapag gusto mong sabihin na mayroon kaming ilang field, isang string, at hayaan ang ClickHouse na malaman ito nang mag-isa, at hindi ako mag-abala. Ngunit sulit pa rin ang paggawa ng ilang pagsisikap.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Halimbawa, mayroon kaming IP address. Sa isang kaso, na-save namin ito bilang isang string. Halimbawa, 192.168.1.1. At sa isa pang kaso, ito ay isang bilang ng uri ng UInt32*. Ang 32 bits ay sapat na para sa isang IPv4 address.

Una, kakaiba, ang data ay mai-compress nang humigit-kumulang pantay. Magkakaroon ng pagkakaiba, siyempre, ngunit hindi ganoon kalaki. Kaya walang mga espesyal na problema sa disk I/O.

Ngunit mayroong isang malubhang pagkakaiba sa oras ng processor at oras ng pagpapatupad ng query.

Bilangin natin ang bilang ng mga natatanging IP address kung nakaimbak ang mga ito bilang mga numero. Gumagana iyon sa 137 milyong linya bawat segundo. Kung ang parehong ay sa anyo ng mga string, pagkatapos ay 37 milyong mga linya sa bawat segundo. Hindi ko alam kung bakit nangyari ang coincidence na ito. Ako mismo ang nagsagawa ng mga kahilingang ito. Ngunit humigit-kumulang 4 na beses na mas mabagal.

At kung kalkulahin mo ang pagkakaiba sa puwang ng disk, mayroon ding pagkakaiba. At ang pagkakaiba ay humigit-kumulang isang quarter, dahil napakaraming natatanging IP address. At kung mayroong mga linya na may maliit na bilang ng iba't ibang kahulugan, kung gayon madali silang mai-compress ayon sa diksyunaryo sa humigit-kumulang sa parehong dami.

At ang apat na beses na pagkakaiba ng oras ay hindi namamalagi sa kalsada. Siguro hindi ka nagpaparamdam, siyempre, ngunit kapag nakita ko ang gayong pagkakaiba, nalulungkot ako.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Tingnan natin ang iba't ibang mga kaso.

1. Isang kaso kapag mayroon kang ilang iba't ibang natatanging halaga. Sa kasong ito, gumagamit kami ng isang simpleng kasanayan na malamang na alam mo at magagamit para sa anumang DBMS. Ang lahat ng ito ay may katuturan hindi lamang para sa ClickHouse. Sumulat lamang ng mga numeric identifier sa database. At maaari kang mag-convert sa mga string at pabalik sa gilid ng iyong application.

Halimbawa, mayroon kang isang rehiyon. At sinusubukan mong i-save ito bilang isang string. At ito ay isusulat doon: Moscow at Moscow Region. At kapag nakita ko na ito ay nagsasabing "Moscow", ito ay wala, ngunit kapag ito ay Moscow, ito ay nagiging ganap na malungkot. Ito ay kung gaano karaming mga byte.

Sa halip, isulat lang namin ang numerong Ulnt32 at 250. Mayroon kaming 250 sa Yandex, ngunit maaaring iba ang sa iyo. Kung sakali, sasabihin ko na ang ClickHouse ay may built-in na kakayahang magtrabaho sa isang geobase. Isulat mo lang ang isang direktoryo na may mga rehiyon, kabilang ang isang hierarchical, ibig sabihin, magkakaroon ng Moscow, Rehiyon ng Moscow, at lahat ng kailangan mo. At maaari kang mag-convert sa antas ng kahilingan.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ang pangalawang opsyon ay halos pareho, ngunit may suporta sa loob ng ClickHouse. Ito ang uri ng data ng Enum. Isulat mo lang ang lahat ng mga halaga na kailangan mo sa loob ng Enum. Halimbawa, uri ng device at isulat doon: desktop, mobile, tablet, TV. Mayroong 4 na pagpipilian sa kabuuan.

Ang kawalan ay kailangan mong baguhin ito pana-panahon. Isang opsyon lang ang idinagdag. Mag-alter table tayo. Sa katunayan, ang alter table sa ClickHouse ay libre. Lalo na libre para sa Enum dahil ang data sa disk ay hindi nagbabago. Ngunit gayunpaman, nakakakuha si alter ng lock* sa mesa at dapat maghintay hanggang sa maisakatuparan ang lahat ng pinili. At pagkatapos lamang na isasagawa ang pagbabagong ito, ibig sabihin, mayroon pa ring ilang mga abala.

* sa mga pinakabagong bersyon ng ClickHouse, ang ALTER ay ginawang ganap na hindi nakaharang.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ang isa pang opsyon na medyo kakaiba para sa ClickHouse ay ang pagkonekta ng mga panlabas na diksyunaryo. Maaari kang magsulat ng mga numero sa ClickHouse, at panatilihin ang iyong mga direktoryo sa anumang sistemang maginhawa para sa iyo. Halimbawa, maaari mong gamitin ang: MySQL, Mongo, Postgres. Maaari ka ring lumikha ng iyong sariling microservice na magpapadala ng data na ito sa pamamagitan ng http. At sa antas ng ClickHouse, sumulat ka ng isang function na magko-convert ng data na ito mula sa mga numero patungo sa mga string.

Ito ay isang dalubhasa ngunit napakahusay na paraan upang magsagawa ng pagsali sa isang panlabas na talahanayan. At mayroong dalawang pagpipilian. Sa isang embodiment, ang data na ito ay ganap na mai-cache, ganap na naroroon sa RAM at na-update nang may ilang dalas. At sa isa pang pagpipilian, kung ang data na ito ay hindi magkasya sa RAM, maaari mong bahagyang i-cache ito.

Narito ang isang halimbawa. Mayroong Yandex.Direct. At mayroong isang kumpanya ng advertising at mga banner. Marahil ay may mga sampu-sampung milyong kumpanya ng advertising. At halos magkasya sila sa RAM. At mayroong bilyon-bilyong mga banner, hindi sila magkasya. At gumagamit kami ng naka-cache na diksyunaryo mula sa MySQL.

Ang problema lang ay gagana nang maayos ang naka-cache na diksyunaryo kung malapit sa 100% ang hit rate. Kung ito ay mas maliit, pagkatapos ay kapag nagpoproseso ng mga query para sa bawat batch ng data, kailangan mo talagang kunin ang mga nawawalang key at kunin ang data mula sa MySQL. Tungkol sa ClickHouse, masisiguro ko pa rin iyon - oo, hindi ito bumabagal, hindi ako magsasalita tungkol sa iba pang mga sistema.

At bilang isang bonus, ang mga diksyunaryo ay isang napakadaling paraan upang retroaktibong i-update ang data sa ClickHouse. Ibig sabihin, nagkaroon ka ng ulat sa mga kumpanya ng advertising, binago lang ng user ang kumpanya ng advertising at sa lahat ng lumang data, sa lahat ng ulat, nagbago din ang data na ito. Kung direktang isusulat mo ang mga hilera sa talahanayan, imposibleng i-update ang mga ito.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Isa pang paraan kapag hindi mo alam kung saan kukunin ang mga identifier para sa iyong mga string. maaari mo lamang itong i-hash. Bukod dito, ang pinakasimpleng opsyon ay ang kumuha ng 64-bit hash.

Ang tanging problema ay kung ang hash ay 64-bit, halos tiyak na magkakaroon ka ng mga banggaan. Dahil kung mayroong isang bilyong linya doon, kung gayon ang posibilidad ay nagiging kapansin-pansin.

At hindi magiging napakahusay na i-hash ang mga pangalan ng mga kumpanya ng advertising sa ganitong paraan. Kung ang mga kampanya sa advertising ng iba't ibang mga kumpanya ay magkakahalo, pagkatapos ay magkakaroon ng isang bagay na hindi maintindihan.

At mayroong isang simpleng trick. Totoo, hindi rin ito masyadong angkop para sa seryosong data, ngunit kung may hindi masyadong seryoso, idagdag lang ang client identifier sa key ng diksyunaryo. At pagkatapos ay magkakaroon ka ng mga banggaan, ngunit sa loob lamang ng isang kliyente. At ginagamit namin ang paraang ito para sa mga link na mapa sa Yandex.Metrica. Mayroon kaming mga URL doon, nag-iimbak kami ng mga hash. At alam naman natin na, siyempre, may mga banggaan. Ngunit kapag ipinakita ang pahina, maaaring mapabayaan ang posibilidad na sa isang pahina ng isang user ang ilang mga URL ay magkakadikit at ito ay mapapansin.

Bilang isang bonus, para sa maraming mga operasyon, ang mga hash lamang ay sapat at ang mga string mismo ay hindi kailangang itago kahit saan.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ang isa pang halimbawa ay kung maikli ang mga string, halimbawa, mga domain ng website. Maaari silang maiimbak gaya ng dati. O, halimbawa, ang wika ng browser na ru ay 2 bytes. Siyempre, naaawa talaga ako sa mga byte, ngunit huwag mag-alala, ang 2 byte ay hindi isang awa. Mangyaring panatilihin ito bilang ay, huwag mag-alala.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ang isa pang kaso ay kapag, sa kabaligtaran, mayroong maraming mga linya at mayroong maraming mga kakaiba sa mga ito, at kahit na ang set ay potensyal na walang limitasyon. Ang karaniwang halimbawa ay mga parirala sa paghahanap o URL. Mga parirala sa paghahanap, kabilang ang mga typo. Tingnan natin kung gaano karaming mga natatanging parirala sa paghahanap ang mayroon bawat araw. At ito pala ay halos kalahati ng lahat ng mga kaganapan. At sa kasong ito, maaari mong isipin na kailangan mong gawing normal ang data, bilangin ang mga identifier, at ilagay ito sa isang hiwalay na talahanayan. Ngunit hindi mo kailangang gawin iyon. Panatilihin lamang ang mga linyang ito.

Mas mainam na huwag mag-imbento ng anuman, dahil kung iimbak mo ito nang hiwalay, kakailanganin mong sumali. At ang pagsali na ito ay, sa pinakamainam, isang random na pag-access sa memorya, kung umaangkop pa rin ito sa memorya. Kung hindi ito magkasya, magkakaroon ng mga problema.

At kung ang data ay naka-imbak sa lugar, pagkatapos ay basahin lamang ito sa kinakailangang pagkakasunud-sunod mula sa file system at lahat ay maayos.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Kung mayroon kang mga URL o ilang iba pang kumplikadong mahabang string, sulit na isaalang-alang na maaari mong kalkulahin ang ilang uri ng extract nang maaga at isulat ito sa isang hiwalay na hanay.

Para sa mga URL, halimbawa, maaari mong iimbak ang domain nang hiwalay. At kung talagang kailangan mo ng isang domain, pagkatapos ay gamitin lamang ang column na ito, at ang mga URL ay makikita doon, at hindi mo man lang hawakan ang mga ito.

Tingnan natin kung ano ang pagkakaiba. Ang ClickHouse ay may espesyal na function na kinakalkula ang domain. Ito ay napakabilis, na-optimize namin ito. At, sa totoo lang, hindi man lang ito sumusunod sa RFC, ngunit gayunpaman, isinasaalang-alang nito ang lahat ng kailangan natin.

At sa isang kaso kukunin lang namin ang mga URL at kalkulahin ang domain. Gumagana iyon sa 166 milliseconds. At kung kukuha ka ng isang handa na domain, ito ay lumalabas na 67 milliseconds lamang, ibig sabihin, halos tatlong beses na mas mabilis. At mas mabilis ito hindi dahil kailangan nating gumawa ng ilang kalkulasyon, ngunit dahil mas kaunting data ang ating binabasa.

Kaya naman ang isang kahilingan, na mas mabagal, ay may mas mataas na bilis ng gigabytes bawat segundo. Dahil mas maraming gigabytes ang binabasa nito. Ito ay ganap na hindi kinakailangang data. Mukhang mas mabilis tumakbo ang kahilingan, ngunit mas matagal bago makumpleto.

At kung titingnan mo ang dami ng data sa disk, lumalabas na ang URL ay 126 megabytes, at ang domain ay 5 megabytes lamang. Ito ay lumalabas ng 25 beses na mas kaunti. Ngunit gayunpaman, ang kahilingan ay naisakatuparan lamang ng 4 na beses na mas mabilis. Ngunit iyon ay dahil ang data ay mainit. At kung ito ay malamig, ito ay malamang na 25 beses na mas mabilis dahil sa disk I/O.

Sa pamamagitan ng paraan, kung tinatantya mo kung gaano kalaki ang isang domain kaysa sa isang URL, lumalabas na ito ay humigit-kumulang 4 na beses na mas maliit. Ngunit sa ilang kadahilanan, ang data ay tumatagal ng 25 beses na mas kaunti sa disk. Bakit? Dahil sa compression. At ang URL ay naka-compress, at ang domain ay naka-compress. Ngunit kadalasan ang URL ay naglalaman ng isang bungkos ng basura.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

At, siyempre, nagbabayad ang paggamit ng mga tamang uri ng data na partikular na idinisenyo para sa mga nais na halaga o na angkop. Kung ikaw ay nasa IPv4, pagkatapos ay iimbak ang UInt32*. Kung IPv6, pagkatapos ay FixedString(16), dahil ang IPv6 address ay 128 bits, ibig sabihin, naka-imbak nang direkta sa binary na format.

Ngunit paano kung minsan mayroon kang mga IPv4 address at kung minsan ay IPv6? Oo, maaari mong iimbak ang dalawa. Isang column para sa IPv4, isa pa para sa IPv6. Siyempre, mayroong isang pagpipilian upang ipakita ang IPv4 sa IPv6. Gagana rin ito, ngunit kung madalas mong kailanganin ang isang IPv4 address sa mga kahilingan, mainam na ilagay ito sa isang hiwalay na column.

* Ang ClickHouse ay mayroon na ngayong hiwalay na IPv4, IPv6 na mga uri ng data na nag-iimbak ng data nang kasinghusay ng mga numero, ngunit kinakatawan ang mga ito nang maginhawa gaya ng mga string.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Mahalaga rin na tandaan na ito ay nagkakahalaga ng preprocessing ng data nang maaga. Halimbawa, nakakatanggap ka ng ilang hilaw na log. At marahil ay hindi mo na lang dapat ilagay kaagad ang mga ito sa ClickHouse, bagama't napaka-kaakit-akit na walang gawin at lahat ay gagana. Ngunit sulit pa rin na isagawa ang mga kalkulasyon na posible.

Halimbawa, bersyon ng browser. Sa ilang kalapit na departamento, na hindi ko gustong ituro, ang bersyon ng browser ay naka-imbak tulad nito, iyon ay, bilang isang string: 12.3. At pagkatapos, upang makagawa ng isang ulat, kukunin nila ang string na ito at hinahati ito sa isang array, at pagkatapos ay sa unang elemento ng array. Natural, bumagal ang lahat. Tinanong ko kung bakit nila ginagawa ito. Sinabi nila sa akin na hindi nila gusto ang napaaga na pag-optimize. At hindi ko gusto ang napaaga na pessimization.

Kaya sa kasong ito ay magiging mas tama na hatiin sa 4 na hanay. Huwag matakot dito, dahil ito ay ClickHouse. Ang ClickHouse ay isang columnar database. At ang mas maayos na maliliit na hanay, mas mabuti. Magkakaroon ng 5 BrowserVersions, gumawa ng 5 column. Ito ay mabuti.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ngayon tingnan natin kung ano ang gagawin kung marami kang napakahabang string, napakahabang array. Hindi na kailangang maimbak ang mga ito sa ClickHouse. Sa halip, maaari ka lamang mag-imbak ng isang identifier sa ClickHouse. At ilagay ang mga mahabang linyang ito sa ibang sistema.

Halimbawa, ang isa sa aming mga serbisyo ng analytics ay may ilang mga parameter ng kaganapan. At kung maraming parameter para sa mga kaganapan, i-save lang namin ang unang 512 na makikita. Dahil hindi sayang ang 512.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

At kung hindi ka makapagpasya sa iyong mga uri ng data, maaari ka ring mag-record ng data sa ClickHouse, ngunit sa isang pansamantalang talahanayan ng uri ng Log, espesyal para sa pansamantalang data. Pagkatapos nito, maaari mong pag-aralan kung anong pamamahagi ng mga halaga ang mayroon ka doon, kung ano ang naroroon sa pangkalahatan, at lumikha ng mga tamang uri.

*Ang ClickHouse ay mayroon na ngayong uri ng data Mababang Cardinalidad na nagbibigay-daan sa iyo na mag-imbak ng mga string nang mahusay nang may kaunting pagsisikap.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ngayon tingnan natin ang isa pang kawili-wiling kaso. Minsan ang mga bagay ay gumagana nang kakaiba para sa mga tao. Pumasok ako at nakita ko ito. At tila ito ay agad na ginawa ng ilang napaka karanasan, matalinong admin na may malawak na karanasan sa pagse-set up ng MySQL bersyon 3.23.

Dito makikita natin ang isang libong talahanayan, na ang bawat isa ay nagtatala ng natitira sa paghahati na nakakaalam kung ano sa isang libo.

Sa prinsipyo, iginagalang ko ang karanasan ng ibang tao, kabilang ang pag-unawa sa pagdurusa na maaaring makuha sa karanasang ito.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

At ang mga dahilan ay higit pa o hindi gaanong malinaw. Ito ang mga lumang stereotype na maaaring naipon habang nagtatrabaho sa ibang mga system. Halimbawa, ang mga talahanayan ng MyISAM ay walang clustered primary key. At ang ganitong paraan ng paghahati ng data ay maaaring isang desperadong pagtatangka upang makuha ang parehong pag-andar.

Ang isa pang dahilan ay mahirap gawin ang anumang pagbabago sa mga operasyon sa malalaking mesa. Lahat ay haharangin. Bagaman sa mga modernong bersyon ng MySQL ang problemang ito ay hindi na masyadong seryoso.

O, halimbawa, microsharding, ngunit higit pa sa na mamaya.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Hindi na kailangang gawin ito sa ClickHouse, dahil, una, ang pangunahing key ay clustered, ang data ay iniutos ng pangunahing key.

At minsan tinatanong ako ng mga tao: "Paano nag-iiba ang pagganap ng mga query sa hanay sa ClickHouse depende sa laki ng talahanayan?" Sinasabi ko na hindi ito nagbabago. Halimbawa, mayroon kang isang talahanayan na may isang bilyong row at nabasa mo ang isang hanay ng isang milyong row. Maayos ang lahat. Kung mayroong isang trilyong row sa isang table at nabasa mo ang isang milyong row, ito ay halos pareho.

At, pangalawa, ang lahat ng uri ng mga bagay tulad ng mga manu-manong partisyon ay hindi kinakailangan. Kung papasok ka at titingnan kung ano ang nasa file system, makikita mo na ang talahanayan ay isang malaking bagay. At may parang partition sa loob. Ibig sabihin, ginagawa ng ClickHouse ang lahat para sa iyo at hindi mo kailangang magdusa.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ang pagbabago sa ClickHouse ay libre kung babaguhin ang add/drop column.

At hindi ka dapat gumawa ng maliliit na talahanayan, dahil kung mayroon kang 10 mga hilera o 10 mga hilera sa isang talahanayan, kung gayon hindi ito mahalaga. Ang ClickHouse ay isang sistema na nag-o-optimize ng throughput, hindi latency, kaya walang saysay na iproseso ang 000 linya.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Tamang gumamit ng isang malaking mesa. Alisin ang mga lumang stereotype, magiging maayos ang lahat.

At bilang isang bonus, sa pinakabagong bersyon ay mayroon na kaming kakayahang lumikha ng isang di-makatwirang partitioning key upang maisagawa ang lahat ng uri ng mga operasyon sa pagpapanatili sa mga indibidwal na partisyon.

Halimbawa, kailangan mo ng maraming maliliit na talahanayan, halimbawa, kapag may pangangailangan na iproseso ang ilang intermediate na data, makakatanggap ka ng mga chunks at kailangan mong magsagawa ng pagbabago sa mga ito bago sumulat sa huling talahanayan. Para sa kasong ito, mayroong isang kahanga-hangang table engine - StripeLog. Ito ay parang TinyLog, mas maganda lang.

* ngayon ay mayroon din ang ClickHouse input ng function ng talahanayan.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ang isa pang antipattern ay microsharding. Halimbawa, kailangan mong i-shard ang data at mayroon kang 5 server, at bukas ay magkakaroon ng 6 na server. At iniisip mo kung paano i-rebalance ang data na ito. At sa halip, hindi ka masira sa 5 shards, ngunit sa 1 shards. At pagkatapos ay imapa mo ang bawat isa sa mga microshard na ito sa isang hiwalay na server. At makakakuha ka, halimbawa, 000 ClickHouses sa isang server, halimbawa. Paghiwalayin ang mga pagkakataon sa magkakahiwalay na port o hiwalay na database.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ngunit hindi ito napakahusay sa ClickHouse. Dahil kahit isang ClickHouse instance ay sumusubok na gamitin ang lahat ng magagamit na mapagkukunan ng server upang iproseso ang isang kahilingan. Iyon ay, mayroon kang ilang uri ng server at mayroon itong, halimbawa, 56 na mga core ng processor. Nagpapatakbo ka ng isang query na tumatagal ng isang segundo at gagamit ito ng 56 na mga core. At kung naglagay ka ng 200 ClickHouses doon sa isang server, lalabas na 10 na mga thread ang magsisimula. Sa pangkalahatan, ang lahat ay magiging napakasama.

Ang isa pang dahilan ay ang pamamahagi ng trabaho sa mga pagkakataong ito ay magiging hindi pantay. May matatapos ng mas maaga, may matatapos mamaya. Kung nangyari ang lahat ng ito sa isang pagkakataon, ang ClickHouse mismo ang makakaalam kung paano ipapamahagi nang tama ang data sa mga thread.

At isa pang dahilan ay magkakaroon ka ng interprocessor communication sa pamamagitan ng TCP. Ang data ay kailangang serialized, deserialized, at ito ay isang malaking bilang ng mga microshards. Hindi ito gagana nang epektibo.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Isa pang antipattern, bagaman halos hindi ito matatawag na antipattern. Ito ay isang malaking halaga ng pre-aggregation.

Sa pangkalahatan, maganda ang pre-aggregation. Mayroon kang isang bilyong row, pinagsama-sama mo ito at naging 1 row, at ngayon ang query ay naisasagawa kaagad. Lahat ay magaling. Kaya mo yan. At para dito, kahit ang ClickHouse ay may espesyal na uri ng talahanayan, AggregatingMergeTree, na nagsasagawa ng incremental na pagsasama-sama habang ipinapasok ang data.

Ngunit may mga pagkakataon na sa tingin mo ay pagsasama-samahin namin ang data na tulad nito at pagsasama-sama ng data na tulad nito. At sa ilang kalapit na departamento, hindi ko rin gustong sabihin kung alin, ginagamit nila ang mga talahanayan ng SummingMergeTree upang i-summarize sa pamamagitan ng pangunahing susi, at humigit-kumulang 20 mga hanay ang ginagamit bilang pangunahing susi. Kung sakali, pinalitan ko ang mga pangalan ng ilang column para sa pagiging lihim, ngunit iyon lang.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

At ang gayong mga problema ay lumitaw. Una, hindi masyadong nababawasan ang dami ng iyong data. Halimbawa, bumababa ito ng tatlong beses. Magiging magandang presyo ang tatlong beses para maabot ang walang limitasyong mga kakayahan sa analytics na lalabas kung hindi pinagsama-sama ang iyong data. Kung ang data ay pinagsama-sama, pagkatapos ay sa halip na analytics nakakakuha ka lamang ng mga nakakaawa na istatistika.

At ano ang espesyal dito? Ang katotohanan ay ang mga taong ito mula sa kalapit na departamento ay pumupunta at humihiling na magdagdag ng isa pang column sa pangunahing susi. Iyon ay, pinagsama-sama namin ang data tulad nito, ngunit ngayon gusto namin ng kaunti pa. Ngunit ang ClickHouse ay walang alter primary key. Samakatuwid, kailangan nating magsulat ng ilang mga script sa C++. At hindi ko gusto ang mga script, kahit na nasa C++ ang mga ito.

At kung titingnan mo kung para saan nilikha ang ClickHouse, kung gayon ang hindi pinagsama-samang data ay eksakto ang senaryo kung saan ito ipinanganak. Kung gumagamit ka ng ClickHouse para sa hindi pinagsama-samang data, ginagawa mo ito nang tama. Kung pinagsama-sama mo, minsan ito ay mapapatawad.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ang isa pang kawili-wiling kaso ay ang mga query sa isang walang katapusang loop. Minsan pumunta ako sa ilang production server at tumitingin sa show processlist doon. At sa tuwing matutuklasan ko na may nangyayaring kakila-kilabot.

Halimbawa, ganito. Kaagad na malinaw na ang lahat ay maaaring gawin sa isang kahilingan. Isulat lang ang url at ang listahan doon.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Bakit masama ang maraming ganoong mga query sa isang walang katapusang loop? Kung hindi ginagamit ang isang index, magkakaroon ka ng maraming pass sa parehong data. Ngunit kung ginamit ang index, halimbawa, mayroon kang pangunahing susi para sa ru at sumulat ka ng url = isang bagay doon. At iniisip mo na kung isang URL lang ang babasahin mula sa talahanayan, magiging maayos ang lahat. Pero sa totoo lang hindi. Dahil ginagawa ng ClickHouse ang lahat sa mga batch.

Kapag kailangan niyang basahin ang isang tiyak na hanay ng data, nagbabasa siya ng kaunti pa, dahil ang index sa ClickHouse ay kalat-kalat. Hindi ka pinapayagan ng index na ito na makahanap ng isang indibidwal na hilera sa talahanayan, isang hanay lamang ng ilang uri. At ang data ay naka-compress sa mga bloke. Upang mabasa ang isang linya, kailangan mong kunin ang buong bloke at alisin ito. At kung gumagawa ka ng isang grupo ng mga query, magkakaroon ka ng maraming magkakapatong, at magkakaroon ka ng maraming gawaing paulit-ulit.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

At bilang isang bonus, maaari mong tandaan na sa ClickHouse hindi ka dapat matakot na ilipat kahit na megabytes at kahit na daan-daang megabytes sa seksyong IN. Naaalala ko mula sa aming pagsasanay na kung sa MySQL ay naglilipat kami ng isang grupo ng mga halaga sa seksyong IN, halimbawa, naglilipat kami ng 100 megabytes ng ilang mga numero doon, pagkatapos ay kumakain ang MySQL ng 10 gigabytes ng memorya at wala nang mangyayari dito, lahat hindi gumagana.

At ang pangalawa ay sa ClickHouse, kung ang iyong mga query ay gumagamit ng isang index, kung gayon ito ay palaging hindi mas mabagal kaysa sa isang buong pag-scan, ibig sabihin, kung kailangan mong basahin ang halos buong talahanayan, ito ay pupunta nang sunud-sunod at basahin ang buong talahanayan. Sa pangkalahatan, malalaman niya ito sa kanyang sarili.

Ngunit gayunpaman may ilang mga paghihirap. Halimbawa, ang katotohanan na ang IN na may subquery ay hindi gumagamit ng index. Ngunit ito ang aming problema at kailangan namin itong ayusin. Walang pundamental dito. Aayusin namin ito*.

At ang isa pang kawili-wiling bagay ay kung mayroon kang napakahabang kahilingan at ang distributed request processing ay isinasagawa, ang napakahabang kahilingang ito ay ipapadala sa bawat server nang walang compression. Halimbawa, 100 megabytes at 500 server. At, nang naaayon, magkakaroon ka ng 50 gigabytes na mailipat sa network. Ipapasa ito at pagkatapos ay matagumpay na makukumpleto ang lahat.

* gumagamit na; Naayos ang lahat gaya ng ipinangako.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

At ang isang medyo karaniwang kaso ay kapag ang mga kahilingan ay nagmula sa API. Halimbawa, lumikha ka ng ilang uri ng iyong sariling serbisyo. At kung kailangan ng isang tao ang iyong serbisyo, pagkatapos ay buksan mo ang API at literal pagkalipas ng dalawang araw ay makikita mo na may nangyayaring hindi maintindihan. Sobra na ang lahat at dumarating ang ilang kahila-hilakbot na kahilingan na hindi dapat nangyari.

At isa lang ang solusyon. Kung binuksan mo ang API, kailangan mong i-cut ito. Halimbawa, magpakilala ng ilang uri ng mga quota. Walang ibang mga normal na opsyon. Kung hindi, susulat agad sila ng script at magkakaroon ng mga problema.

At ang ClickHouse ay may espesyal na tampok - pagkalkula ng quota. Bukod dito, maaari mong ilipat ang iyong quota key. Ito ay, halimbawa, ang panloob na user ID. At ang mga quota ay kakalkulahin nang nakapag-iisa para sa bawat isa sa kanila.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ngayon isa pang kawili-wiling bagay. Ito ay manu-manong pagtitiklop.

Alam ko ang maraming kaso kung saan, sa kabila ng pagkakaroon ng ClickHouse na may built-in na suporta sa pagtitiklop, manu-manong ginagaya ng mga tao ang ClickHouse.

Ano ang prinsipyo? Mayroon kang pipeline sa pagproseso ng data. At ito ay gumagana nang nakapag-iisa, halimbawa, sa iba't ibang mga sentro ng data. Isinulat mo ang parehong data sa parehong paraan sa ClickHouse. Totoo, ipinapakita ng kasanayan na mag-iiba pa rin ang data dahil sa ilang feature sa iyong code. Sana nasa iyo.

At paminsan-minsan ay kailangan mo pa ring manu-manong mag-sync. Halimbawa, isang beses sa isang buwan ang mga admin ay gumagawa ng rsync.

Sa katunayan, mas madaling gamitin ang pagtitiklop na nakapaloob sa ClickHouse. Ngunit maaaring mayroong ilang mga contraindications, dahil para dito kailangan mong gumamit ng ZooKeeper. Wala akong sasabihing masama tungkol sa ZooKeeper, sa prinsipyo, gumagana ang system, ngunit nangyayari na hindi ito ginagamit ng mga tao dahil sa java-phobia, dahil ang ClickHouse ay napakagandang sistema, nakasulat sa C++, na maaari mong gamitin at lahat ay magiging maayos . At ang ZooKeeper ay nasa java. At kahit papaano ay hindi mo nais na tumingin, ngunit pagkatapos ay maaari mong gamitin ang manu-manong pagtitiklop.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ang ClickHouse ay isang praktikal na sistema. Isinasaalang-alang niya ang iyong mga pangangailangan. Kung mayroon kang manu-manong pagtitiklop, maaari kang lumikha ng isang Naipamahagi na talahanayan na tumitingin sa iyong mga manu-manong replika at gumagawa ng isang failover sa pagitan ng mga ito. At mayroong kahit isang espesyal na opsyon na nagbibigay-daan sa iyo upang maiwasan ang mga flop, kahit na ang iyong mga linya ay sistematikong magkakaiba.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Maaaring lumitaw ang mga karagdagang problema kung gumagamit ka ng mga primitive table engine. Ang ClickHouse ay isang constructor na mayroong isang grupo ng iba't ibang table engine. Para sa lahat ng seryosong kaso, gaya ng nakasulat sa dokumentasyon, gumamit ng mga talahanayan mula sa pamilyang MergeTree. At lahat ng iba pa - ito ay gayon, para sa mga indibidwal na kaso o para sa mga pagsubok.

Sa isang talahanayan ng MergeTree, hindi mo kailangang magkaroon ng anumang petsa at oras. Magagamit mo pa rin ito. Kung walang petsa at oras, isulat na ang default ay 2000. Ito ay gagana at hindi mangangailangan ng mga mapagkukunan.

At sa bagong bersyon ng server, maaari mo ring tukuyin na mayroon kang custom na partitioning nang walang partition key. Ito ay magiging pareho.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Sa kabilang banda, maaari mong gamitin ang mga primitive table engine. Halimbawa, punan ang data nang isang beses at tingnan, i-twist at tanggalin. Maaari mong gamitin ang Log.

O ang pag-iimbak ng maliliit na volume para sa intermediate processing ay StripeLog o TinyLog.

Maaaring gamitin ang memorya kung ang dami ng data ay maliit at maaari mo lamang i-twiddle ang isang bagay sa RAM.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Hindi talaga gusto ng ClickHouse ang renormalized na data.

Narito ang isang tipikal na halimbawa. Ito ay isang malaking bilang ng mga URL. Ilagay mo sila sa susunod na mesa. At pagkatapos ay nagpasya silang SUMALI sa kanila, ngunit hindi ito gagana, bilang panuntunan, dahil sinusuportahan lamang ng ClickHouse ang Hash JOIN. Kung walang sapat na RAM para sa maraming data na kailangang konektado, hindi gagana ang JOIN*.

Kung ang data ay may mataas na cardinality, huwag mag-alala, itabi ito sa isang denormalized na form, ang mga URL ay direktang nakalagay sa pangunahing talahanayan.

* at ngayon ang ClickHouse ay mayroon ding merge join, at ito ay gumagana sa mga kondisyon kung saan ang intermediate na data ay hindi magkasya sa RAM. Ngunit ito ay hindi epektibo at ang rekomendasyon ay nananatiling may bisa.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ilang mga halimbawa pa, ngunit nagdududa na ako kung sila ay anti-pattern o hindi.

May isang kilalang depekto ang ClickHouse. Hindi ito marunong mag-update*. Sa ilang mga paraan, ito ay kahit na mabuti. Kung mayroon kang ilang mahalagang data, halimbawa, accounting, kung gayon walang makakapagpadala nito, dahil walang mga update.

* Ang suporta para sa pag-update at pagtanggal sa batch mode ay matagal nang naidagdag.

Ngunit may ilang mga espesyal na paraan na nagbibigay-daan sa mga update na parang nasa background. Halimbawa, ang mga talahanayan tulad ng ReplaceMergeTree. Gumagawa sila ng mga update habang pinagsama ang background. Maaari mong pilitin ito gamit ang optimize table. Ngunit huwag gawin ito nang madalas, dahil ganap nitong ma-overwrite ang partisyon.

Ang mga distributed JOIN sa ClickHouse ay hindi rin maayos na pinangangasiwaan ng query planner.

Masama, pero minsan Ok.

Gamit lamang ang ClickHouse upang basahin muli ang data gamit ang piling*.

Hindi ko irerekomenda ang paggamit ng ClickHouse para sa masalimuot na mga kalkulasyon. Ngunit hindi ito ganap na totoo, dahil lumalayo na kami sa rekomendasyong ito. At nagdagdag kami kamakailan ng kakayahang maglapat ng mga modelo ng machine learning sa ClickHouse - Catboost. At nakakaabala sa akin dahil iniisip ko, "Nakakatakot. Ito ay kung gaano karaming mga cycle sa bawat byte ang lumalabas! Ayaw ko talagang mag-aksaya ng mga orasan sa mga byte.

Epektibong paggamit ng ClickHouse. Alexey Milovidov (Yandex)

Ngunit huwag matakot, i-install ang ClickHouse, magiging maayos ang lahat. Kung mayroon man, mayroon tayong komunidad. Sa pamamagitan ng paraan, ang komunidad ay ikaw. At kung mayroon kang anumang mga problema, maaari kang pumunta sa aming chat, at sana ay matulungan ka nila.

mga katanungan

Salamat sa ulat! Saan ako maaaring magreklamo tungkol sa pag-crash ng ClickHouse?

Maaari kang magreklamo sa akin nang personal ngayon.

Sinimulan ko kamakailan ang paggamit ng ClickHouse. Binaba ko agad ang cli interface.

Anong score.

Maya-maya ay na-crash ko ang server na may maliit na pili.

May talent ka.

Nagbukas ako ng isang GitHub bug, ngunit hindi ito pinansin.

Makikita natin.

Niloko ako ni Alexey na dumalo sa ulat, nangako na sasabihin sa akin kung paano mo maa-access ang data sa loob.

Napaka-simpleng.

Napagtanto ko ito kahapon. Higit pang mga detalye.

Walang mga kahila-hilakbot na trick doon. Mayroon lang block-by-block compression. Ang default ay LZ4, maaari mong paganahin ang ZSTD*. Bina-block mula 64 kilobytes hanggang 1 megabyte.

* mayroon ding suporta para sa mga espesyal na compression codec na maaaring magamit sa isang chain kasama ng iba pang mga algorithm.

Ang mga bloke ba ay hilaw na data lamang?

Hindi ganap na hilaw. May mga arrays. Kung mayroon kang numeric na column, ang mga numero sa isang row ay inilalagay sa isang array.

Malinaw naman.

Alexey, isang halimbawa na may uniqExact sa mga IP, ibig sabihin, ang katotohanan na ang uniqExact ay mas tumatagal upang makalkula sa pamamagitan ng mga linya kaysa sa pamamagitan ng mga numero, at iba pa. Paano kung gumamit tayo ng isang pagkukunwari sa ating mga tainga at mag-cast sa oras ng pag-proofread? Iyon ay, tila sinabi mo na sa aming disk ito ay hindi masyadong naiiba. Kung magbabasa tayo ng mga linya mula sa disk at cast, magiging mas mabilis ba ang ating mga aggregates o hindi? O medyo makikinabang pa ba tayo dito? Tila sa akin na sinubukan mo ito, ngunit sa ilang kadahilanan ay hindi ito ipinahiwatig sa benchmark.

Sa tingin ko ito ay magiging mas mabagal kaysa sa walang pag-cast. Sa kasong ito, ang IP address ay dapat na mai-parse mula sa string. Siyempre, sa ClickHouse, ang aming IP address parsing ay na-optimize din. Sinubukan namin nang husto, ngunit mayroon kang mga numero na nakasulat sa ika-sampung libong anyo. Sobrang hindi komportable. Sa kabilang banda, ang uniqExact function ay gagana nang mas mabagal sa mga string, hindi lamang dahil ito ay mga string, ngunit dahil din sa ibang espesyalisasyon ng algorithm ang napili. Ang mga string ay pinoproseso lamang sa ibang paraan.

Paano kung kumuha kami ng mas primitive na uri ng data? Halimbawa, isinulat namin ang user id, kung saan mayroon kami, isinulat ito bilang isang linya, at pagkatapos ay i-scramble ito, magiging mas masaya ba ito o hindi?

nagdududa ako. Sa tingin ko ito ay magiging mas malungkot, dahil pagkatapos ng lahat, ang pag-parse ng mga numero ay isang malubhang problema. Para sa akin, ang kasamahan na ito ay nagbigay pa ng isang ulat kung gaano kahirap i-parse ang mga numero sa ika-sampung libong anyo, ngunit maaaring hindi.

Alexey, maraming salamat sa ulat! At maraming salamat sa ClickHouse! May tanong ako tungkol sa mga plano. Mayroon bang anumang mga plano para sa isang tampok upang i-update ang mga diksyunaryo nang hindi kumpleto?

Iyon ay, isang bahagyang pag-reboot?

Oo Oo. Tulad ng kakayahang magtakda ng isang MySQL field doon, ibig sabihin, i-update pagkatapos upang ang data na ito lamang ang na-load kung ang diksyunaryo ay napakalaki.

Isang napaka-kagiliw-giliw na tampok. At sa tingin ko may nagmungkahi nito sa aming chat. Baka ikaw rin iyon.

parang hindi naman.

Mahusay, ngayon ay lumabas na mayroong dalawang kahilingan. At maaari mong dahan-dahang simulan ang paggawa nito. Ngunit gusto kong balaan ka kaagad na ang tampok na ito ay medyo simple upang ipatupad. Iyon ay, sa teorya, kailangan mo lamang isulat ang numero ng bersyon sa talahanayan at pagkatapos ay isulat ang: bersyon na mas mababa sa ganito at ganoon. Nangangahulugan ito na, malamang, iaalok namin ito sa mga mahilig. Ikaw ba ay isang mahilig?

Oo, ngunit, sa kasamaang-palad, wala sa C++.

Alam ba ng iyong mga kasamahan kung paano magsulat sa C++?

Hahanap ako ng tao.

Malaki*.

* ang tampok ay idinagdag dalawang buwan pagkatapos ng ulat - binuo ito ng may-akda ng tanong at ipinadala ang kanyang mga pull kahilingan.

Salamat sa iyo!

Kamusta! Salamat sa ulat! Nabanggit mo na ang ClickHouse ay napakahusay sa pagkonsumo ng lahat ng mga mapagkukunang magagamit dito. At ang tagapagsalita sa tabi ng Luxoft ay nagsalita tungkol sa kanyang solusyon para sa Russian Post. Sinabi niya na talagang nagustuhan nila ang ClickHouse, ngunit hindi nila ito ginamit sa halip na ang kanilang pangunahing katunggali dahil mismong kinakain nito ang lahat ng CPU. At hindi nila ito maisaksak sa kanilang arkitektura, sa kanilang ZooKeeper na may mga docker. Posible bang kahit papaano ay limitahan ang ClickHouse upang hindi nito maubos ang lahat ng magagamit dito?

Oo, ito ay posible at napakadali. Kung gusto mong kumonsumo ng mas kaunting mga core, pagkatapos ay magsulat lamang set max_threads = 1. At iyon lang, isasagawa nito ang kahilingan sa isang core. Bukod dito, maaari mong tukuyin ang iba't ibang mga setting para sa iba't ibang mga user. Kaya walang problema. At sabihin sa iyong mga kasamahan mula sa Luxoft na hindi maganda na hindi nila nakita ang setting na ito sa dokumentasyon.

Alexey, hello! Gusto kong magtanong tungkol sa tanong na ito. Hindi ito ang unang pagkakataon na narinig ko na maraming tao ang nagsisimulang gumamit ng ClickHouse bilang imbakan para sa mga log. Sa ulat na sinabi mong huwag gawin ito, ibig sabihin, hindi mo kailangang mag-imbak ng mahabang string. Ano ang iyong palagay tungkol sa mga ito?

Una, ang mga log ay, bilang panuntunan, hindi mahabang string. Mayroong, siyempre, mga pagbubukod. Halimbawa, ang ilang serbisyong nakasulat sa java ay naghagis ng eksepsiyon, ito ay naka-log. At iba pa sa isang walang katapusang loop, at ang espasyo sa hard drive ay naubusan. Ang solusyon ay napaka-simple. Kung ang mga linya ay napakahaba, pagkatapos ay i-cut ang mga ito. Ano ang ibig sabihin ng matagal? Masama ang sampu-sampung kilobytes*.

* sa mga pinakabagong bersyon ng ClickHouse, ang "adaptive index granularity" ay pinagana, na nag-aalis ng problema sa pag-iimbak ng mahahabang row para sa karamihan.

Normal ba ang isang kilobyte?

Normal ito.

Kamusta! Salamat sa ulat! Nagtanong na ako tungkol dito sa chat, ngunit hindi ko matandaan kung nakatanggap ako ng sagot. May mga plano bang palawakin ang seksyong WITH sa paraan ng CTE?

Hindi pa. Ang aming WITH section ay medyo walang kabuluhan. Ito ay tulad ng isang maliit na tampok para sa amin.

Naiintindihan ko. Salamat!

Salamat sa ulat! Napaka-interesante! Pandaigdigang tanong. Mayroon bang anumang mga plano na baguhin ang pagtanggal ng data, marahil sa anyo ng ilang uri ng mga stub?

Kailangan. Ito ang aming unang gawain sa aming pila. Aktibo na kaming nag-iisip kung paano gagawin ang lahat ng tama. At dapat mong simulan ang pagpindot sa keyboard*.

* pinindot ang mga pindutan sa keyboard at ginawa ang lahat.

Maaapektuhan ba nito ang pagganap ng system o hindi? Magiging kasing bilis ba ngayon ang pagpasok?

Marahil ang mga pagtanggal sa kanilang sarili at ang mga pag-update mismo ay magiging napakabigat, ngunit hindi ito makakaapekto sa pagganap ng mga pinili o ang pagganap ng mga pagsingit.

At isa pang maliit na tanong. Sa pagtatanghal ay napag-usapan mo ang tungkol sa pangunahing susi. Alinsunod dito, mayroon kaming partitioning, na buwanan bilang default, tama? At kapag nagtakda tayo ng hanay ng petsa na umaakma sa isang buwan, ang partition na ito lang ang mababasa, di ba?

Oo.

Isang tanong. Kung hindi tayo makakapili ng anumang pangunahing susi, tama bang gawin ito nang partikular ayon sa patlang na "Petsa" upang sa background ay may mas kaunting muling pagsasaayos ng data na ito upang magkasya ito sa mas maayos na paraan? Kung wala kang mga query sa hanay at hindi ka makakapili ng anumang pangunahing key, sulit ba ang paglalagay ng petsa sa pangunahing key?

Oo.

Marahil ay makatuwirang maglagay ng field sa pangunahing key na mas mai-compress ang data kung ito ay pinagsunod-sunod ayon sa field na ito. Halimbawa, user ID. Ang user, halimbawa, ay pumupunta sa parehong site. Sa kasong ito, ilagay ang user id at oras. At pagkatapos ay mas mai-compress ang iyong data. Tulad ng para sa petsa, kung talagang wala ka at hindi kailanman magkakaroon ng mga query sa hanay sa mga petsa, hindi mo kailangang ilagay ang petsa sa pangunahing key.

OK maraming salamat!

Pinagmulan: www.habr.com

Magdagdag ng komento