{"id":91438,"date":"2020-08-13T19:42:36","date_gmt":"2020-08-13T17:42:36","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/effektivnoe-ispolzovanie-clickhouse-aleksej-milovidov-yandeks"},"modified":"2020-08-13T19:42:36","modified_gmt":"2020-08-13T17:42:36","slug":"effektivnoe-ispolzovanie-clickhouse-aleksej-milovidov-yandeks","status":"publish","type":"post","link":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/effektivnoe-ispolzovanie-clickhouse-aleksej-milovidov-yandeks","title":{"rendered":"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/8e42c1fffffcc964eacef240ea90bbc5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Da ClickHouse er et specialiseret system, er det vigtigt at tage h\u00f8jde for de s\u00e6rlige kendetegn ved dets arkitektur, n\u00e5r man bruger det. I denne pr\u00e6sentation vil Alexey diskutere typiske fejl ved brug af ClickHouse, som kan f\u00f8re til ineffektiv drift. Gennem praktiske eksempler vil det blive vist, hvordan valget af en bestemt databehandlingsmetode kan \u00e6ndre ydelsen markant.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Hej alle sammen! Jeg hedder Alexey, og jeg arbejder med ClickHouse.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/7f5fc01663be58d3d25e518a4169b8cf.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>For det f\u00f8rste, s\u00e5 vil jeg straks gl\u00e6de jer med, at jeg ikke vil fort\u00e6lle om, hvad ClickHouse er i dag. Hvis jeg skal v\u00e6re \u00e6rlig, s\u00e5 er jeg tr\u00e6t af at g\u00f8re det. Jeg fort\u00e6ller hver gang, hvad det er. Og sandsynligvis ved alle det allerede. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/fae6bd07d098200643d591b8e5bf51e8.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I stedet vil jeg fokusere p\u00e5 de mulige faldgruber, dvs. hvordan man kan bruge ClickHouse forkert. Man skal faktisk ikke v\u00e6re bange, for vi udvikler ClickHouse som et system, der er simpelt, brugervenligt og fungerer med det samme. Installeret og klar, ingen problemer. <\/p>\n<p><\/p>\n<p>Men man skal stadig tage h\u00f8jde for, at dette er et specialiseret system, og man kan let st\u00f8de p\u00e5 us\u00e6dvanlige anvendelsesscenarier, som kan bringe systemet ud af sin komfortzone.<\/p>\n<p><\/p>\n<p>S\u00e5, hvilke faldgruber findes der? Jeg vil prim\u00e6rt tale om \u00e5benlyse ting. Alt er \u00e5benlyst for alle, og de kan gl\u00e6de sig over, hvor kloge de er, mens de, der ikke forst\u00e5r, vil l\u00e6re noget nyt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/bffacf353ff31b361460178e911f0e16.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Det f\u00f8rste, mest enkle eksempel, der desv\u00e6rre ofte ses, er et stort antal inserts med sm\u00e5 batches, dvs. et stort antal sm\u00e5 inserts.<\/p>\n<p><\/p>\n<p>Hvis vi ser p\u00e5, hvordan ClickHouse udf\u00f8rer inserts, kan du sende en datastream p\u00e5 op til en terabyte i \u00e9n foresp\u00f8rgsel. Det er ikke et problem. <\/p>\n<p><\/p>\n<p>Lad os se p\u00e5, hvad den typiske ydelse vil v\u00e6re. For eksempel har vi en tabel med data fra Yandex.Metrica. Hits. 105 forskellige kolonner. 700 byte i ukomprimeret form. Og vi vil inds\u00e6tte i ordentlige batches af en million r\u00e6kker. <\/p>\n<p><\/p>\n<p>N\u00e5r vi inds\u00e6tter i MergeTree-tabellen, f\u00e5r vi en halv million r\u00e6kker per sekund. Fremragende. I den replicerede tabel bliver det lidt mindre, omkring 400.000 r\u00e6kker i sekundet. <\/p>\n<p><\/p>\n<p>Og hvis vi aktiverer quorum-insert, f\u00e5r vi lidt mindre, men stadig en anst\u00e6ndig ydeevne, 250.000 r\u00e6kker i sekundet. Quorum-insert er en uofficiel funktion i ClickHouse*.<\/p>\n<p><\/p>\n<p>* pr. 2020, <noindex><a rel=\"nofollow\" href=\"https:\/\/clickhouse.tech\/docs\/en\/operations\/settings\/settings\/#settings-insert_quorum\">er allerede dokumenteret<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/668498fc82a0f6e851d05e6e1ea67033.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hvad sker der, hvis man g\u00f8r det d\u00e5rligt? Vi inds\u00e6tter en r\u00e6kke ad gangen i MergeTree-tabellen, og det bliver til 59 r\u00e6kker i sekundet. Det er 10.000 gange langsommere. I ReplicatedMergeTree er det 6 r\u00e6kker i sekundet. Og hvis quorum ogs\u00e5 aktiveres, f\u00e5r man 2 r\u00e6kker i sekundet. Jeg synes, det er virkelig en frygtelig situation. Hvordan kan man v\u00e6re s\u00e5 langsom? Jeg har endda en t-shirt, der siger, at ClickHouse ikke burde v\u00e6re langsom. Men alligevel sker det nogle gange. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/4c771eddc4e8453f60ef91123ae5d109.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Faktisk er det vores fejl. Vi kunne sagtens have s\u00f8rget for, at alt fungerede normalt, men det gjorde vi ikke. Og vi gjorde det ikke, fordi det ikke var n\u00f8dvendigt for vores scenario. Vi havde allerede batches. Data kom ind i batches, og der var ingen problemer. Vi indsatte, og alt fungerede fint. Men selvf\u00f8lgelig er der mange scenarier. For eksempel, n\u00e5r du har en masse servere, hvor data genereres. Og de inds\u00e6tter data ikke s\u00e5 ofte, men der er stadig hyppige indsatser. Og det skal man p\u00e5 en eller anden m\u00e5de undg\u00e5. <\/p>\n<p><\/p>\n<p>Fra et teknisk synspunkt er essensen, at n\u00e5r du laver en insert i ClickHouse, s\u00e5 lander dataene ikke i nogen memtable. Vi har ikke engang en rigtig log structure MergeTree, men blot en MergeTree, fordi der hverken er log eller memTable. Vi skriver simpelthen data direkte til filsystemet, allerede opdelt i kolonner. Og hvis du har 100 kolonner, skal over 200 filer skrives til en separat mappe. Det er hele vejen rundt ret besv\u00e6rligt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/24688fe3d39d81b92f12ac1b8b21425b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Og sp\u00f8rgsm\u00e5let opst\u00e5r: \"Hvordan g\u00f8r man det rigtigt?\", hvis man har en situation, hvor man alligevel skal skrive data til ClickHouse.<\/p>\n<p><\/p>\n<p>Metode 1. Det er den nemmeste metode. Brug en eller anden distribueret k\u00f8. For eksempel Kafka. Du tr\u00e6kker bare data ud fra Kafka, batcher hver sekund. Og s\u00e5 vil det fungere fint, du skriver, og det fungerer alle steder. <\/p>\n<p><\/p>\n<p>Ulemperne er, at Kafka er endnu et besv\u00e6rligt distribueret system. Jeg kan stadig forst\u00e5, hvis dit firma allerede har Kafka. Det er godt, det er praktisk. Men hvis det ikke er tilf\u00e6ldet, s\u00e5 skal du t\u00e6nke grundigt over, inden du bringer endnu et distribueret system ind i dit projekt. Derfor b\u00f8r du overveje alternativer. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/4f687221e8c7443abf02fb002c4eba5b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Metode 2. Her er et gammeldags alternativ, og samtidig meget simpelt. Har du en server, der genererer dine logs? Den gemmer blot dine logs i en fil. Og hver sekund for eksempel omd\u00f8ber vi denne fil og \u00e5bner en ny. En separat script, enten via cron eller en daemon, tager den \u00e6ldste fil og inds\u00e6tter den i ClickHouse. Hvis logs gemmes hver sekund, fungerer det glimrende. <\/p>\n<p><\/p>\n<p>Men ulempe ved denne metode er, at hvis din server, der genererer logs, forsvinder et sted, s\u00e5 forsvinder dataene ogs\u00e5.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/b4c28b6df87386c42b6908bdfccb6b90.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Metode 3. Der er en anden interessant metode, der overhovedet ikke bruger midlertidige filer. For eksempel, hvis du har en eller anden reklamegenerator eller en interessant daemon, der genererer data. Du kan samle en bunke data direkte i RAM, i en buffer. Og n\u00e5r der er g\u00e5et tilstr\u00e6kkelig med tid, gemmer du denne buffer, opretter en ny, og i en separat tr\u00e5d inds\u00e6tter du det, der allerede er blevet akkumuleret, i ClickHouse.<\/p>\n<p><\/p>\n<p>P\u00e5 den anden side forsvinder dataene ogs\u00e5 ved kill -9. Hvis din server g\u00e5r ned, mister du disse data. Og derudover er der et problem med, at hvis du ikke kunne skrive til databasen, vil dine data samle sig i RAM. Enten l\u00f8ber RAM'en t\u00f8r, eller ogs\u00e5 mister du ganske enkelt dataene. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/dc375b22fcb26cfa111d0bdb4563aa88.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Metode 4. Endnu en interessant metode. Har du en serverprocess, der kan sende data til ClickHouse med det samme, men g\u00f8re det i \u00e9t forbindelse. For eksempel, sendte en http-anmodning med transfer-encoding: chunked med et insert. Og generere chunks ikke for sj\u00e6ldent, du kan sende hver linje, selvom der vil v\u00e6re overhead til framing af disse data. <\/p>\n<p><\/p>\n<p>Men alligevel, i dette tilf\u00e6lde vil dataene blive sendt til ClickHouse med det samme. Og ClickHouse vil selv buffere dem. <\/p>\n<p><\/p>\n<p>Men ogs\u00e5 problemerne opst\u00e5r. Nu vil du miste data, hvis din proces dr\u00e6bes, og hvis ClickHouse-processen dr\u00e6bes, fordi det vil v\u00e6re en ufuldst\u00e6ndig insert. I ClickHouse er inserts atomare op til en v\u00e6rdi, der er specificeret i r\u00e6kkeantal. I princippet er det en interessant metode. Den kan ogs\u00e5 bruges.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/6a18a974b9600ade377a870390e95d3d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Metode 5. Her er en interessant metode. Dette er en slags community-udviklet server til batch-databehandling. Jeg har ikke selv set p\u00e5 den, s\u00e5 jeg kan ikke garantere noget. Men for ClickHouse gives der heller ingen garantier. Dette er ogs\u00e5 open source, men p\u00e5 den anden side kunne du have v\u00e6nnet dig til en vis standard for kvalitet, som vi arbejder p\u00e5 at sikre. Men for dette v\u00e6rkt\u00f8j - jeg ved ikke, tag et kig p\u00e5 GitHub, se koden. M\u00e5ske har de skrevet noget fornuftigt. <\/p>\n<p><\/p>\n<p>* pr. 2020 b\u00f8r ogs\u00e5 overvejes <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/company\/vk\/blog\/430168\/\">KittenHouse<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/ae6a04af63ae4e7fa160c002fdb6d506.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Metode 6. En anden metode er brugen af buffer-tabeller. Fordelen ved denne metode er, at det er meget nemt at begynde at bruge. Du opretter en buffer-tabel og inds\u00e6tter i den. <\/p>\n<p><\/p>\n<p>Ulempen er, at problemet ikke l\u00f8ses helt. Hvis du inds\u00e6tter med MergeTree-type, skal du gruppere dataene til en batch pr. sekund, men ved inds\u00e6ttelse i en buffer-tabel, skal du gruppere mindst til flere tusinde pr. sekund. Hvis der er mere end 10.000 pr. sekund, vil det stadig v\u00e6re d\u00e5rligt. Og hvis du inds\u00e6tter i batches, s\u00e5 har du set, at der kan komme hundrede tusinde r\u00e6kker pr. sekund. Og det er allerede med ret tunge data. <\/p>\n<p><\/p>\n<p>Og buffer-tabeller har heller ikke en log. Hvis der er noget galt med din server, vil dataene g\u00e5 tabt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/9bb16bf5e8145cc8368b11e54c86c837.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Og som en bonus har vi for nylig f\u00e5et muligheden for at hente data fra Kafka i ClickHouse. Der findes en tabellmotor - Kafka. Du opretter bare en. Og du kan tilf\u00f8je materialiserede synspunkter til den. I dette tilf\u00e6lde vil den selv tr\u00e6kke data fra Kafka og inds\u00e6tte i de \u00f8nskede tabeller. <\/p>\n<p><\/p>\n<p>Og s\u00e6rligt gl\u00e6der det mig, at denne mulighed ikke blev lavet af os. Det er en community-feature. Og n\u00e5r jeg siger \"community-feature\", mener jeg det uden nogen form for nedladende tone. Vi har l\u00e6st koden, lavet anmeldelser, det burde fungere fint. <\/p>\n<p><\/p>\n<p>* pr. 2020 blev der tilf\u00f8jet tilsvarende support for <noindex><a rel=\"nofollow\" href=\"https:\/\/clickhouse.tech\/docs\/en\/engines\/table-engines\/integrations\/rabbitmq\/\">RabbitMQ<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/15dc61dfd435f5f8640395b7de480fe2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hvad kan ellers v\u00e6re ubelejligt eller overraskende ved inds\u00e6ttelse af data? Hvis du laver en insert values-anmodning og i values skriver beregnede udtryk. For eksempel, now() - er dette ogs\u00e5 et beregnet udtryk. Og i dette tilf\u00e6lde er ClickHouse n\u00f8dt til at k\u00f8re fortolkeren for disse udtryk for hver enkelt r\u00e6kke, hvilket vil s\u00e6nke ydelsen markant. Det er bedst at undg\u00e5 dette.<\/p>\n<p><\/p>\n<p>* P\u00e5 nuv\u00e6rende tidspunkt er problemet fuldst\u00e6ndig l\u00f8st, og der er ikke l\u00e6ngere nogen regressionsproblemer med ydeevnen ved brug af udtryk i VALUES.<\/p>\n<p><\/p>\n<p>Et andet eksempel, hvor der kan opst\u00e5 nogle problemer, er, n\u00e5r du har data i \u00e9n batch, der relaterer sig til flere partitioner. Som standard er partitionerne i ClickHouse m\u00e5nedlige. Og hvis du inds\u00e6tter en batch p\u00e5 en million r\u00e6kker, og der er data fra flere \u00e5r, vil du have flere ti partitioner. Det svarer til, at der vil v\u00e6re batches med flere ti dages st\u00f8rrelse, fordi de altid f\u00f8rst opdeles efter partitioner indeni.<\/p>\n<p><\/p>\n<p>* For nylig blev der i ClickHouse i eksperimentel tilstand tilf\u00f8jet underst\u00f8ttelse af et kompakt format for stykker og stykker i hukommelsen med write-ahead log, hvilket n\u00e6sten helt l\u00f8ser problemet.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/b8c6cecdba53559dad31ed11713a980d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Lad os nu se p\u00e5 den anden type problem \u2013 datatyper. <\/p>\n<p><\/p>\n<p>Datatyper kan v\u00e6re strenge eller v\u00e6re af typen string. String-type er, n\u00e5r du bare har taget og erkl\u00e6ret, at alle dine felter er af typen string. Det er ikke en god id\u00e9. S\u00e5dan skal man ikke g\u00f8re. <\/p>\n<p><\/p>\n<p>Lad os finde ud af, hvordan man g\u00f8r det rigtigt i de tilf\u00e6lde, hvor man \u00f8nsker at sige, at et bestemt felt er en string, og lad os lade ClickHouse ordne det selv, uden at jeg skal bekymre mig. Men det er alligevel v\u00e6rd at g\u00f8re nogle anstrengelser. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/a0fdcf6423933293318411242fe2ede7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>For eksempel har vi en IP-adresse. I \u00e9t tilf\u00e6lde har vi gemt den som en string, f.eks. 192.168.1.1. I et andet tilf\u00e6lde vil det v\u00e6re et tal af typen UInt32*. 32 bit er tilstr\u00e6kkeligt til en IPv4 adresse.<\/p>\n<p><\/p>\n<p>For det f\u00f8rste, som ikke er overraskende, vil dataene komprimere omtrent ens. Der vil v\u00e6re en forskel, selvf\u00f8lgelig, men ikke s\u00e5 stor. S\u00e5 der er ikke st\u00f8rre problemer med diskindgangen-udgangen. <\/p>\n<p><\/p>\n<p>Men der er en alvorlig forskel i CPU-tid og udf\u00f8relsestid for foresp\u00f8rgslen. <\/p>\n<p><\/p>\n<p>Lad os t\u00e6lle antallet af unikke IP-adresser, hvis de gemmes som tal. Det bliver 137 millioner r\u00e6kker i sekunder. Hvis det samme g\u00f8res som strenge, s\u00e5 vil det v\u00e6re 37 millioner r\u00e6kker i sekunder. Jeg ved ikke, hvorfor s\u00e5 sammenfald er opn\u00e5et. Jeg selv udf\u00f8rte disse foresp\u00f8rgsler. Men ikke desto mindre er det cirka 4 gange langsommere. <\/p>\n<p><\/p>\n<p>Og hvis vi beregner forskellen i plads p\u00e5 disken, er der ogs\u00e5 en forskel. Og forskellen er omkring en fjerdedel, fordi der er mange unikke IP-adresser. Og hvis her var strenge med et lille antal forskellige v\u00e6rdier, ville de nemt kunne komprimeres i en ordbog til omtrent samme volumen. <\/p>\n<p><\/p>\n<p>Og den firedobbelte forskel i tidsforbrug kan ikke ignoreres. M\u00e5ske er det ligemeget for dig, men n\u00e5r jeg ser s\u00e5dan en forskel, bliver jeg trist.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/f74dbfdab5a9e26fa044a5870a8cc00d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Lad os se p\u00e5 forskellige scenarier. <\/p>\n<p><\/p>\n<p>1. Et scenarie, hvor du har f\u00e5 forskellige unikke v\u00e6rdier. I dette tilf\u00e6lde bruger vi en simpel praksis, som du sikkert kender og kan anvende p\u00e5 enhver DBMS. Det giver mening ikke kun for ClickHouse. Du indtaster blot numeriske identificatorer i databasen. Og konvertering til strenge og tilbage kan ske i din applikation. <\/p>\n<p><\/p>\n<p>For eksempel har du en region. Og du fors\u00f8ger at gemme den som en streng. Og der vil st\u00e5: Moskva og MO. N\u00e5r jeg ser, at der st\u00e5r 'Moskva', er det fint, men n\u00e5r der ogs\u00e5 st\u00e5r MO, s\u00e5 bliver jeg virkelig trist. Det handler jo om, hvor mange bytes der bruges. <\/p>\n<p><\/p>\n<p>I stedet gemmer vi blot nummeret Uint32 og 250. Vi har 250 i Yandex, men det kan v\u00e6re anderledes for dig. For god ordens skyld vil jeg n\u00e6vne, at ClickHouse har indbygget funktionalitet til at arbejde med geodatabaser. Du indtaster blot et register med regioner, herunder hierarkisk, s\u00e5 der vil v\u00e6re Moskva, MO og alt, hvad du beh\u00f8ver. Og du kan konvertere det p\u00e5 foresp\u00f8rgselsniveau. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/cc6e871136dab8f8a35246a5af512cda.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Den anden mulighed er temmelig lignende, men allerede med st\u00f8tte inden for ClickHouse. Det er datatypen Enum. Du indtaster blot alle de v\u00e6rdier, du har behov for, inden for Enum. For eksempel enhedstype, hvor du skriver: desktop, mobil, tablet, tv. Kun 4 muligheder. <\/p>\n<p><\/p>\n<p>Ulempen er, at du j\u00e6vnligt skal \u00e6ndre. Du tilf\u00f8jer blot \u00e9n mulighed. Vi laver en ALTER TABLE. Faktisk er ALTER TABLE i ClickHouse gratis. Is\u00e6r gratis for Enum, fordi dataene p\u00e5 disken ikke \u00e6ndres. Men ikke desto mindre kr\u00e6ver ALTER en l\u00e5s p\u00e5 tabellen og skal vente, indtil alle SELECTs er gennemf\u00f8rt. Og f\u00f8rst derefter udf\u00f8res ALTER, det vil sige, der er stadig nogle ulemper.<\/p>\n<p><\/p>\n<p>* i de nyeste versioner af ClickHouse, er ALTER helt ikke-blokerende.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/d7284fa5be583ab063bb6de0b60f54d4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En anden ret unik mulighed for ClickHouse er tilslutning af eksterne ordb\u00f8ger. Du kan indtaste tal i ClickHouse, mens dine ordb\u00f8ger opbevares i et system, der er bekvemt for dig. For eksempel kan du bruge: MySQL, Mongo, Postgres. Du kan ogs\u00e5 lave din egen mikrotjeneste, der via HTTP leverer disse data. Og p\u00e5 ClickHouse-niveau skriver du en funktion, der omdanner disse tal til strenge. <\/p>\n<p><\/p>\n<p>Dette er en specialiseret, men meget effektiv metode til at udf\u00f8re et join med en ekstern tabel. Der er faktisk to muligheder. I den ene mulighed vil disse data v\u00e6re fuldt cachet, fuldt til stede i RAM og opdateres med nogen j\u00e6vne mellemrum. I den anden mulighed, hvis disse data ikke kan rummes i RAM, kan de delvist caches. <\/p>\n<p><\/p>\n<p>Her er et eksempel. Der er Yandex.Direct. Og der er en reklamekampagne og bannere. Der er nok omkring ti millioner reklamekampagner. Og de kan omtrent rummes i RAM. Men der er milliarder af bannere, de kan ikke rummes. Og vi bruger et cachetabellen fra MySQL.<\/p>\n<p><\/p>\n<p>Det eneste problem er, at den cache-yget tabel fungerer korrekt, hvis hit rate er t\u00e6t p\u00e5 100 %. Hvis den er lavere, skal vi ved behandling af foresp\u00f8rgsler til hver data pakke reelt hente de manglende n\u00f8gler og kigge efter data i MySQL. Om ClickHouse kan jeg stadig sikre mig, at \u2013 ja, det stopper ikke, men jeg vil ikke tale om andre systemer.<\/p>\n<p><\/p>\n<p>Og som et bonus er det, at tabellerne \u2013 det er en meget simpel m\u00e5de at opdatere data i ClickHouse bagud i tiden. Det vil sige, hvis du har en rapport om reklamekampagner, og brugeren blot \u00e6ndrer reklamekampagnen, vil disse data ogs\u00e5 \u00e6ndres i alle gamle data og rapporter. Hvis vi skriver r\u00e6kker direkte til tabellen, vil det v\u00e6re umuligt at opdatere dem. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/a5a2919d6be7d00c0ad5875b9a8f0f31.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En anden metode, n\u00e5r du ikke ved, hvor du skal hente identifikatorerne til dine r\u00e6kker. Du kan bare hash'e dem. Og den simpleste mulighed \u2013 det er at tage en 64-bit hash. <\/p>\n<p><\/p>\n<p>Det eneste problem er, at hvis hashen er 64-bit, vil der n\u00e6sten helt sikkert v\u00e6re kollisioner. For hvis der er en milliard r\u00e6kker, bliver sandsynligheden m\u00e6rkbar. <\/p>\n<p><\/p>\n<p>Og det ville ikke v\u00e6re s\u00e6rlig godt at hash'e navne p\u00e5 reklamekampagner p\u00e5 den m\u00e5de. Hvis reklamekampagnerne fra forskellige virksomheder bliver blandet sammen, s\u00e5 vil der ske noget uforst\u00e5eligt. <\/p>\n<p><\/p>\n<p>Der er et simpelt trick. Selvom det ikke er s\u00e6rlig velegnet til alvorlige data, hvis du har noget, der ikke er alt for vigtigt, s\u00e5 tilf\u00f8j blot klientens ID til ordbogsn\u00f8glen. P\u00e5 den m\u00e5de vil du f\u00e5 kollisioner, men kun inden for en enkelt klient. Denne metode anvender vi til linkkortet i Yandex.Metrica. Vi har urls der, hvor vi gemmer hasher. Og vi ved, at der bestemt forekommer kollisioner. Men n\u00e5r siden vises, er chancen for, at der p\u00e5 en enkelt side er nogen urls, der overlapper for en bruger, s\u00e5 h\u00f8je, at det kan ignoreres. <\/p>\n<p><\/p>\n<p>Som bonus \u2013 til mange operationer er det tilstr\u00e6kkeligt at have hasherne, s\u00e5 selve strenge ikke beh\u00f8ver at blive gemt nogen steder. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/abbb73aaba29d10e3b7e7650bf68e6a6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Et andet eksempel er, hvis strenge er korte, s\u00e5som dom\u00e6ner. De kan gemmes, som de er. For eksempel, browserens sprog ru \u2013 2 byte. Jeg er selvf\u00f8lgelig meget ked af hver byte, men beh\u00f8ver ikke bekymre dig, 2 byte er ikke v\u00e6rd at spare p\u00e5. Gem dem, som de er, uden at t\u00e6nke mere over det. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/901eaed0029da6ea59630b57ccf80c25.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En anden situation er, n\u00e5r der er mange strenge, og der er meget unikt indhold, og antallet af unikke nok er ubegribelig stort. Et typisk eksempel er s\u00f8gefrase eller urls. S\u00f8gefraser, herunder dem med stavefejl. Lad os se, hvor mange unikke s\u00f8gefraser der er p\u00e5 en dag. Det viser sig, at de n\u00e6sten udg\u00f8r halvdelen af alle h\u00e6ndelser. I dette tilf\u00e6lde kan du t\u00e6nke, at dataene skal normaliseres, identificere IDs og gemme dem i en separat tabel. Men s\u00e5dan skal det ikke g\u00f8res. Gem bare disse strenge, som de er. <\/p>\n<p><\/p>\n<p>Bedre \u2013 find ikke p\u00e5 noget, for hvis de gemmes separat, skal der laves en join. Og denne join \u2013 i bedste fald vil det indeb\u00e6re tilf\u00e6ldig adgang til hukommelsen, hvis det kan v\u00e6re i hukommelsen. Hvis ikke, vil der v\u00e6re problemer. <\/p>\n<p><\/p>\n<p>Og hvis dataene gemmes in place, s\u00e5 bliver de bare l\u00e6st i den rigtige r\u00e6kkef\u00f8lge fra filsystemet, og s\u00e5 er alt, som det skal v\u00e6re.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/15f1d632083def16ccbc939579c1cf6b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hvis du har urls eller en anden kompleks lang streng, s\u00e5 b\u00f8r du overveje at beregne en eller anden opsummering p\u00e5 forh\u00e5nd og gemme den i en separat kolonne. <\/p>\n<p><\/p>\n<p>For urls kan du for eksempel gemme dom\u00e6net separat. Og hvis du faktisk har brug for dom\u00e6net, s\u00e5 kan du blot bruge denne kolonne; urls vil ligge der, og du skal endda ikke r\u00f8re dem. <\/p>\n<p><\/p>\n<p>Lad os se, hvilken forskel der opst\u00e5r. I ClickHouse findes der en specialiseret funktion, der beregner dom\u00e6net. Den er meget hurtig, og vi har optimeret den. Og, for at v\u00e6re \u00e6rlig, overholder den ikke engang RFC, men den beregner alligevel alt, hvad vi har brug for. <\/p>\n<p><\/p>\n<p>I det ene tilf\u00e6lde vil vi blot udtr\u00e6kke URL'er og beregne dom\u00e6net. Det tager 166 millisekunder. Men hvis vi bruger et f\u00e6rdigt dom\u00e6ne, tager det kun 67 millisekunder, hvilket er n\u00e6sten tre gange hurtigere. Og hurtigere ikke fordi vi skal foretage nogle beregninger, men fordi vi l\u00e6ser mindre data. <\/p>\n<p><\/p>\n<p>Af en eller anden grund har \u00e9n af foresp\u00f8rgslerne, der er langsommere, en h\u00f8jere hastighed af gigabyte pr. sekund. Fordi den l\u00e6ser flere gigabytes. Disse data er helt overfl\u00f8dige. Foresp\u00f8rgslen virker hurtigere, men tager l\u00e6ngere tid at udf\u00f8re.<\/p>\n<p><\/p>\n<p>N\u00e5r vi ser p\u00e5 datavolumen p\u00e5 disken, viser det sig, at URL'en fylder 126 megabyte, mens dom\u00e6net kun fylder 5 megabyte. Det er 25 gange mindre. Men foresp\u00f8rgslen udf\u00f8res kun fire gange hurtigere. Det skyldes, at dataene er 'varme'. Hvis de var 'kolde', ville det helt sikkert have v\u00e6ret 25 gange hurtigere p\u00e5 grund af disk I\/O. <\/p>\n<p><\/p>\n<p>Hvis vi vurderer, hvor meget mindre dom\u00e6net er end URL'en, er det omkring fire gange. Men af en eller anden grund fylder dataene p\u00e5 disken 25 gange mindre. Hvorfor? P\u00e5 grund af komprimering. B\u00e5de URL'en og dom\u00e6net komprimeres. Men ofte indeholder URL'en en masse skrald. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/c93d2128a41561ed7abb25d77414bc2d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Og det er selvf\u00f8lgelig vigtigt at bruge de rigtige datatyper, der er specielt designet til de n\u00f8dvendige v\u00e6rdier eller passer til dem. Hvis du bruger IPv4, skal du gemme det som UInt32*. Hvis det er IPv6, s\u00e5 FixedString(16), fordi en IPv6-adresse er 128 bit, s\u00e5 gem det i bin\u00e6rt format. <\/p>\n<p><\/p>\n<p>Hvad g\u00f8r man, hvis du nogle gange har IPv4-adresser og nogle gange IPv6? Ja, du kan gemme begge. En kolonne til IPv4, en anden til IPv6. Selvf\u00f8lgelig er der en mulighed for at vise IPv4 som IPv6. Det vil ogs\u00e5 fungere, men hvis du ofte har brug for IPv4-adressen i dine foresp\u00f8rgsler, er det en god id\u00e9 at placere den i en separat kolonne. <\/p>\n<p><\/p>\n<p>* nu er der i ClickHouse separate datatyper for IPv4 og IPv6, der gemmer data lige s\u00e5 effektivt som tal, men pr\u00e6senterer dem lige s\u00e5 praktisk som strenge.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/d7d6342ebd6b8b4f3526b3cd8a06cf26.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Det er ogs\u00e5 vigtigt at bem\u00e6rke, at det er en god id\u00e9 at forbehandle dataene p\u00e5 forh\u00e5nd. For eksempel, hvis du modtager nogle r\u00e5 logs. Og m\u00e5ske er det bedre ikke straks at smide dem ind i ClickHouse, selvom det virker fristende at lade v\u00e6re, og s\u00e5 fungerer alt. Men det er stadig en god id\u00e9 at lave de beregninger, der er mulige.<\/p>\n<p><\/p>\n<p>For eksempel, browser-versionen. I en n\u00e6rliggende afdeling, som jeg ikke vil n\u00e6vne, opbevares versionen af browseren s\u00e5ledes, alts\u00e5 som en streng: 12.3. Og derefter, for at lave en rapport, tager de denne streng og deler den op i et array, og s\u00e5 p\u00e5 det f\u00f8rste element i arrayet. Naturligvis resulterer det i langsommelighed. Jeg spurgte, hvorfor de g\u00f8r s\u00e5dan. De svarede, at de ikke kan lide for tidlig optimering. Men jeg kan ikke lide for tidlig pessimisering.<\/p>\n<p><\/p>\n<p>S\u00e5 i dette tilf\u00e6lde vil det v\u00e6re bedre at opdele i 4 kolonner. Her skal du ikke v\u00e6re bange, fordi det er ClickHouse. ClickHouse er en kolonnedatabase. Og jo flere pr\u00e6cise sm\u00e5 kolonner, jo bedre. Hvis der er 5 BrowserVersion, s\u00e5 lav 5 kolonner. Det er helt normalt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/f9a67221bf8508933d7bd336b16f9e04.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Lad os nu se p\u00e5, hvad der skal g\u00f8res, hvis du har mange meget lange strenge, meget lange arrays. De skal overhovedet ikke lagres i ClickHouse. I stedet kan du kun gemme en eller anden identifikator i ClickHouse. S\u00e5 send de lange strenge ind i et andet system. <\/p>\n<p><\/p>\n<p>For eksempel, i en af vores analytiske tjenester har vi nogle parametre for begivenheder. Og hvis der kommer mange parametre til begivenhederne, gemmer vi bare de f\u00f8rste 512, der kommer forbi. Fordi 512 \u2013 det er der ikke noget problem med. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/755271e8788ba4bd638f493bf320c820.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Og hvis du ikke kan beslutte dig for dine datatyper, kan du ogs\u00e5 skrive dataene til ClickHouse, men i en midlertidig tabel af typen Log, der er specifik for midlertidige data. Efter dette kan du analysere, hvordan distributionen af v\u00e6rdierne er, hvad der overhovedet findes, og sammens\u00e6tte de rigtige typer.<\/p>\n<p><\/p>\n<p>* lige nu er der i ClickHouse en datatype, <noindex><a rel=\"nofollow\" href=\"https:\/\/clickhouse.tech\/docs\/en\/sql-reference\/data-types\/lowcardinality\/\">LowCardinality,<\/a><\/noindex> som tillader effektiv opbevaring af strenge med f\u00e6rre ressourcer.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/7e9e53d86a4189783c28ce56a669198c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Lad os nu se p\u00e5 et andet interessant tilf\u00e6lde. Nogle gange fungerer tingene m\u00e6rkeligt for folk. Jeg g\u00e5r ind og ser noget s\u00e5dant. Og det giver straks indtryk af, at det er lavet af en meget erfaren, klog admin, der har stor erfaring med ops\u00e6tning af MySQL version 3.23. <\/p>\n<p><\/p>\n<p>Her ser vi tusinde tabeller, hvor hver indeholder rester fra divisionen af noget, der er uklart, med tusinde. <\/p>\n<p><\/p>\n<p>Generelt respekterer jeg andres erfaringer, og jeg forst\u00e5r, hvilke kvaler de kan have med deres opn\u00e5else. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/3a5e21ef2076966fcc627670485c5b3a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Og \u00e5rsagerne er mere eller mindre forst\u00e5elige. Det er gamle stereotyper, der kan have ophobet sig fra arbejde med andre systemer. For eksempel er der ikke en klynget prim\u00e6r n\u00f8gle i MyISAM-tabeller. En s\u00e5dan tilgang til datadeling kan v\u00e6re et desperat fors\u00f8g p\u00e5 at opn\u00e5 den samme funktionalitet. <\/p>\n<p><\/p>\n<p>En anden \u00e5rsag er, at det er vanskeligt at udf\u00f8re operationer som alter p\u00e5 store tabeller. Alt vil blive blokeret. Selvom dette problem ikke l\u00e6ngere er s\u00e5 alvorligt i de moderne versioner af MySQL. <\/p>\n<p><\/p>\n<p>Eller for eksempel mikroskabeloning, men det vender vi tilbage til lidt senere.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/321b1d9caa8db7aca5b96e08c61d05b5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I ClickHouse skal man ikke g\u00f8re s\u00e5dan, fordi for det f\u00f8rste er den prim\u00e6re n\u00f8gle klynget, og dataene er organiseret efter den prim\u00e6re n\u00f8gle. <\/p>\n<p><\/p>\n<p>Og nogle gange sp\u00f8rger folk mig: \u201eHvordan \u00e6ndrer ydeevnen af r\u00e6kkeanmodninger i ClickHouse sig med tabellens st\u00f8rrelse?\u201d. Jeg siger, at den ikke \u00e6ndrer sig. For eksempel har du en tabel med en milliard r\u00e6kker, og du l\u00e6ser en r\u00e6kke p\u00e5 en million. Det fungerer helt fint. Hvis du har en tabel med en trillion r\u00e6kker, og du l\u00e6ser en million r\u00e6kker, vil det n\u00e6sten v\u00e6re det samme. <\/p>\n<p><\/p>\n<p>Og for det andet kr\u00e6ves der ikke nogle ting som manuelle partitioner. Hvis du g\u00e5r ind og ser, hvad der er p\u00e5 filsystemet, vil du se, at tabellen er en ret alvorlig st\u00f8rrelse. Og derinde er der noget, der ligner partitioner. Det vil sige, at ClickHouse g\u00f8r alt for dig, s\u00e5 du slipper for at lide.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/652f3742ad3a44f172d0d7302abd09f6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Alter i ClickHouse er gratis, hvis det er alter add\/drop column. <\/p>\n<p><\/p>\n<p>Og det giver ikke mening at lave sm\u00e5 tabeller, for hvis din tabel har 10 r\u00e6kker eller 10.000 r\u00e6kker, s\u00e5 er det helt ligegyldigt. ClickHouse er et system, der optimerer throughput, ikke latency, s\u00e5 det giver ikke mening at behandle 10 r\u00e6kker. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/144144b4740e9c5daec80c8dadc445f9.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Det er rigtigt at bruge en stor tabel. Slip af med gamle stereotyper, s\u00e5 g\u00e5r det hele godt. <\/p>\n<p><\/p>\n<p>Og som en bonus har vi i den seneste version f\u00e5et muligheden for at lave en vilk\u00e5rlig partitionsn\u00f8gle for at udf\u00f8re forskellige vedligeholdelsesoperationer p\u00e5 individuelle partitioner. <\/p>\n<p><\/p>\n<p>For example, you need many small tables, such as when there's a need to process some intermediate data, you receive chunks, and you need to perform transformations on them before writing to the final table. For this case, there is a wonderful table engine \u2013 StripeLog. It's somewhat like TinyLog, but better. <\/p>\n<p><\/p>\n<p>* there is also <noindex><a rel=\"nofollow\" href=\"https:\/\/clickhouse.tech\/docs\/en\/sql-reference\/table-functions\/input\/\">the table function input<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/d62f0b3d29876c29c6c0ba236b200186.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Another anti-pattern is micro-sharding. For instance, if you need to shard data and you have 5 servers, but tomorrow there will be 6 servers. You might think about how to rebalance this data. Instead of sharding into 5 shards, you split it into 1,000 shards. Then you map each of these micro-shards to a separate server. For example, one server ends up with 200 ClickHouse instances, each on different ports or separate databases. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/3e550ef7e338b84e4394eb9fa4538769.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>But in ClickHouse, this approach doesn't work very well. Because even a single ClickHouse instance tries to use all the available server resources to process one query. For example, if you have a server with 56 CPU cores and you execute a query that takes one second, it will use all 56 cores. If you\u2019ve placed 200 ClickHouse instances on one server, then 10,000 threads will start up. Overall, this will result in very poor performance.<\/p>\n<p><\/p>\n<p>Another reason is that the workload distribution across these instances will be uneven. Some will finish earlier, some later. If all this happened within a single instance, ClickHouse would manage to distribute the data correctly among the threads. <\/p>\n<p><\/p>\n<p>And another reason is that you will have inter-process communication over TCP. Data will need to be serialized and deserialized, and having such a huge number of micro-shards will be inefficient.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/18cacc17d22ae1cb2977c6be74769896.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Another anti-pattern, although it\u2019s hard to call it that, is a large number of pre-aggregations.<\/p>\n<p><\/p>\n<p>In general, pre-aggregation is good. If you had a billion rows, aggregated it down to 1,000 rows, then the query executes instantly. That's great. It's perfectly acceptable. For this, ClickHouse even has a special table type called AggregatingMergeTree, which performs incremental aggregation as data is inserted. <\/p>\n<p><\/p>\n<p>Men der er tilf\u00e6lde, hvor man tror, at vi vil aggregere data p\u00e5 denne m\u00e5de, og s\u00e5 aggregere data yderligere. I en n\u00e6rliggende afdeling, som jeg ikke \u00f8nsker at n\u00e6vne, bruger de SummingMergeTree-tabeller til summation efter prim\u00e6rn\u00f8glen, og som prim\u00e6rn\u00f8gle bruger de omkring 20 forskellige kolonner. Jeg har \u00e6ndret navnene p\u00e5 nogle kolonner for at skjule deres identitet, men det er stort set s\u00e5dan, det foreg\u00e5r.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/54e3a02ab4bbce7c63ded595780ae1f6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Og der opst\u00e5r s\u00e5danne problemer. For det f\u00f8rste mindskes datam\u00e6ngden ikke s\u00e5 meget. For eksempel reduceres den til en tredjedel. En tredjedel ville v\u00e6re en god pris, der g\u00f8r det muligt at opn\u00e5 ubegr\u00e6nsede analytiske muligheder, som opst\u00e5r, hvis dine data ikke er aggregerede. Hvis dataene er aggregerede, f\u00e5r du i stedet for analyse blot en skr\u00e6mmende statistik. <\/p>\n<p><\/p>\n<p>Og hvad er det, der is\u00e6r irriterer? At folk fra den n\u00e6rliggende afdeling g\u00e5r rundt og beder om at tilf\u00f8je endnu en kolonne til prim\u00e6rn\u00f8glen. Det vil sige, at vi har aggregeret dataene p\u00e5 denne m\u00e5de, men nu \u00f8nsker vi lidt mere. Men i ClickHouse er der ingen mulighed for at \u00e6ndre prim\u00e6rn\u00f8glen. Derfor m\u00e5 vi skrive nogle scripts i C++. Og jeg bryder mig ikke om scripts, selvom de er skrevet i C++.<\/p>\n<p><\/p>\n<p>Og hvis man ser p\u00e5, hvorfor ClickHouse blev skabt, s\u00e5 er det ikke-aggregerede data lige pr\u00e6cis det scenarie, som det er f\u00f8dt til. Hvis du bruger ClickHouse til ikke-aggregerede data, s\u00e5 g\u00f8r du det rigtigt. Hvis du aggregerer, s\u00e5 er det nogle gange tilgiveligt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/09fafd4c8a3ea8c22e586cb7a5cf6564.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En anden interessant situation er foresp\u00f8rgsler i en uendelig l\u00f8kke. Nogle gange logger jeg ind p\u00e5 en produktionsserver og ser p\u00e5 processlisten. Og hver gang opdager jeg, at der foreg\u00e5r noget forf\u00e6rdeligt. <\/p>\n<p><\/p>\n<p>For eksempel s\u00e5dan her. Her er det klart, at alt kunne v\u00e6re udf\u00f8rt i \u00e9n foresp\u00f8rgsel. Man skal bare skrive url in og listen.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/ae03b659f178962f50e0640614517296.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hvorfor er s\u00e5 mange af s\u00e5danne foresp\u00f8rgsler i en uendelig l\u00f8kke d\u00e5rligt? Hvis indekset ikke bruges, vil du have mange gennemgange af de samme data. Men hvis indekset bruges, for eksempel, hvis du har en prim\u00e6rn\u00f8gle p\u00e5 ru, og du skriver url = noget der. Og du tror, at der pr\u00e6cist vil blive l\u00e6st \u00e9t url fra tabellen, s\u00e5 vil alt v\u00e6re i orden. Men det er det ikke. Fordi ClickHouse h\u00e5ndterer det hele i pakker. <\/p>\n<p><\/p>\n<p>N\u00e5r du skal l\u00e6se et datas\u00e6t, l\u00e6ser du lidt mere, fordi indekset i ClickHouse er sparsommelig. Dette indeks tillader ikke at finde en individuel r\u00e6kke i tabellen, kun et interval af data. Og data komprimeres i blokke. For at l\u00e6se en r\u00e6kke skal du tage en hel blok og dekomprimere den. Og hvis du udf\u00f8rer mange foresp\u00f8rgsler, vil du have mange overlappende foresp\u00f8rgsler, og meget af arbejdet vil blive udf\u00f8rt igen og igen.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/95eef43c5b869f8b145c61ce3c616cfd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Og som en bonus kan det bem\u00e6rkes, at i ClickHouse b\u00f8r du ikke v\u00e6re bange for at sende selv megabytes og endda hundrede megabytes i IN-sektionen. Jeg husker fra vores praksis, at hvis vi sender mange v\u00e6rdier i IN-sektionen i MySQL, for eksempel sender 100 megabytes af nogle tal, s\u00e5 bruger MySQL 10 gigabytes hukommelse og intet mere sker, alt fungerer d\u00e5rligt. <\/p>\n<p><\/p>\n<p>Og det andet er, at i ClickHouse, hvis dine foresp\u00f8rgsler bruger indekset, s\u00e5 er det altid ikke langsommere end en fuld scanning, dvs. hvis n\u00e6sten hele tabellen skal l\u00e6ses, k\u00f8rer det sekventielt og l\u00e6ser hele tabellen. Generelt klarer det sig selv.<\/p>\n<p><\/p>\n<p>Men der er alligevel nogle vanskeligheder. For eksempel, at IN med en underforesp\u00f8rgsel ikke bruger indekset. Men det er vores problem, og vi skal rette det. Der er ikke noget fundamentalt her. Vi skal fikse det. <\/p>\n<p><\/p>\n<p>Og en anden interessant ting er, at hvis du har en meget lang foresp\u00f8rgsel og distribueret behandling af foresp\u00f8rgsler sker, s\u00e5 vil denne meget lange foresp\u00f8rgsel blive sendt til hver server uden komprimering. For eksempel, 100 megabytes og 500 servere. Og derfor vil der blive overf\u00f8rt 50 gigabytes over netv\u00e6rket. Det vil blive sendt og derefter udf\u00f8rt med succes.<\/p>\n<p><\/p>\n<p>* allerede bruger; alt er blevet fikset, som lovet.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/5fcde9bf04fff0645be2530daa12743f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Og en ret almindelig situation er, hvis foresp\u00f8rgsler kommer fra API'et. For eksempel, hvis du har lavet en service. Og hvis din service er n\u00f8dvendig for nogen, s\u00e5 \u00e5bnede du API'et, og bogstaveligt talt to dage senere ser du, at der sker noget uforst\u00e5eligt. Alt er overbelastet, og der kommer nogle skr\u00e6kkelige foresp\u00f8rgsler, som aldrig burde have v\u00e6ret. <\/p>\n<p><\/p>\n<p>Og der er \u00e9n l\u00f8sning her. Hvis du har \u00e5bnet API'et, s\u00e5 bliver du n\u00f8dt til at begr\u00e6nse det. For eksempel indf\u00f8re kvoter. Der er ingen andre fornuftige muligheder. Ellers vil de straks skrive et script, og der vil v\u00e6re problemer. <\/p>\n<p><\/p>\n<p>Og i ClickHouse er der en s\u00e6rlig mulighed \u2013 det er kvoteregnskabet. Man kan faktisk overf\u00f8re sin egen kvoten\u00f8gle, som for eksempel er en intern brugeridentifikator. Og kvoterne vil blive beregnet uafh\u00e6ngigt for hver af dem. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/532438d0f116919e62f04e32ebbd3c45.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nu en anden interessant ting. Det er manuel replikation. <\/p>\n<p><\/p>\n<p>Jeg kender mange tilf\u00e6lde, hvor folk, p\u00e5 trods af at ClickHouse har indbygget support til replikation, alligevel replikere ClickHouse manuelt.<\/p>\n<p><\/p>\n<p>Hvad g\u00e5r princippet ud p\u00e5? Du har en databehandlingspipeline, som arbejder uafh\u00e6ngigt, for eksempel i forskellige datacentre. Du skriver de samme data p\u00e5 samme m\u00e5de ind i ClickHouse. Sandheden er, at praksis viser, at dataene stadig vil afvige p\u00e5 grund af nogle specielle forhold i din kode. Jeg h\u00e5ber, at dette ikke er tilf\u00e6ldet for din. <\/p>\n<p><\/p>\n<p>Og af og til bliver du stadig n\u00f8dt til at synkronisere manuelt. For eksempel laver administratorer rsync en gang om m\u00e5neden.<\/p>\n<p><\/p>\n<p>Det er faktisk meget lettere at bruge den indbyggede replikation i ClickHouse. Men der kan v\u00e6re nogle kontraindikationer, fordi det kr\u00e6ver ZooKeeper. Jeg vil ikke sige noget d\u00e5rligt om ZooKeeper, i princippet er systemet fungerende, men nogle mennesker bruger det ikke p\u00e5 grund af en frygt for Java, fordi ClickHouse er et glimrende system skrevet i C++, som man kan bruge uden problemer. Og ZooKeeper er p\u00e5 Java. Det kan endda v\u00e6re lidt fristende at lade v\u00e6re, men hvis det er tilf\u00e6ldet, kan du bruge manuel replikation. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/3b5b68996daef6b8920f067b189f25e0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>ClickHouse er et praktisk system. Det tager hensyn til dine behov. Hvis du har manuel replikation, kan du oprette en Distributed tabel, der ser p\u00e5 dine manuelle replikater og selv udf\u00f8rer failover imellem dem. Og der er endda en s\u00e6rlig mulighed, der g\u00f8r det muligt at undg\u00e5 flapper, selv hvis dine replikater systematisk divergerer.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/70f6630f8b14756163923a7db8dd7391.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Der kan opst\u00e5 problemer, hvis du bruger primitive table engines. ClickHouse er som en byggeklods, der har en masse forskellige tabelmotorer. For alle alvorlige tilf\u00e6lde, som det fremg\u00e5r af dokumentationen, b\u00f8r du bruge tabeller fra MergeTree-familien. Alle andre er kun til s\u00e6rlige tilf\u00e6lde eller til test.<\/p>\n<p><\/p>\n<p>I en MergeTree-tabel er det ikke n\u00f8dvendigt, at du har en specifik dato og tid. Du kan stadig bruge det. Hvis der ikke er nogen dato og tid, s\u00e5 skriv, at default er 2000. Det vil fungere og kr\u00e6ver ikke ressourcer. <\/p>\n<p><\/p>\n<p>I den nye version af serveren kan du endda angive, at du vil have brugerdefineret partitionering uden partitionstast. Det vil v\u00e6re det samme. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/6d4046d11afdd1e5962d49a1612b666a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>P\u00e5 den anden side kan du bruge primitive tabelmotorer. For eksempel kan du indl\u00e6se data \u00e9n gang og se, vende og slette. Du kan bruge Log.<\/p>\n<p><\/p>\n<p>Eller opbevaring af sm\u00e5 m\u00e6ngder til midlertidig behandling \u2013 det er StripeLog eller TinyLog.<\/p>\n<p><\/p>\n<p>Memory kan bruges, hvis du har sm\u00e5 datam\u00e6ngder, og bare vil dreje noget i hukommelsen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/8a3d4e0e3a8c26dd3a2b2f64123e2bf9.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>ClickHouse elsker ikke meget normaliserede data. <\/p>\n<p><\/p>\n<p>Her er et typisk eksempel. Det er et stort antal URL'er. Du har lagt dem i en n\u00e6rliggende tabel. Og s\u00e5 besluttede du at lave JOIN med dem, men det vil normalt ikke fungere, fordi ClickHouse kun underst\u00f8tter Hash JOIN. Hvis der ikke er nok hukommelse til mange data, som skal forbindes, s\u00e5 kan JOIN ikke udf\u00f8res*. <\/p>\n<p><\/p>\n<p>Hvis dataene har h\u00f8j kardinalitet, s\u00e5 bekymre dig ikke, opbevar dem i denormaliseret form, URL'er lige p\u00e5 stedet i hovedtabellen. <\/p>\n<p><\/p>\n<p>* men nu er der ogs\u00e5 merge join i ClickHouse, og det fungerer under forhold, hvor de mellemliggende data ikke kan v\u00e6re i hukommelsen. Men det er ineffektivt, og anbefalingen st\u00e5r ved magt.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/e8160a8db17c18d48f810092c55b094c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Her er et par eksempler mere, men jeg er allerede i tvivl om, hvorvidt de er antipatterns eller ej. <\/p>\n<p><\/p>\n<p>ClickHouse har en kendt ulempe. Den kan ikke opdatere*. P\u00e5 en m\u00e5de er det endda godt. Hvis du har nogle vigtige data, for eksempel regnskab, s\u00e5 kan ingen \u00e6ndre dem, fordi der ikke er nogen opdateringer.<\/p>\n<p><\/p>\n<p>* underst\u00f8ttelse af opdateringer og sletninger i batch-tilstand blev for l\u00e6ngst tilf\u00f8jet.<\/p>\n<p><\/p>\n<p>Men der er nogle s\u00e6rlige metoder, der g\u00f8r det muligt at udf\u00f8re opdateringer som om de sker i baggrunden. For eksempel tabeller af typen ReplaceMergeTree. De foretager opdateringer under baggrundsmerges. Du kan tvinge dette med optimize table. Men g\u00f8r det ikke for ofte, fordi det vil medf\u00f8re en fuld omskrivning af partitionen. <\/p>\n<p><\/p>\n<p>Distribution JOIN i ClickHouse \u2013 det h\u00e5ndteres ogs\u00e5 d\u00e5rligt af foresp\u00f8rgselsplanl\u00e6ggeren. <\/p>\n<p><\/p>\n<p>D\u00e5rligt, men nogle gange okay.<\/p>\n<p><\/p>\n<p>Brug af ClickHouse kun for at l\u00e6se data tilbage med select*.<\/p>\n<p><\/p>\n<p>Jeg vil ikke anbefale at bruge ClickHouse til omfattende beregninger. Men det er ikke helt rigtigt, fordi vi allerede er begyndt at tr\u00e6kke os fra denne anbefaling. Vi har for nylig tilf\u00f8jet muligheden for at anvende maskinl\u00e6ringsmodeller i ClickHouse \u2013 Catboost. Og det bekymrer mig, fordi jeg t\u00e6nker: \u201eHvilken r\u00e6dsel. Hvor mange cykler pr. byte bliver det!\u201c. Jeg har virkelig ondt af at bruge cykler p\u00e5 bytes. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Effektiv brug af ClickHouse. Alexey Milovidov (Yandex)\" src=\"\/wp-content\/uploads\/2020\/08\/f686d5d352ccb444cd06e2ae68897137.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Men frygt ikke, installer ClickHouse, alt vil v\u00e6re godt. Hvis der opst\u00e5r problemer, har vi et f\u00e6llesskab. Forresten, f\u00e6llesskabet \u2013 det er jer. Og hvis I har nogen problemer, kan I i det mindste komme ind i vores chat, og jeg h\u00e5ber, at I f\u00e5r hj\u00e6lp. <\/p>\n<p><\/p>\n<p>Sp\u00f8rgsm\u00e5l<\/p>\n<p><\/p>\n<p><em>Tak for pr\u00e6sentationen! Hvor kan man klage over, at ClickHouse falder?<\/em><\/p>\n<p><\/p>\n<p>I kan klage til mig personligt lige nu. <\/p>\n<p><\/p>\n<p><em>Jeg er for nylig begyndt at bruge ClickHouse. Jeg nedbr\u00f8d straks cli-interfacet.<\/em><\/p>\n<p><\/p>\n<p>Du er heldig. <\/p>\n<p><\/p>\n<p><em>Kort efter nedbr\u00f8d jeg serveren med et lille select.<\/em><\/p>\n<p><\/p>\n<p>Du har talent. <\/p>\n<p><\/p>\n<p><em>Jeg \u00e5bnede en fejl p\u00e5 GitHub, men den blev ignoreret.<\/em> <\/p>\n<p><\/p>\n<p>Lad os se. <\/p>\n<p><\/p>\n<p><em>Alexey narrede mig til pr\u00e6sentationen og lovede at fort\u00e6lle, hvordan du komprimerer data indeni.<\/em><\/p>\n<p><\/p>\n<p>Meget enkelt. <\/p>\n<p><\/p>\n<p><em>Det fandt jeg ud af i g\u00e5r. Mere konkret.<\/em> <\/p>\n<p><\/p>\n<p>Der er ingen forf\u00e6rdelige tricks. Det er blot blokkomprimering. Som standard bruges LZ4, man kan aktivere ZSTD*. Blokke fra 64 kilobyte til 1 megabyte.<\/p>\n<p><\/p>\n<p>* der er ogs\u00e5 st\u00f8tte til specialiserede komprimeringscodecs, som kan bruges i k\u00e6de med andre algoritmer.<\/p>\n<p><\/p>\n<p><em>Er der bare r\u00e5 data i blokkene?<\/em><\/p>\n<p><\/p>\n<p>Ikke helt r\u00e5. Der er arrays. Hvis du har en numerisk kolonne, s\u00e5 er der tal, der er lagt t\u00e6t i et array. <\/p>\n<p><\/p>\n<p><em>Forst\u00e5et.<\/em> <\/p>\n<p><\/p>\n<p><em>Alexey, eksemplet med uniqExact over ip-adresser, dvs. det, at uniqExact tager l\u00e6ngere tid over strenge end over tal og s\u00e5 videre. Hvad hvis vi bruger et trick og caster i l\u00e6se\u00f8jeblikket? Dvs. du n\u00e6vnte, at det n\u00e6sten ikke adskiller sig p\u00e5 disken. Hvis vi l\u00e6ser strenge fra disken og caster, vil aggregaterne s\u00e5 v\u00e6re hurtigere hos os eller ej? Eller vil vi alligevel ikke m\u00e6rke nogen betydelig gevinst her? Jeg tror, du testede det, men n\u00e6vnte det ikke i benchmarket.<\/em> <\/p>\n<p><\/p>\n<p>Jeg tror, at det vil v\u00e6re langsommere end uden casting. I s\u00e5 fald skal IP-adressen parses fra strengen. Vi har selvf\u00f8lgelig ogs\u00e5 optimeret parsing af IP-adresser i ClickHouse. Vi har virkelig gjort vores bedste, men der har I tallene skrevet i ti tusinders format. Meget uhensigtsm\u00e6ssigt. P\u00e5 den anden side vil funktionen uniqExact ogs\u00e5 arbejde langsommere p\u00e5 strenge, ikke kun fordi det er strenge, men ogs\u00e5 fordi der v\u00e6lges en anden specialisering af algoritmen. Strenge behandles simpelthen anderledes.<\/p>\n<p><\/p>\n<p><em>Hvad hvis vi tager en mere primitiv datatype? For eksempel, vi skrev user id, som vi har in, vi skrev det som en streng, og s\u00e5 castede vi \u2014 vil det v\u00e6re sjovere eller ej?<\/em><\/p>\n<p><\/p>\n<p>Jeg er i tvivl. Jeg tror, det vil v\u00e6re endda mere trist, fordi parsing af tal er en alvorlig udfordring. Jeg mener, at en af jeres kolleger endda havde et opl\u00e6g om, hvor sv\u00e6rt det er at parse tal i ti tusinders format, men m\u00e5ske ikke. <\/p>\n<p><\/p>\n<p><em>Alexey, mange tak for opl\u00e6gget! Og ogs\u00e5 mange tak for ClickHouse! Jeg har et sp\u00f8rgsm\u00e5l vedr\u00f8rende funktioner. Er der planer om en funktion til delvis opdatering af ordb\u00f8ger?<\/em><\/p>\n<p><\/p>\n<p>Alts\u00e5, en delvis genindl\u00e6sning?<\/p>\n<p><\/p>\n<p><em>Ja ja. En mulighed for at angive et MySQL-felt, alts\u00e5 at opdatere efter, s\u00e5 kun disse data bliver indl\u00e6st, hvis ordbogen er meget stor.<\/em><\/p>\n<p><\/p>\n<p>Meget interessant funktion. Og jeg mener, at en eller anden person har foresl\u00e5et det i vores chat. M\u00e5ske var det endda dig. <\/p>\n<p><\/p>\n<p><em>Jeg tror ikke, det var mig.<\/em><\/p>\n<p><\/p>\n<p>Fint, nu ser det ud til, at der er to foresp\u00f8rgsler. Og vi kan begynde at arbejde i ro og mag. Men jeg vil straks advare jer om, at denne funktion er ret simpel at implementere. Alts\u00e5, i princippet skal man bare skrive versionsnummeret i tabellen og derefter skrive: version mindre end s\u00e5- og s\u00e5 mange. Og det betyder, at vi sandsynligvis vil foresl\u00e5 det til entusiaster. Er du en entusiast? <\/p>\n<p><\/p>\n<p><em>Ja, men desv\u00e6rre ikke i C++.<\/em><\/p>\n<p><\/p>\n<p>Kan dine kolleger skrive i C++? <\/p>\n<p><\/p>\n<p><em>Jeg finder nogen.<\/em><\/p>\n<p><\/p>\n<p>Fremragende*.<\/p>\n<p><\/p>\n<p>* muligheden blev tilf\u00f8jet to m\u00e5neder efter opl\u00e6gget \u2014 den blev udviklet af sp\u00f8rgsm\u00e5lets forfatter og sendt sin <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/ClickHouse\/ClickHouse\/pull\/1771\">pull request<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><em>Tak!<\/em><\/p>\n<p><\/p>\n<p><em>Hej! Tak for pr\u00e6sentationen! Du n\u00e6vnte, at ClickHouse bruger alle tilg\u00e6ngelige ressourcer meget effektivt. Og foredragsholderen ved siden af, fra Luxoft, fortalte om sin l\u00f8sning til Post Rusland. Han sagde, at de virkelig kunne lide ClickHouse, men de brugte det ikke i stedet for deres hovedkonkurrent, fordi det tog hele CPU'en. Og de kunne ikke f\u00e5 det til at passe ind i deres arkitektur, i deres ZooKeeper med Docker. Er der en mulighed for at begr\u00e6nse ClickHouse, s\u00e5 det ikke bruger alt, hvad det kan f\u00e5 fat i?<\/em><\/p>\n<p><\/p>\n<p>Ja, det kan man, og det er meget nemt. Hvis du \u00f8nsker at bruge f\u00e6rre kerner, s\u00e5 skriv bare <code>set max_threads = 1<\/code>. Og s\u00e5 vil det kun udf\u00f8re foresp\u00f8rgsler p\u00e5 en enkelt kerne. Desuden kan man angive denne indstilling forskelligt for forskellige brugere. S\u00e5 der er ingen problemer. Og sig til kollegerne fra Luxoft, at det ikke er godt, at de ikke fandt denne indstilling i dokumentationen. <\/p>\n<p><\/p>\n<p><em>Alexey, hej! Jeg ville lige h\u00f8re om et sp\u00f8rgsm\u00e5l. Det er ikke f\u00f8rste gang, jeg h\u00f8rer, at mange begynder at bruge ClickHouse som lager til logfiler. I pr\u00e6sentationen sagde du, at man ikke skulle g\u00f8re dette, dvs. man skal ikke gemme lange strenge. Hvad er din holdning til det?<\/em><\/p>\n<p><\/p>\n<p>For det f\u00f8rste er logfiler som regel ikke lange strenge. Der kan dog v\u00e6re undtagelser. For eksempel kan en service skrevet i Java kaste undtagelser, som logges. Og det kan ske i en uendelig l\u00f8kke, hvilket fylder pladsen p\u00e5 harddisken. L\u00f8sningen er meget enkel. Hvis strenge er meget lange, s\u00e5 sk\u00e6r dem. Hvad betyder lange? Dosis af kilobyte er d\u00e5rligt*.<\/p>\n<p><\/p>\n<p>* I de nyeste versioner af ClickHouse er &quot;adaptiv granuleret indeks&quot; inkluderet, hvilket stort set l\u00f8ser problemet med opbevaring af lange strenge.<\/p>\n<p><\/p>\n<p><em>Og er kilobyte normalt?<\/em><\/p>\n<p><\/p>\n<p>Normalt. <\/p>\n<p><\/p>\n<p><em>Hej! Tak for pr\u00e6sentationen! Jeg har allerede spurgt om dette i chatten, men jeg kan ikke huske, om jeg fik svar. Er der planer om at udvide WITH-sektionen p\u00e5 en m\u00e5de, der ligner CTE?<\/em><\/p>\n<p><\/p>\n<p>Ikke lige nu. WITH-sektionen er noget, vi betragter som lidt uformel. Den er som en lille funktion.<\/p>\n<p><\/p>\n<p><em>Jeg forst\u00e5r. Tak!<\/em><\/p>\n<p><\/p>\n<p><em>Tak for pr\u00e6sentationen! Meget interessant! Et globalt sp\u00f8rgsm\u00e5l. Er der planer om at lave en \u00e6ndring til datal\u00e6sning i form af nogen slags stub?<\/em><\/p>\n<p><\/p>\n<p>Det vil helt sikkert ske. Det er vores h\u00f8jeste prioritet i r\u00e6kken. Vi har i \u00f8jeblikket aktivt overvejet, hvordan vi g\u00f8r alt rigtigt. Og det er tid til at begynde at trykke p\u00e5 tasterne*.<\/p>\n<p><\/p>\n<p>* trykkede p\u00e5 tasterne p\u00e5 tastaturet, og s\u00e5 gjorde vi det hele.<\/p>\n<p><\/p>\n<p><em>Vil dette p\u00e5virke systemets ydeevne p\u00e5 nogen m\u00e5de, eller ej? Bliver inds\u00e6ttelsen lige s\u00e5 hurtig som nu?<\/em><\/p>\n<p><\/p>\n<p>Det er muligt, at deletes og updates i sig selv vil v\u00e6re meget tunge, men det vil ikke p\u00e5virke ydeevnen af selects og inds\u00e6ttelser.<\/p>\n<p><\/p>\n<p><em>Og et lille sp\u00f8rgsm\u00e5l til. P\u00e5 pr\u00e6sentationen n\u00e6vnte du prim\u00e6rn\u00f8glen. S\u00e5 vi har partitionering, som som standard er m\u00e5nedlig, er det korrekt? Og n\u00e5r vi angiver et datointerval, der falder inden for en m\u00e5ned, bliver kun denne partition l\u00e6st, ikke?<\/em><\/p>\n<p><\/p>\n<p>Ja.<\/p>\n<p><\/p>\n<p><em>Et s\u00e5dant sp\u00f8rgsm\u00e5l. Hvis vi ikke kan udpege en prim\u00e6rn\u00f8gle, er det s\u00e5 korrekt at lave den efter feltet \"Dato\" for at minimere omstruktureringen af disse data i baggrunden, s\u00e5 de bliver mere ordentligt arrangeret? Hvis du ikke har intervalforesp\u00f8rgsler, og du ikke engang kan v\u00e6lge nogen prim\u00e6rn\u00f8gle, skal vi s\u00e5 overveje at inkludere datoen i prim\u00e6rn\u00f8glen?<\/em><\/p>\n<p><\/p>\n<p>Ja.<\/p>\n<p><\/p>\n<p>M\u00e5ske giver det mening at inkludere et felt i prim\u00e6rn\u00f8glen, hvor data vil blive bedre komprimeret, hvis de er sorteret efter dette felt. For eksempel, identifikatoren for brugeren. En bruger bes\u00f8ger for eksempel den samme hjemmeside. I dette tilf\u00e6lde l\u00e6gger du bruger-id og tidspunkt. Og s\u00e5 vil dine data blive bedre komprimeret. Hvad ang\u00e5r datoen, hvis du virkelig ikke har og aldrig har intervalforesp\u00f8rgsler efter datoer, s\u00e5 kan du undlade at inkludere datoen i prim\u00e6rn\u00f8glen. <\/p>\n<p><\/p>\n<p><em>Okay, mange tak!<\/em><\/p>\n<p>Kilde: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/514840\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0422\u0430\u043a \u043a\u0430\u043a ClickHouse \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439, \u043f\u0440\u0438 \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0432\u0430\u0436\u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0435\u0433\u043e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b. \u0412 \u044d\u0442\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u0410\u043b\u0435\u043a\u0441\u0435\u0439 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u0442 \u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u0445 \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 ClickHouse, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043d\u0435\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435. \u041d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u0438\u0437 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0438 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e, \u043a\u0430\u043a \u0432\u044b\u0431\u043e\u0440 \u0442\u043e\u0439 \u0438\u043b\u0438 \u0438\u043d\u043e\u0439 \u0441\u0445\u0435\u043c\u044b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0436\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u043f\u043e\u0440\u044f\u0434\u043a\u0438. \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":91439,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-91438","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/effektivnoe-ispolzovanie-clickhouse-aleksej-milovidov-yandeks\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 ClickHouse. \u0410\u043b\u0435\u043a\u0441\u0435\u0439 \u041c\u0438\u043b\u043e\u0432\u0438\u0434\u043e\u0432 (\u042f\u043d\u0434\u0435\u043a\u0441) | ProHoster\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/effektivnoe-ispolzovanie-clickhouse-aleksej-milovidov-yandeks\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-08-13T17:42:36+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-08-13T17:42:36+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Effektiv brug af ClickHouse. Alexey Milovidov (Yandex) | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/effektivnoe-ispolzovanie-clickhouse-aleksej-milovidov-yandeks","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 ClickHouse. \u0410\u043b\u0435\u043a\u0441\u0435\u0439 \u041c\u0438\u043b\u043e\u0432\u0438\u0434\u043e\u0432 (\u042f\u043d\u0434\u0435\u043a\u0441) | ProHoster","og:url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/effektivnoe-ispolzovanie-clickhouse-aleksej-milovidov-yandeks","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-08-13T17:42:36+00:00","article:modified_time":"2020-08-13T17:42:36+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"91438","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 12:27:23","updated":"2022-09-28 17:25:41","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/91438","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=91438"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/91438\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media\/91439"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=91438"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=91438"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=91438"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}