ClickHouse for avancerede brugere i spørgsmål og svar

I april samledes Avito-ingeniører til onlinesamlinger med Alexey Milovidov, hovedudvikleren af ​​ClickHouse, og Kirill Shvakov, en Golang-udvikler fra Integros. Vi diskuterede, hvordan vi bruger databasestyringssystemet, og hvilke vanskeligheder vi står over for.

På baggrund af mødet har vi sammensat en artikel med eksperternes svar på vores og publikums spørgsmål om sikkerhedskopiering, omfordeling af data, eksterne ordbøger, Golang-driveren og ClickHouse versionsopdateringer. Det kan være nyttigt for udviklere, der allerede arbejder aktivt med Yandex DBMS og er interesserede i dets nutid og fremtid. Aleksey Milovidovs svar som standard, medmindre andet er angivet.

Pas på, der er meget tekst under snittet. Vi håber, at indholdet med spørgsmål vil hjælpe dig med at navigere.

ClickHouse for avancerede brugere i spørgsmål og svar

Indhold

Hvis du ikke ønsker at læse teksten, kan du se optagelsen af ​​sammenkomster på vores youtube kanal. Tidsstempler er i den første kommentar under videoen.

ClickHouse opdateres konstant, men det er vores data ikke. Hvad skal man gøre med det?

ClickHouse bliver løbende opdateret, og vores data, der blev behandlet af optimize final, opdateres ikke og ligger i en backup.

Antag, at vi havde en form for problem, og dataene gik tabt. Vi besluttede at gendanne, og det viste sig, at de gamle partitioner, der bliver gemt på backup-serverne, er meget forskellige fra den version af ClickHouse, der bruges i øjeblikket. Hvad skal man gøre i en sådan situation, og er det muligt?

Situationen, hvor du gendannede data fra en sikkerhedskopi i det gamle format, men på den nye version er de ikke forbundet, er umulig. Vi sørger for, at dataformatet i ClickHouse altid forbliver bagudkompatibelt. Dette er meget vigtigere end bagudkompatibilitet i funktionalitet, hvis adfærden for en sjældent brugt funktion har ændret sig. De data, der er gemt på disken, skal den nye version af ClickHouse altid kunne læse. Dette er loven.

Hvad er den aktuelle bedste praksis for sikkerhedskopiering af data fra ClickHouse?

Hvordan laver man sikkerhedskopier under hensyntagen til, at vi har optimeret endelige operationer, en enorm database med terabyte og data, der er opdateret, lad os sige, for de sidste tre dage, og så sker der ingen procedurer med dem?

Vi kan sammensætte vores egen løsning og skrive på hovedet: Saml disse sikkerhedskopier på sådan og sådan måde. Måske behøver du ikke krykke noget, og cyklen er opfundet for længe siden?

Lad os starte med de bedste fremgangsmåder. Mine kolleger råder altid til som svar på spørgsmål om sikkerhedskopier for at minde dem om Yandex.Cloud-tjenesten, hvor denne opgave allerede er løst. Så brug det hvis muligt.

Der er ingen komplet løsning, hundrede procent indbygget i ClickHouse, til sikkerhedskopiering. Der er nogle emner, som du kan bruge. For at få en komplet løsning skal du enten pille lidt manuelt, eller lave indpakninger i form af scripts.

Jeg starter med de enkleste løsninger og slutter af med de mest sofistikerede, afhængigt af mængden af ​​data og klyngestørrelsen. Jo større klyngen er, jo sværere bliver løsningen.

Hvis datatabellen kun fylder nogle få gigabyte, kan sikkerhedskopieringen udføres sådan:

  1. Gem definitionen af ​​tabeller, dvs. metadata − vis opret tabel.
  2. Lav et dump ved hjælp af ClickHouse-klienten − Vælg * fra bordet at arkivere. Som standard vil du modtage en fil i TabSeparated-formatet. Hvis du vil være mere effektiv, kan du bruge Native-formatet.

Hvis mængden af ​​data er større, vil sikkerhedskopieringen tage mere tid og meget plads. Dette kaldes en logisk backup, den er ikke bundet til ClickHouse dataformat. Hvis det er det, så kan du hurtigt tage en sikkerhedskopi og uploade den til MySQL til gendannelse.

Til mere avancerede tilfælde har ClickHouse en indbygget mulighed for at skabe et øjebliksbillede af partitioner i det lokale filsystem. Denne funktion er tilgængelig som en anmodning. ændre bordfrysningspartition. Eller simpelthen ændre bordfrysning er et øjebliksbillede af hele bordet.

Snapshottet vil blive skabt konsistent for én tabel på én shard, det vil sige, at det er umuligt at skabe et konsistent snapshot af hele klyngen på denne måde. Men for de fleste opgaver er der ikke et sådant behov, og det er nok at udføre en anmodning på hvert shard og få et ensartet øjebliksbillede. Det er skabt i form af hardlinks og fylder derfor ikke ekstra. Derefter kopierer du dette snapshot til backupserveren eller til det lager, som du bruger til backup.

Gendannelse af en sådan sikkerhedskopi er ret nemt. Først opretter du tabeller i henhold til de eksisterende tabeldefinitioner. Kopier derefter de gemte partitionssnapshots til Directory-Detached for disse tabeller og kør forespørgslen vedhæfte skillevæg. Denne løsning er ganske velegnet til de mest seriøse mængder data.

Nogle gange har du brug for noget endnu sejere - i tilfælde hvor du har titusinder eller endda hundredvis af terabyte på hver server og hundredvis af servere. Der er en løsning her, som jeg spionerede på fra kolleger fra Yandex.Metrica. Jeg vil ikke anbefale det til alle – læs det og afgør selv, om det er egnet eller ej.

Først skal du oprette flere servere med store diskhylder. Derefter skal du rejse flere ClickHouse-servere på disse servere og konfigurere dem, så de fungerer som en anden replika for de samme shards. Og brug så filsystemet på disse servere eller et eller andet værktøj, der giver dig mulighed for at oprette snapshots. Der er to muligheder her. Den første mulighed er LVM-snapshots, den anden mulighed er ZFS på Linux.

Derefter skal du hver dag lave et snapshot, det vil ligge og optage lidt plads. Naturligvis, hvis dataene ændres, vil mængden af ​​plads stige over tid. Du kan få dette øjebliksbillede til enhver tid og gendanne dataene, sådan en mærkelig beslutning. Derudover skal du stadig begrænse disse replikaer i konfigurationen, så de ikke forsøger at blive ledere.

Vil det være muligt at organisere et kontrolleret efterslæb af replikaer i skakterne?

I år planlægger du at lave skafter i ClickHouse. Vil det være muligt at organisere et kontrolleret efterslæb af replikaer i dem? Vi vil gerne bruge det til at beskytte os mod negative scenarier med ændringer og andre ændringer.

Er det muligt at lave en form for roll back for ændringer? For eksempel, i en eksisterende aksel, tage og sige, at indtil dette øjeblik, anvende ændringerne, og fra dette øjeblik af, stoppe med at anvende ændringerne?

Hvis en kommando kom til vores klynge og brød den, så har vi en betinget replika med en times forsinkelse, hvor vi kan sige, at lad os bruge den i øjeblikket, men vi vil ikke anvende ændringerne i den i de sidste ti minutter?

Til at begynde med om det kontrollerede efterslæb af replikaer. Der var sådan en anmodning fra brugere, og vi oprettede et problem på Github med en anmodning: "Hvis nogen har brug for dette, læg et like, sæt et hjerte." Ingen satsede, og spørgsmålet blev lukket. Du kan dog allerede nu få denne mulighed ved at opsætte ClickHouse. Sandt nok, kun fra version 20.3.

ClickHouse fletter konstant data i baggrunden - flet. Når en fletning foretages, erstattes nogle sæt af datastykker med en større chunk. Samtidig forbliver stykker data, der var før, på disken i nogen tid.

For det første fortsætter de med at blive gemt, så længe der er udvalgte forespørgsler, der bruger dem, for at sikre ikke-blokerende drift. Udvalgte anmodninger læses stille og roligt fra gamle bidder.

For det andet er der også en tidsgrænse - gamle stykker data ligger på disken i otte minutter. Disse otte minutter kan tilpasses og forvandles til en enkelt dag. Dette vil koste diskplads: afhængigt af dataflowet vil det vise sig, at dataene i løbet af den sidste dag ikke kun fordobles, det kan blive fem gange mere. Men i tilfælde af et alvorligt problem, kan du stoppe ClickHouse-serveren og håndtere alt.

Nu er spørgsmålet, hvordan dette beskytter mod ændringer. Det er værd at kigge dybere her, for i ældre versioner af ClickHouse fungerede alteret på en sådan måde, at det simpelthen ændrede brikkerne direkte. Der er et stykke data med nogle filer, og vi gør f.eks. ændre drop kolonne. Så fjernes denne kolonne fysisk fra alle bidder.

Men siden version 20.3 er ændringsmekanismen blevet fuldstændig ændret, og nu er datastykker altid uforanderlige. De ændrer sig overhovedet ikke - alters fungerer nu på nogenlunde samme måde som fusioner. I stedet for at ændre en brik på plads, skaber vi en ny. I den nye chunk bliver filer, der ikke er ændret, til hardlinks, og hvis vi sletter en kolonne, vil den simpelthen mangle i den nye chunk. Det gamle stykke slettes som standard efter otte minutter, og her kan du justere indstillingerne nævnt ovenfor.

Det samme gælder for ændringer som mutationer. Når du gør det ændre slet eller ændre opdatering, det ændrer ikke stykket, men skaber et nyt. Og sletter så den gamle.

Hvad hvis tabellens struktur er ændret?

Hvordan rejser man en backup, der blev lavet med den gamle ordning? Og det andet spørgsmål handler om tilfældet med snapshots og filsystemværktøjer. Er Btrfs egnet her i stedet for ZFS på Linux LVM?

Hvis du gør vedhæfte skillevæg partitioner med en anden struktur, så vil ClickHouse fortælle dig, at dette ikke er muligt. Løsningen er denne. Den første er at oprette en midlertidig tabel af typen MergeTree med den gamle struktur, vedhæfte data der ved hjælp af attach og udstede en ændringsforespørgsel. Derefter kan du enten kopiere eller overføre disse data og vedhæfte igen, eller bruge forespørgslen ændre tabel flytte partition.

Nu er det andet spørgsmål, om det er muligt at bruge Btrfs. For det første, hvis du har LVM, så er LVM-snapshots nok, og filsystemet kan være ext4, det betyder ikke noget. Med Btrts afhænger det hele af din erfaring med det. Dette er et modent filsystem, men der er stadig nogle mistanker om, hvordan alt vil fungere i praksis i et bestemt scenarie. Jeg vil ikke anbefale at bruge dette, medmindre du har Btrfs i produktion.

Hvad er den aktuelle bedste praksis for omdeling af data?

Spørgsmålet om resharding er komplekst og mangefacetteret. Her kan du svare på flere muligheder på én gang. Du kan gå ind fra den ene side og sige dette – der er ingen indbygget resharding-mulighed i ClickHouse. Men jeg er bange for, at dette svar ikke vil passe nogen. Derfor kan du gå fra den anden side og sige, at ClickHouse har mange måder at resharde data på.

Hvis klyngen løber tør for plads, eller den ikke kan klare belastningen, tilføjer du nye servere. Men disse servere er tomme som standard, der er ingen data på dem, der er ingen belastning. Du skal flytte dataene, så de bliver jævnt fordelt over den nye, større klynge.

Den første måde at gøre dette på er at kopiere en del af partitionerne til nye servere ved hjælp af forespørgslen ændre tabelhentningspartition. For eksempel havde du partitioner efter måneder, og du tager den første måned af 2017 og kopierer den til en ny server, og kopierer derefter den tredje måned til en anden ny server. Og det gør man, indtil det bliver mere eller mindre jævnt.

Overførsel kan kun udføres for de partitioner, der ikke ændres under optagelsen. For nye partitioner skal skrivning være deaktiveret, fordi deres overførsel ikke er atomær. Ellers vil du ende med dubletter eller huller i dataene. Denne metode er dog praktisk og virker ganske effektivt. Færdiglavede komprimerede partitioner transmitteres over netværket, det vil sige, at dataene ikke komprimeres eller omkodes.

Denne metode har én ulempe, og det afhænger af sønderdelingsordningen, om du har lovet denne sønderdelingsordning, hvilken sønderdelingsnøgle du havde. I dit eksempel i tilfældet med metrics er sharding-nøglen en hash af stien. Når du vælger en distribueret tabel, går den til alle shards af klyngen på én gang og tager data derfra.

Det betyder, at det faktisk ikke er lige meget for dig, hvilke data der ender på hvilket skærv. Det vigtigste er, at data langs én vej ender på ét skår, men hvilken er ikke vigtig. I dette tilfælde er overførslen af ​​færdige partitioner perfekt, for med udvalgte forespørgsler vil du også modtage fuld data - både før omdeling og efter, skemaet betyder ikke rigtig noget.

Men der er sager, der er mere komplicerede. Hvis du på applikationslogikniveau er afhængig af en speciel sharding-ordning, at denne klient er placeret på sådan og sådan shard, og anmodningen kan sendes med det samme der, og ikke til den distribuerede tabel. Eller bruger du en forholdsvis ny version af ClickHouse og har aktiveret indstillingen optimer spring ubrugte skår over. I dette tilfælde vil udtrykket i where-sektionen blive parset under udvælgelsesforespørgslen, og det vil blive beregnet, hvilke shards der skal gå til i henhold til sharding-skemaet. Dette fungerer, forudsat at dataene dekomponeres nøjagtigt i overensstemmelse med denne sønderdeling. Hvis du flyttede dem manuelt, kan korrespondancen ændre sig.

Så det er vej nummer én. Og jeg venter på dit svar, er metoden egnet, eller kom videre.

Vladimir Kolobaev, ledende systemadministrator i Avito: Alexey, den metode, du nævnte, passer ikke særlig godt, når du skal sprede belastningen, inklusive læsning. Vi kan tage en partition, der er månedlig, og vi kan tage den foregående måned til en anden node, men når der kommer en anmodning om disse data, vil vi kun indlæse dem. Men jeg vil gerne indlæse hele klyngen, for ellers vil hele læsebelastningen i nogen tid blive behandlet af to skår.

Alexey Milovidov: Svaret her er mærkeligt – ja, det er dårligt, men det kan virke. Jeg vil forklare præcis hvordan. Det er værd at se på belastningsscenariet, der følger med dine data. Hvis dette er overvågningsdata, så er det næsten sikkert, at langt de fleste anmodninger er for friske data.

Du har installeret nye servere, migreret gamle partitioner, men også ændret, hvordan friske data skrives. Og friske data vil blive spredt i hele klyngen. Efter fem minutter vil anmodninger for de sidste fem minutter således indlæse klyngen jævnt, efter en dag vil anmodninger om en dag indlæse klyngen jævnt. Og anmodninger for den foregående måned vil desværre kun gå til en del af klyngeserverne.

Men ofte vil du ikke have anmodninger til februar 2019. Mest sandsynligt, hvis anmodninger går til 2019, så vil de være for hele 2019 - i et stort tidsinterval og ikke for et lille interval. Og sådanne anmodninger vil også være i stand til at indlæse klyngen jævnt. Men generelt er din bemærkning ganske korrekt, at der er tale om en ad hoc-løsning, der ikke spreder dataene helt jævnt.

Jeg har et par punkter mere til at besvare spørgsmålet. En af dem handler om, hvordan man i første omgang laver sharding-skemaet sådan, at der er mindre smerter ved resharding. Dette er ikke altid muligt.

For eksempel har du overvågningsdata. Overvågningsdata vokser af tre grunde. Den første er akkumulering af historiske data. Det andet er trafikvækst. Og den tredje er en stigning i antallet af ting, der er underlagt overvågning. Der er nye mikrotjenester og metrics, der skal gemmes.

Det er muligt, at af disse skyldes den største stigning den tredje årsag - det er en stigning i brugen af ​​overvågning. Og i dette tilfælde er det værd at se på belastningens art, hvad er de vigtigste anmodninger om at vælge. De vigtigste udvalgte forespørgsler følger sandsynligvis nogle undergrupper af metrics.

For eksempel CPU-brug på nogle servere af en eller anden tjeneste. Det viser sig, at der er en undergruppe af nøgler, som du får disse data med. Og selve anmodningen om disse data er højst sandsynligt ret simpel og kører på snesevis af millisekunder. Bruges til overvågningstjenester, til dashboards. Jeg håber, jeg forstår dette rigtigt.

Vladimir Kolobaev: Faktum er, at vi meget ofte appellerer til historiske data, da vi sammenligner den aktuelle position med den historiske i realtid. Og det er vigtigt for os at have hurtig adgang til en stor mængde data, og ClickHouse gør et godt stykke arbejde med dette.

Du har fuldstændig ret, de fleste af de læseforespørgsler oplever vi den sidste dag, ligesom ethvert overvågningssystem. Men samtidig er belastningen på historiske data også ret stor. Det er for det meste fra et alarmsystem, der går rundt hvert tredive sekund og fortæller ClickHouse: "Giv mig dataene for de sidste seks uger. Og opbyg nu et glidende gennemsnit af dem, og lad os sammenligne den nuværende værdi med den historiske værdi.

Jeg vil gerne sige, at for så meget friske anmodninger har vi en anden lille tabel, hvor vi kun gemmer to dages data, og de vigtigste anmodninger flyver ind i den. Vi sender kun store historiske forespørgsler til et stort opdelt bord.

Alexey Milovidov: Desværre viser det sig at være dårligt anvendeligt til dit scenarie, men jeg vil beskrive to dårlige og komplekse sønderdelingsskemaer, som ikke skal bruges, men som bruges i min venners tjeneste.

Der er en hovedklynge med Yandex.Metrica-begivenheder. Hændelser er sidevisninger, klik og overgange. De fleste anmodninger går til en bestemt hjemmeside. Du åbner Yandex.Metrica-tjenesten, du har en hjemmeside - avito.ru, gå til rapporten, og en anmodning er lavet til din hjemmeside.

Men der er andre anmodninger - analytiske og globale, som er lavet af interne analytikere. For en sikkerheds skyld bemærker jeg, at interne analytikere kun fremsætter anmodninger om Yandex-tjenester. Men ikke desto mindre optager selv Yandex-tjenester en betydelig del af alle data. Disse er anmodninger, ikke for specifikke tællere, men til bredere filtrering.

Hvordan organiserer man data på en sådan måde, at alt fungerer effektivt for én tæller, og også globale forespørgsler? En anden vanskelighed ligger i, at antallet af anmodninger i ClickHouse for Metrics-klyngen er flere tusinde pr. sekund. Samtidig håndterer én ClickHouse-server ikke ikke-trivielle anmodninger, for eksempel flere tusinde i sekundet.

Klyngestørrelsen er seks hundrede og noget servere. Hvis du blot strækker en distribueret tabel over denne klynge og sender flere tusinde anmodninger dertil, vil det blive endnu værre end at sende dem til én server. Til gengæld afvises muligheden for, at dataene er jævnt fordelt, og vi går og efterspørger fra alle servere, med det samme.

Der er en diametralt modsat mulighed. Forestil dig, hvis vi sønderdeler data efter websted, og en anmodning om et websted går til et fragment. Nu vil klyngen være i stand til at trække ti tusinde anmodninger ud i sekundet, men på én shard vil en anmodning arbejde for langsomt. Det vil ikke længere skalere i båndbredde. Især hvis det er et websted avito.ru. Jeg vil ikke afsløre en hemmelighed, hvis jeg siger, at Avito er et af de mest besøgte steder i Runet. Og at bearbejde det på ét skår ville være sindssygt.

Derfor er skæringsordningen indrettet på en mere tricky måde. Hele klyngen er opdelt i en række klynger, som vi kalder lag. Inde i hver klynge er der fra ti til flere dusin skår. Der er niogtredive sådanne klynger i alt.

Hvordan skalerer det hele? Antallet af klynger ændrer sig ikke - som det var for niogtredive år siden, forbliver det det samme. Men inden for hver af dem øger vi gradvist antallet af shards, efterhånden som data akkumuleres. Og sharding-skemaet som helhed er dette - opdelingen i disse klynger foregår efter hjemmesider, og for at forstå hvilket site der er på hvilken klynge, bruges generelt en separat metabase i MySQL. Ét sted - på én klynge. Og inde i den foregår sønderdeling i henhold til de besøgendes identifikatorer.

Ved optagelse opdeler vi dem efter resten af ​​besøgs-id'et. Men når et nyt skær er tilføjet, ændres skæringsskemaet, vi fortsætter med at dele, men med resten af ​​at dividere med et andet tal. Det betyder, at én besøgende allerede er placeret på flere servere, og du kan ikke spille på den. Dette gøres udelukkende for at sikre, at dataene bliver bedre komprimeret. Og når vi forespørger, går vi til tabellen Distribueret, som ser på klyngen og får adgang til snesevis af servere. Det er sådan en dum ordning.

Men min historie vil være ufuldstændig, hvis jeg ikke siger, at vi har opgivet denne ordning. I den nye ordning ændrede vi alt og kopierede alle data ved hjælp af clickhouse-kopimaskine.

I den nye ordning er alle pladser opdelt i to kategorier - store og små. Jeg ved ikke, hvordan tærsklen blev valgt der, men som et resultat viste det sig, at store websteder er registreret på en klynge, hvor der er 120 shards med tre replikaer i hver - det vil sige 360 ​​servere. Og skæringsordningen er sådan, at enhver anmodning går til alle skærver på én gang. Hvis du nu åbner en rapportside for avito.ru i Yandex.Metrica, vil anmodningen gå til 120 servere. Der er få store steder i Runet. Og anmodningerne er ikke tusinde i sekundet, men endda mindre end hundrede. Alt dette tygges stille og roligt af den distribuerede tabel, som hver af dem behandler 120 servere.

Og den anden klynge er til små steder. Her er en sharding-ordning efter site-id, og hver anmodning går til præcis et shard.

ClickHouse har et clickhouse-kopiværktøj. Kan du fortælle om hende?

Jeg må sige med det samme, at denne løsning er mere besværlig og noget mindre produktiv. Fordelen er, at den smører dataene fuldstændigt efter det skema, du angiver. Men ulempen ved værktøjet er, at det slet ikke omskærer sig. Den kopierer data fra et klyngeskema til et andet klyngeskema.

Det betyder, at for at det skal virke, skal du have to klynger. De kan være placeret på de samme servere, men ikke desto mindre vil dataene ikke blive flyttet trinvist, men vil blive kopieret.

For eksempel var der fire servere, nu er der otte. Du opretter en ny distribueret tabel på alle servere, nye lokale tabeller og starter clickhouse-copier, og specificerer i den det arbejdsskema, som det skal læse derfra, accepterer det nye shardingskema og overfører data dertil. Og du skal bruge halvanden gang mere plads på de gamle servere, end du har nu, fordi de gamle data skal forblive på dem, og halvdelen af ​​de samme gamle data kommer oven på dem. Hvis du på forhånd troede, at dataene skal omskæres, og der er plads, så er denne metode velegnet.

Hvordan fungerer clickhouse-kopimaskine indeni? Det opdeler alt arbejdet i et sæt opgaver til behandling af én partition af én tabel på én shard. Alle disse opgaver kan køre parallelt, og clickhouse-copier kan køre flere forekomster på forskellige maskiner, men hvad den gør for en enkelt partition, er intet mere end en insert select. Dataene læses, dekomprimeres, ompartitioneres, derefter komprimeres igen, skrives et sted, sorteres igen. Dette er en sværere beslutning.

Du havde en pilotting, der hed resharding. Hvad med hende?

Tilbage i 2017 havde du en pilotting, der hed resharding. Der er endda en mulighed i ClickHouse. Jeg forstår, at det ikke tog fart. Kan du fortælle hvorfor det skete? Det ser ud til at være meget relevant.

Hele problemet er, at hvis du har brug for at omskære data på plads, kræves en meget kompleks synkronisering for at gøre dette atomært. Da vi begyndte at se på, hvordan denne synkronisering fungerer, blev det klart, at der er grundlæggende problemer. Og disse grundlæggende problemer er ikke kun teoretiske, men begyndte straks at vise sig i praksis i form af noget, der kan forklares meget enkelt - intet virker.

Er det muligt at flette alle dele af data sammen, før du flytter til langsomme diske?

Et spørgsmål om TTL med overgangen til langsom disk mulighed i forbindelse med fusioner. Er der en anden måde end cron at flette alle dele til én, før du flytter til langsomme diske?

Svaret på spørgsmålet om, hvorvidt det er muligt på en eller anden måde automatisk at lime alle stykkerne i én, før de overføres, er nej. Det forekommer mig, at dette ikke er nødvendigt. Du kan ikke flette alle dele til én, men blot stole på, at de automatisk overføres til langsomme diske.

Vi har to kriterier for transferregler. Den første er som den fyldes op. Hvis det aktuelle lagerniveau har mindre end en vis procentdel ledig plads, vælger vi én del og flytter den til en langsommere lagerplads. Eller rettere sagt, ikke langsommere, men følgende - hvordan du sætter det op.

Det andet kriterium er størrelse. Han taler om overførsel af store stykker. Du kan justere tærsklen baseret på ledig plads på en hurtig disk, og dataene vil blive migreret automatisk.

Hvordan migrere til nye versioner af ClickHouse, hvis der ikke er nogen måde at kontrollere kompatibiliteten på forhånd?

Dette emne diskuteres jævnligt i Telegram chat ClickHouse under hensyntagen til forskellige versioner, og dog. Hvor sikkert er det at opgradere fra version 19.11 til 19.16 og for eksempel fra 19.16 til 20.3. Hvad er den bedste måde at flytte til nye versioner på uden at være i stand til at tjekke kompatibilitet i sandkassen på forhånd?

Der er et par gyldne regler her. Først - læs ændringslog. Det er stort, men der er separate punkter om bagud uforenelige ændringer. Behandl ikke disse genstande som et rødt flag. Disse er normalt mindre inkompatibiliteter, der er relateret til en eller anden kantfunktionalitet, som du sandsynligvis ikke bruger.

For det andet, hvis der ikke er nogen måde at kontrollere kompatibilitet i sandkassen, og du vil opgradere med det samme i produktionen, er anbefalingen, at du ikke behøver at gøre dette. Opret først en sandkasse og test. Hvis der ikke er et testmiljø, så har du højst sandsynligt ikke en særlig stor virksomhed, hvilket betyder, at du kan kopiere nogle af dataene til din bærbare computer og sikre dig, at alt fungerer korrekt på den. Du kan endda hente et par replikaer op lokalt på din maskine. Eller du kan rejse en ny version et sted i nærheden og uploade nogle data der - altså lave et improviseret testmiljø.

En anden regel er ikke at opdatere inden for en uge efter udgivelsen af ​​versionen på grund af at fange fejl i produktionen og efterfølgende hurtige rettelser. Lad os forstå ClickHouse-versionsnummereringen for ikke at blive forvirret.

Der er version 20.3.4. Tallet 20 angiver fremstillingsåret - 2020. Fra synspunktet om, hvad der er indeni, er dette ligegyldigt, så vi vil ikke være opmærksomme på det. Yderligere - 20.3. Det andet tal - i dette tilfælde 3 - øger vi hver gang vi frigiver en udgivelse med noget ny funktionalitet. Hvis vi ønsker at tilføje nogle funktioner til ClickHouse, skal vi øge dette antal. Det vil sige, at ClickHouse i version 20.4 vil fungere endnu bedre. Det tredje ciffer er 20.3.4. Her 4 er antallet af patch-udgivelser, hvor vi ikke tilføjede nye funktioner, men rettede nogle fejl. Og 4 betyder, at vi gjorde det fire gange.

Tro ikke, det er noget forfærdeligt. Normalt kan brugeren installere den nyeste version, og den vil fungere uden problemer med oppetid om året. Men forestil dig, at i en eller anden funktion til behandling af bitmaps, som blev tilføjet af vores kinesiske kammerater, når de sender forkerte argumenter, går serveren ned. Vi skal ordne dette. Vi vil frigive en ny patch-version, og ClickHouse vil blive mere stabil.

Hvis du har ClickHouse, der arbejder i produktion, og en ny version af ClickHouse med yderligere funktioner er frigivet - for eksempel er 20.4.1 den allerførste, så skynd dig ikke at sætte den i produktion på den første dag. Hvorfor er der overhovedet brug for hende? Hvis du ikke bruger ClickHouse endnu, så kan du installere det, og højst sandsynligt vil alt være fint. Men hvis ClickHouse allerede fungerer stabilt, så følg med for patches og opdateringer - hvilke problemer løser vi.

Kirill Shvakov: Jeg vil tilføje lidt om testmiljøer. Alle er meget bange for testmiljøer og mener af en eller anden grund, at hvis du har en meget stor ClickHouse-klynge, så skal testmiljøet ikke være mindre eller mindst ti gange mindre. Sådan er det slet ikke.

Jeg kan se ved mit eksempel. Jeg har et projekt, og der er ClickHouse. Vores testmiljø for ham er en lille virtuel maskine i Hetzner til tyve euro, hvor absolut alt er installeret. For at gøre dette har vi fuld automatisering i Ansible, og derfor er der i princippet ingen forskel, hvor man skal rulle – på jernservere eller blot implementere i virtuelle maskiner.

Hvad kan gøres? Det ville være rart at lave et eksempel i ClickHouse-dokumentationen på, hvordan man implementerer en lille klynge på egen hånd - i Docker, i LXC, opret måske en Ansible playbook, fordi forskellige mennesker har forskellige implementeringer. Dette vil gøre mange ting nemmere. Når du tager og implementerer en klynge på fem minutter, er det meget nemmere at prøve at finde ud af noget. Det er meget mere bekvemt på denne måde, fordi at rulle en version, som du ikke har testet i produktion, er en vej til ingen steder. Nogle gange virker det, og nogle gange gør det ikke. Og så er det dårligt at håbe på succes.

Maxim Kotyakov, senior backend-ingeniør Avito: Jeg vil tilføje lidt om testmiljøer fra en række problemer for store virksomheder. Vi har en fuldgyldig ClickHouse-acceptklynge, i henhold til dataskemaer og indstillinger, en nøjagtig kopi af, hvad der er i produktion. Denne klynge er indsat i ret rådne containere med et minimum af ressourcer. Vi skriver der en vis procentdel af produktionsdataene, da der er mulighed for at replikere strømmen i Kafka. Alt er synkroniseret og skaleret der - både i forhold til kapacitet og flow, og i teorien burde det alt andet lige opføre sig som en produktion målt i forhold til metrik. Alt potentielt eksplosivt rulles først op på dette stativ og infunderes der i flere dage, indtil det er klart. Men selvfølgelig er denne løsning dyr, tung og med ikke-nul supportomkostninger.

Alexey Milovidov: Jeg vil fortælle dig, hvordan testmiljøet for vores venner fra Yandex.Metrica er. Den ene klynge var til 600-noget-servere, den anden til 360, og der er en tredje og flere klynger. Testmiljøet for en af ​​dem er blot to skår med to replikaer i hver. Hvorfor to skår? For ikke at være alene. Og replikaer skal også være. Bare et minimumsbeløb, som du har råd til.

Dette testmiljø giver dig mulighed for at kontrollere forespørgslernes helbred, og om noget er brudt i stor stil. Men ofte opstår der problemer af en helt anden karakter, når alt fungerer, men der er nogle små ændringer med belastningen.

Jeg vil give dig et eksempel. Vi besluttede at installere en ny version af ClickHouse. Det er lagt ud på et testmiljø, automatiserede test bestået i selve Yandex.Metrica, som sammenligner data på den gamle version og på den nye, der kører hele pipelinen. Og selvfølgelig grønne test af vores CI. Ellers ville vi ikke engang have foreslået denne version.

Alt er fint. Vi begynder at rulle ind i produktionen. Jeg får besked om, at belastningen er steget flere gange på graferne. Vi ruller versionen tilbage. Jeg ser på grafen og ser: belastningen steg virkelig flere gange under udrulningen og faldt tilbage, når den blev rullet ud. Så begyndte vi at rulle versionen tilbage. Og belastningen steg på samme måde og faldt tilbage på samme måde. Så konklusionen er denne - belastningen er steget i forbindelse med beregningen, intet overraskende.

Så var det svært at overbevise kollegerne om alligevel at installere den nye version. Jeg siger: ”Det er okay, rul ud. Kryds fingre, alt vil virke. Nu er belastningen steget på hitlisterne, men alt er fint. Hold fast." Generelt gjorde vi dette, og det er det - versionen er lagt ud på produktionssiden. Men næsten med hver beregning opstår lignende problemer.

Kill-forespørgsel formodes at dræbe forespørgsler, men det gør den ikke. Hvorfor?

En bruger kom til mig, en slags analytiker, og oprettede en bestemt anmodning, som satte min ClickHouse-klynge. En eller anden node eller en hel klynge, afhængigt af hvilken replika eller shard anmodningen kom ind i. Jeg ser, at alle CPU-ressourcer på denne server er på hylden, alt er rødt. Samtidig reagerer ClickHouse selv på forespørgsler. Og jeg skriver: "Vis mig venligst proceslisten, hvilken anmodning genererede dette vanvid."

Jeg finder denne anmodning og skriver dræb til den. Og jeg kan se, at der ikke sker noget. Min server er på hylden, ClickHouse giver mig så nogle kommandoer, viser at serveren er i live, og alt er fint. Men jeg har forringelse i alle brugeranmodninger, nedbrydning ved indtastning i ClickHouse begynder, og min kill-forespørgsel virker ikke. Hvorfor? Jeg troede, at kill query skulle dræbe forespørgsler, men det gør det ikke.

Nu kommer der et ret mærkeligt svar. Pointen er, at kill-forespørgsel ikke dræber anmodninger.

Kill-forespørgsel sætter et lille afkrydsningsfelt kaldet "Jeg vil have, at denne forespørgsel skal slås ihjel". Og selve anmodningen, når den behandler hver blok, ser på dette flag. Hvis den er indstillet, holder anmodningen op med at virke. Det viser sig, at ingen dræber anmodningen, han skal selv tjekke alt og stoppe. Og dette bør fungere i alle tilfælde, hvor anmodningen er i en blokbehandlingstilstand. Det vil behandle den næste blok af data, kontrollere flaget og stoppe.

Dette virker ikke i tilfælde, hvor anmodningen er blokeret på en eller anden operation. Sandt nok er dette højst sandsynligt ikke dit tilfælde, fordi det ifølge dig bruger en masse serverressourcer. Det er muligt, at dette ikke virker ved ekstern sortering og i nogle andre detaljer. Men generelt burde dette ikke være, det er en fejl. Og det eneste jeg kan råde er at opdatere ClickHouse.

Hvordan beregnes responstid under læsebelastning?

Der er en tabel, der gemmer vareaggregater - forskellige tællere. Antallet af linjer er omkring hundrede millioner. Er det muligt at regne med en forudsigelig responstid, hvis du hælder 1K RPS på 1K varer?

Ud fra sammenhængen at dømme taler vi om en læsebelastning, for der er ingen problemer med at skrive - der kan indsættes mindst tusinde, mindst hundrede tusinde og nogle gange flere millioner linjer.

Læseønsker er meget forskellige. I udvalgt 1 kan ClickHouse udføre omkring titusindvis af anmodninger i sekundet, så selv anmodninger om en enkelt nøgle vil allerede kræve nogle ressourcer. Og sådanne punktforespørgsler vil være vanskeligere end i nogle nøgleværdidatabaser, fordi det for hver læsning er nødvendigt at læse datablok for indeks. Vores indeks adresserer ikke hver post, men hvert område. Det vil sige, at du skal læse hele området - det er 8192 linjer som standard. Og du skal dekomprimere den komprimerede datablok fra 64 KB til 1 MB. Typisk tager sådanne punktforespørgsler fra et par millisekunder. Men dette er den nemmeste mulighed.

Lad os prøve noget simpelt regnestykke. Hvis du ganger et par millisekunder med tusind, får du et par sekunder. Som om det er umuligt at holde tusinde anmodninger i sekundet, men faktisk er det muligt, fordi vi har flere processorkerner. Så i princippet kan 1000 RPS ClickHouse nogle gange holde, men på korte anmodninger, nemlig punkt.

Hvis du skal skalere ClickHouse-klyngen efter antallet af simple anmodninger, så anbefaler jeg den enkleste ting - øg antallet af replikaer og send anmodninger til en tilfældig replika. Hvis en replika rummer fem hundrede anmodninger i sekundet, hvilket er fuldstændig realistisk, så vil tre replikaer indeholde halvandet tusinde.

Nogle gange kan du selvfølgelig også konfigurere ClickHouse til det maksimale antal punktaflæsninger. Hvad skal der til? Den første er at reducere indeksets granularitet. Samtidig skal det ikke reduceres til én, men ud fra at antallet af poster i indekset bliver flere millioner eller titusinder pr. server. Hvis tabellen har hundrede millioner rækker, kan 64 indstilles som granularitet.

Du kan reducere størrelsen af ​​den komprimerede blok. Der er indstillinger for dette. min komprimeringsblokstørrelse, maks. komprimeringsblokstørrelse. Du kan reducere dem, genindlæse data, og så vil punktforespørgsler være hurtigere. Men alligevel er ClickHouse ikke en nøgleværdidatabase. Et stort antal små anmodninger er et belastnings-anti-mønster.

Kirill Shvakov: Jeg vil give råd, hvis der er almindelige revisorer. Dette er en ret standard situation, når en form for tæller er gemt i ClickHouse. Jeg har en bruger, han er fra sådan og sådan et land, et andet tredje felt, og jeg skal øge noget trinvist. Tag MySQL, lav en unik nøgle - i MySQL er det en dubletnøgle, og i PostgreSQL er det en konflikt - og tilføj et plustegn. Dette vil fungere meget bedre.

Når du har lidt data, er der ikke meget mening i at bruge ClickHouse. Der er regelmæssige databaser, og de gør et godt stykke arbejde med det.

Hvad skal man justere i ClickHouse, så der er flere data i cachen?

Lad os forestille os situationen - serverne har 256 GB RAM, i den daglige rutine tager ClickHouse omkring 60-80 GB, på toppen - op til 130. Hvad kan aktiveres og justeres, så flere data er i cachen og i overensstemmelse hermed , er der færre ture til disken?

Som regel klarer sidecachen i operativsystemet denne opgave godt. Hvis du bare åbner toppen, ser der cache eller ledig - der står også hvor meget der er cache - så kan du se, at al den ledige hukommelse er brugt til cachen. Og når du læser disse data, vil de ikke blive læst fra disken, men fra RAM. Samtidig kan jeg sige, at cachen bliver brugt effektivt, fordi det er de komprimerede data, der cachelagres.

Men hvis du vil fremskynde nogle simple forespørgsler endnu mere, er det muligt at aktivere en cache i de dekomprimerede data inde i ClickHouse. Det kaldes ukomprimeret cache. Indstil den ukomprimerede cachestørrelse i konfigurationsfilen config.xml til den værdi, du har brug for - jeg anbefaler ikke mere end halvdelen af ​​den frie RAM, fordi resten vil gå under sidecachen.

Derudover er der to anmodningsniveauindstillinger. Første indstilling - bruge ukomprimeret cache - omfatter dets brug. Det anbefales at aktivere det for alle anmodninger, undtagen for tunge, som kan læse alle data og tømme denne cache. Og den anden indstilling er noget i retning af det maksimale antal linjer for at bruge cachen. Det begrænser automatisk store anmodninger, så de er forbi cachen.

Hvordan kan jeg konfigurere storage_configuration til lagring i RAM?

I den nye ClickHouse-dokumentation læste jeg afsnittet relateret med datalagring. I beskrivelsen er der et eksempel med en hurtig SSD.

Jeg spekulerer på, hvordan du kan konfigurere det samme med volumen varm hukommelse. Og endnu et spørgsmål. Hvordan fungerer select med denne dataorganisation, vil den læse hele sættet eller kun det på disken, og er disse data komprimeret i hukommelsen? Og hvordan fungerer prewhere-sektionen på sådan en dataorganisation?

Denne indstilling påvirker lagringen af ​​datastykker, og deres format ændres ikke på nogen måde.
Lad os se nærmere.

Du kan konfigurere lagring af data i RAM'en. Alt, hvad der er konfigureret til en disk, er dens sti. Du opretter en tmpfs-partition, der er monteret på en sti i filsystemet. Angiv denne sti som datalagringsstien for den hotteste partition, stykker data begynder at ankomme og blive skrevet der, alt er fint.

Men jeg anbefaler ikke at gøre dette på grund af lav pålidelighed, men hvis du har mindst tre replikaer i forskellige datacentre, så kan du det. Hvis det er tilfældet, vil dataene blive gendannet. Forestil dig, at serveren pludselig blev slukket og tændt igen. Sektionen blev monteret igen, men der er et tomrum. Ved opstart ser ClickHouse-serveren, at disse dele mangler, selvom de ifølge ZooKeeper-metadata burde være det. Han ser på, hvilke replikaer de er på, anmoder om dem og downloader dem. Således vil dataene blive gendannet.

I denne forstand er lagring af data i RAM ikke fundamentalt anderledes end lagring på disk, for når data skrives til disk, falder de også først ind i sidecachen og bliver fysisk skrevet senere. Det afhænger af, hvordan filsystemet er monteret. Men for en sikkerheds skyld vil jeg sige, at ClickHouse ikke fsynkroniserer ved indsættelse.

I dette tilfælde er dataene i RAM gemt i nøjagtig samme format som på disken. Select-forespørgslen vælger de bidder, der skal læses, på samme måde, vælger de nødvendige dataområder i chuns-erne og læser dem. Og prewhere fungerer nøjagtigt det samme, uanset om data var i RAM eller på disk.

Op til hvilket antal unikke værdier er Low Cardinality effektiv?

Lav kardinalitet er vanskelig. Den kompilerer dataordbøger, men de er lokale. For det første er ordbøgerne forskellige for hvert stykke, og for det andet kan de selv inden for et stykke være forskellige for hvert sortiment. Når antallet af unikke værdier når en tærskel - en million, tror jeg - bliver ordbogen simpelthen lagt til side, og en ny oprettes.

Svaret er generelt: For hver lokal række - for eksempel for hver dag - et sted op til en million unikke værdier, er Low Cardinality effektiv. Herefter vil der blot være et fallback, hvor mange forskellige ordbøger vil blive brugt, og ikke kun én. Det vil fungere på nogenlunde samme måde som en almindelig kolonne af strengtypen, måske lidt mindre effektivt, men der vil ikke være nogen alvorlig forringelse af ydeevnen.

Hvad er de bedste fremgangsmåder for fuldtekstsøgning på en tabel med fem milliarder rækker?

Der er forskellige svar. Den første er at sige, at ClickHouse ikke er en fuldtekstsøgemaskine. Der findes specielle systemer til dette, f.eks. Elasticsearch и Sphinx. Jeg ser dog flere og flere mennesker, der siger, at de flytter fra Elasticsearch til ClickHouse.

Hvorfor sker dette? De forklarer dette med, at Elasticsearch ophører med at klare belastningen på nogle volumener, begyndende med at bygge indekser. Indekser bliver for besværlige, og overfører man blot dataene til ClickHouse, viser det sig, at de volumenmæssigt bliver lagret flere gange mere effektivt. Samtidig var søgeforespørgsler ofte ikke sådan, at det var nødvendigt at finde en eller anden sætning i hele mængden af ​​data, under hensyntagen til morfologi, men helt andre. For eksempel for at finde de sidste par timer i logfilerne for nogle efterfølger af bytes.

I dette tilfælde opretter du et indeks i ClickHouse, hvor det første felt vil være datoen med tiden. Og den største afskæring af data vil være nøjagtigt for datointervallet. Inden for det valgte datointerval er det som regel allerede muligt at udføre en fuldtekstsøgning, selv ved brug af brute-force-metoden ved hjælp af like. Like-erklæringen i ClickHouse er den mest effektive lignende-erklæring, du kan finde. Hvis du finder en bedre, så fortæl mig.

Men det er stadig en fuld scanning. Og fuld scanning kan være langsom ikke kun på CPU'en, men også på disken. Hvis du pludselig har én terabyte data om dagen, og du leder efter et ord på en dag, bliver du nødt til at scanne en terabyte. Og det er sikkert på almindelige harddiske, og som følge heraf bliver de indlæst på en sådan måde, at du ikke kommer ind på denne server via SSH.

I dette tilfælde er jeg klar til at tilbyde endnu et lille trick. Det er fra kategorien eksperimentelt - det kan virke, eller det kan ikke. ClickHouse har fuldtekstindekser i form af trigram-bloom-filtre. Vores kolleger hos Arenadata har allerede prøvet disse indekser, og ofte fungerer de præcis efter hensigten.

For at kunne bruge dem korrekt, bør du have en god forståelse af præcis, hvordan de fungerer: hvad et trigram bloom filter er, og hvordan du vælger dets størrelse. Jeg kan sige, at de vil hjælpe med forespørgsler om nogle sjældne sætninger, understrenge, der sjældent findes i dataene. I dette tilfælde vil underområder blive valgt af indekser, og færre data vil blive læst.

ClickHouse har for nylig tilføjet endnu mere avancerede funktioner til fuldtekstsøgning. Dette er, for det første, søgningen efter en masse understrenge på én gang i én gang, inklusive indstillinger, der skelner mellem store og små bogstaver, ufølsom, UTF-8-understøttet eller kun ASCII. Vælg den mest effektive, du har brug for.

Der blev også søgt efter flere regulære udtryk i én omgang. Du behøver ikke at skrive X som en understreng eller X som en anden understreng. Skriv med det samme, og alt bliver gjort så effektivt som muligt.

For det tredje er der nu en omtrentlig søgning efter regexps og en omtrentlig søgning efter understrenge. Hvis nogen skrev et ord med en tastefejl, søges det efter det maksimale match.

Hvad er den bedste måde at organisere adgangen til ClickHouse for et stort antal brugere?

Fortæl os, hvordan man bedst organiserer adgang for et stort antal forbrugere og analytikere. Hvordan danner man en kø, prioriterer maks. samtidige forespørgsler, og med hvilke værktøjer?

Hvis klyngen er stor nok, så ville en god løsning være at rejse yderligere to servere, som vil blive indgangspunktet for analytikere. Det vil sige, lad ikke analytikere komme ind i specifikke klyngeshards, men opret blot to tomme servere, uden data, og sætter allerede adgangsrettigheder til dem. Samtidig overføres brugerindstillinger til fjernservere under distribuerede anmodninger. Det vil sige, at du konfigurerer alt på disse to servere, og indstillingerne har en effekt på hele klyngen.

I princippet er disse servere uden data, men mængden af ​​RAM på dem er meget vigtig for at udføre anmodninger. Disk kan også bruges til midlertidige data, hvis ekstern aggregering eller ekstern sortering er aktiveret.

Det er vigtigt at se på de indstillinger, der er forbundet med alle mulige grænser. Hvis jeg nu går til Yandex.Metrics-klyngen som analytiker og sætter en forespørgsel vælg antal af hits, så får jeg straks en undtagelse om, at jeg ikke kan opfylde anmodningen. Det maksimale antal rækker, som jeg må scanne, er hundrede milliarder, og der er halvtreds billioner i alt på klyngen i én tabel. Dette er den første begrænsning.

Lad os sige, at jeg fjerner grænsen for antallet af rækker og kører forespørgslen igen. Så vil jeg se følgende undtagelse - indstillingen er aktiveret kraftindeks efter dato. Jeg kan ikke køre forespørgslen, hvis jeg ikke har angivet et datointerval. Du behøver ikke at stole på analytikere for at indtaste det manuelt. Et typisk tilfælde - et datointerval skrives, hvor begivenhedsdatoen er mellem en uge. Og så har de bare ikke angivet en parentes der, og i stedet for og det viste sig at være eller - eller URL-match. Hvis der ikke er nogen grænse, vil den gennemgå URL-kolonnen og spilde et væld af ressourcer.

Derudover har ClickHouse to prioriterede indstillinger. Desværre er de meget primitive. Man hedder simpelthen prioritet. Hvis prioritet ≠ 0, og anmodninger med en vis prioritet udføres, men en anmodning med en prioritetsværdi, der er lavere, hvilket betyder en højere prioritet, udføres, så er en anmodning med en prioritetsværdi større end, hvilket betyder en lavere prioritet, simpelthen suspenderet og virker slet ikke i denne tid.

Dette er en meget grov indstilling og er ikke egnet til situationer, hvor der er en konstant belastning på klyngen. Men hvis du har korte, impulsforespørgsler, der er vigtige, og klyngen for det meste er inaktiv, vil denne indstilling fungere.

Den næste prioritetsindstilling kaldes OS trådprioritet. Det udsætter simpelthen alle anmodningsudførelsestråde for den gode værdi for Linux-planlæggeren. Det fungerer halvdårligt, men virker stadig. Hvis du indstiller den allermindste nice-værdi - den er den største i værdi, og derfor den laveste prioritet - og indstiller -19 for højprioritetsanmodninger, så vil CPU'en forbruge lavprioritetsanmodninger omkring fire gange mindre end højprioritetsanmodninger.

Du skal også indstille den maksimale udførelsestid for forespørgsler - f.eks. fem minutter. Den minimale anmodningsudførelseshastighed er den fedeste ting. Denne indstilling har eksisteret i lang tid, og det er påkrævet ikke kun at hævde, at ClickHouse ikke bremser, men at tvinge det.

Forestil dig, at du opsætter: Hvis en forespørgsel behandler mindre end en million rækker i sekundet, kan du ikke gøre det. Dette vanærer vores gode navn, vores gode database. Lad os bare forbyde det. Der er faktisk to indstillinger. Den ene kaldes min udførelseshastighed - i linjer pr. sekund, og den anden kaldes timeout før kontrol af min udførelseshastighed - femten sekunder som standard. Det vil sige, at femten sekunder er muligt, og så, hvis langsomt, så smid bare en undtagelse - afbryd anmodningen.

Du skal også oprette kvoter. ClickHouse har en indbygget kvotefunktion, der tæller ressourceforbrug. Men desværre ikke jernressourcer såsom CPU, diske, men logiske - antallet af behandlede anmodninger, linjer og bytes læst. Og du kan for eksempel maksimalt opsætte hundrede anmodninger inden for fem minutter og tusinde anmodninger i timen.

Hvorfor er det vigtigt? Fordi nogle af analyseanmodningerne vil blive udført manuelt direkte fra ClickHouse-klienten. Og alt bliver godt. Men hvis du har avancerede analytikere i din virksomhed, skriver de et script, og der kan være en fejl i scriptet. Og denne fejl vil få anmodningen til at blive udført i en uendelig løkke. Det er det, der skal beskyttes.

Er det muligt at give resultaterne af en anmodning til ti kunder?

Vi har flere brugere, der godt kan lide at komme ind med meget store ønsker på samme tid. Forespørgslen er stor, i princippet bliver den eksekveret hurtigt, men på grund af at der er mange sådanne anmodninger på samme tid, bliver det meget smertefuldt. Er det muligt at udføre den samme anmodning, som ankom ti gange i træk, én gang og give resultatet til ti klienter?

Problemet er, at vi ikke har cacheresultater eller mellemliggende datacache. Der er en sidecache i operativsystemet, som giver dig mulighed for ikke at læse data fra disken igen, men desværre vil dataene stadig blive dekomprimeret, deserialiseret og genbehandlet.

Jeg vil gerne på en eller anden måde undgå dette, enten ved at cache mellemliggende data eller ved at opstille lignende forespørgsler i en slags kø og tilføje en cache med resultater. Nu har vi en pull request under udvikling, som tilføjer en request cache, men kun for subrequests i in og join sektionerne - det vil sige, at løsningen er ringere.

Vi har dog også en sådan situation. Et særligt kanonisk eksempel er anmodninger med paginering. Der er en rapport, den har flere sider, og der er en anmodning om grænse 10. Så det samme, men grænse 10,10. Så endnu en side. Og spørgsmålet er, hvorfor vi tæller det hele hver gang? Men nu er der ingen løsning, og der er ingen måde at undgå det på.

Der er en alternativ løsning, der placeres som sidevogn ved siden af ​​ClickHouse - ClickHouse Proxy.

Kirill Shvakov: ClickHouse Proxy har en indbygget hastighedsbegrænser og en indbygget resultatcache. Der er lavet mange indstillinger, fordi en lignende opgave blev løst. Proxy giver dig mulighed for at begrænse anmodninger ved at sætte dem i kø og konfigurere, hvor længe anmodningscachen lever. Hvis anmodningerne virkelig var de samme, vil proxyen give dem mange gange og kun gå til ClickHouse én gang.

Nginx har også en cache i den gratis version, og det vil også fungere. Nginx har endda indstillinger, så hvis anmodninger kommer ind på samme tid, vil det stoppe andre, indtil en fuldfører. Men det er i ClickHouse Proxy, at indstillingerne er gjort meget bedre. Det blev lavet specifikt til ClickHouse, specifikt til disse anmodninger, så det er mere velegnet. Nå, det er nemt at sætte op.

Hvad med asynkrone operationer og materialiserede synspunkter?

Der er et sådant problem, at operationer med den erstattende motor er asynkrone - data skrives først, derefter kollapser de. Hvis en materialiseret tablet med nogle aggregater bor under tabletten, vil dubletter blive skrevet til den. Og hvis der ikke er nogen kompleks logik, vil dataene blive duplikeret. Hvad kan man gøre ved det?

Der er en oplagt løsning - at implementere en trigger på en specifik matview-klasse under en asynkron kollapsoperation. Er der nogen "silver bullets" planer om at implementere en sådan funktionalitet?

Det er værd at forstå, hvordan deduplikering fungerer. Det, jeg er ved at sige, er ikke relateret til spørgsmålet, men det er værd at huske for en sikkerheds skyld.

Når du indsætter i en replikeret tabel, er der deduplikering af hele de indsatte blokke. Hvis du genindsætter den samme blok, der indeholder det samme antal af de samme rækker i samme rækkefølge, deduplikeres dataene. Du vil få "Ok" som svar på indsættelsen, men en batch af data vil faktisk blive skrevet, og den vil ikke blive duplikeret.

Dette er nødvendigt for sikkerheden. Hvis du får "Ok" under indsættelsen, så er dine data blevet indsat. Hvis du modtager en fejl fra ClickHouse, så er de ikke indsat, og du skal gentage indsættelsen. Men hvis forbindelsen afbrydes under indsættelsen, så ved du ikke, om dataene er indsat eller ej. Den eneste mulighed er at gentage indsættelsen igen. Hvis dataene faktisk blev indsat, og du genindsatte dem, er der blokdeduplikering. Det er nødvendigt for at undgå dubletter.

Og det er også vigtigt, hvordan det fungerer for materialiserede synspunkter. Hvis dataene blev deduplikeret, da de blev indsat i hovedtabellen, vil de heller ikke gå til den materialiserede visning.

Nu om spørgsmålet. Din situation er mere kompliceret, fordi du skriver dubletter af individuelle linjer. Det vil sige, at ikke hele pakken er duplikeret, men specifikke linjer, og de kollapser i baggrunden. Faktisk vil dataene kollapse i hovedtabellen, og de ikke-sammenbrudte vil gå til den materialiserede visning, og der vil ikke ske noget med materialiserede visninger under sammenlægning. Fordi en materialiseret visning ikke er mere end en udløser på indsatsen. Der sker ikke andet med det under andre operationer.

Og jeg kan ikke være glad her. Det er kun nødvendigt at lede efter en specifik løsning til denne sag. Er det for eksempel muligt at erstatte det i en materialiseret visning, og deduplikeringsmetoden vil måske fungere på samme måde. Men desværre ikke altid. Hvis det aggregeres, så virker det ikke.

Kirill Shvakov: Vi havde også knoglebygning på et tidspunkt. Der var et problem med, at der er annoncevisninger, og der er nogle data, som vi kan vise i realtid - det er kun visninger. De bliver sjældent duplikeret, men hvis de gør det, kollapser vi dem alligevel senere. Og der var ting, der ikke kan kopieres - klik og hele denne historie. Men jeg ville også vise dem næsten med det samme.

Hvordan blev materialiserede synspunkter lavet? Der var visninger, hvor det er skrevet direkte - der er rekord i rådata, og det er skrevet i visninger. Der er dataene på et tidspunkt ikke særlig korrekte, de er duplikeret og så videre. Og der er den anden del af tabellen, hvor de ser nøjagtigt ud som de materialiserede synspunkter, det vil sige, at de er nøjagtig ens i strukturen. En gang imellem genberegner vi dataene, tæller dataene uden dubletter, skriver til disse tabeller.

Vi gik gennem API'en - dette vil ikke fungere i ClickHouse i hånden. Og API'en ser ud: når jeg har datoen for den sidste tilføjelse til tabellen, hvor det er garanteret, at de korrekte data allerede er beregnet, og den laver en anmodning til en tabel og til en anden tabel. Fra den ene anmodning vælger den op til et vist tidsrum, og fra den anden får den, hvad der endnu ikke er blevet beregnet. Og det virker, men ikke ved hjælp af ét ClickHouse.

Hvis du har en form for API - for analytikere, for brugere - så er dette i princippet en mulighed. Du tæller altid, tæller altid. Dette kan gøres en gang om dagen eller på et andet tidspunkt. Du vælger selv det sortiment, som du ikke har brug for og ikke er kritisk.

ClickHouse har mange logfiler. Hvordan kan jeg se alt, hvad der sker med serveren på et øjeblik?

ClickHouse har et meget stort antal forskellige logfiler, og dette antal er stigende. I nye versioner er nogle af dem endda aktiveret som standard, i ældre versioner skal de aktiveres ved opdatering. Dem er der dog flere og flere af. Jeg vil gerne endelig se, hvad der sker nu med min server, måske på et resumé-dashboard.

Har du i ClickHouse-teamet eller i dine venners teams, der understøtter nogle funktionaliteter i færdiglavede dashboards, der viser disse logfiler som et færdigt produkt? I sidste ende er det fantastisk bare at se på logfilerne i ClickHouse. Men det ville være meget fedt, hvis det allerede var forberedt i form af et dashboard. Jeg ville blive høj på det her.

Der er dashboards, selvom de ikke er standardiserede. Vi har omkring 60 teams i vores virksomhed, der bruger ClickHouse, og det mærkeligste er, at mange af dem har dashboards, som de selv har lavet, og lidt anderledes. Nogle teams bruger den interne installation af Yandex.Cloud. Der er nogle færdige rapporter, men ikke alle nødvendige. Andre har deres.

Mine kolleger fra Metrica har deres eget dashboard i Grafana, og jeg har mit til deres egen klynge. Jeg ser på ting som et cache-hit til en serif-cache. Og endnu sværere er det, at vi bruger forskellige værktøjer. Jeg lavede mit dashboard på et meget gammelt værktøj kaldet Graphite-web. Han er fuldstændig grim. Og jeg bruger det stadig på den måde, selvom Grafana nok ville være mere praktisk og smukkere.

Det grundlæggende i dashboards er det samme. Disse er systemmålinger for klyngen: CPU, hukommelse, disk, netværk. Andre er antallet af samtidige anmodninger, antallet af samtidige fletninger, antallet af anmodninger pr. sekund, det maksimale antal bidder til MergeTree tabelpartitioner, replikeringsforsinkelsen, størrelsen af ​​replikeringskøen, antallet af rækker indsat pr. sekund, antallet af blokke indsat pr. sekund. Dette er alt, hvad der ikke opnås fra logfilerne, men fra metrikken.

Vladimir Kolobaev: Alexey, jeg vil gerne rette lidt. Der er Grafana. Grafana har en datakilde, som er ClickHouse. Det vil sige, at jeg kan lave forespørgsler fra Grafana direkte til ClickHouse. ClickHouse har et bord med logs, det er ens for alle. Som et resultat vil jeg have adgang til denne logtabel i Grafana og se de anmodninger, som min server anvender. Det ville være fantastisk at have sådan et dashboard.

Jeg cyklede selv. Men jeg har et spørgsmål - hvis det hele er standardiseret, og Grafana bruges af alle, hvorfor har Yandex så ikke et så officielt dashboard?

Kirill Shvakov: Faktisk understøtter den datakilde, som ClickHouse nu, Altinity. Og jeg vil bare give en vektor for, hvor man skal grave, og hvem man skal skubbe. Du kan spørge dem, for Yandex laver stadig ClickHouse, og ikke historien omkring det. Altinity er det vigtigste firma, der i øjeblikket promoverer ClickHouse. De vil ikke forlade ham, men støtte ham. For i princippet, for at uploade et dashboard til Grafanas hjemmeside, skal du kun registrere og uploade det – der er ingen særlige problemer.

Alexey Milovidov: I løbet af det seneste år har ClickHouse tilføjet en masse forespørgselsprofileringsfunktioner. Der er metrics for hver anmodning om ressourceforbrug. Og for nylig er der tilføjet en forespørgselsprofiler på endnu lavere niveau for at se, hvor forespørgslen bruger hvert millisekund. Men for at bruge denne funktionalitet skal jeg åbne konsolklienten og indtaste en forespørgsel, som jeg bliver ved med at glemme. Jeg gemte det et sted og glemmer altid hvor præcist.

Jeg ville ønske, der var et værktøj, der bare siger - her er dine tunge forespørgsler, grupperet efter forespørgselsklasse. Jeg klikkede på en, og de ville fortælle mig, at den derfor er tung. Nu er der ingen sådan løsning. Og det er egentlig ret mærkeligt, når folk spørger mig: "Sig mig, er der nogle færdiglavede dashboards til Grafana?" fra Kostyan. Jeg ved ikke, hvad det er, jeg har ikke selv brugt det«.

Hvordan påvirker man merdzhi, så serveren ikke falder ind i OOM?

Jeg har en tabel, der er kun én partition i tabellen, det er ErstatingMergeTree. Jeg har skrevet data til den i fire år. Jeg var nødt til at lave en ændring i det og slette nogle data.

Jeg gjorde dette, og i løbet af behandlingen af ​​denne anmodning blev al hukommelsen på alle servere i klyngen spist, og alle serverne i klyngen gik ind i OOM sammen. Så rejste de sig alle sammen, begyndte at flette den samme operation, denne datablok, og faldt igen ind i OOM. Så rejste de sig igen og faldt ned igen. Og denne ting stoppede ikke.

Så viste det sig, at det faktisk er en fejl, som fyrene har rettet. Det er meget fedt, mange tak. Men resten forblev. Og nu, når jeg tænker på behovet for at lave en vis fusion i tabellen, har jeg et spørgsmål - hvorfor kan jeg ikke tage disse fusioner og på en eller anden måde påvirke dem? Begræns dem for eksempel med mængden af ​​krævet RAM, eller i princippet ved deres antal, som vil behandle denne særlige tabel.

Jeg har en tabel kaldet "Metrics", bearbejd den for mig i to streams. Ingen grund til at producere ti eller fem fusioner parallelt, gør det i to. Jeg tror, ​​at i to har jeg nok hukommelse, men det er måske ikke nok til at behandle ti. Hvorfor forbliver frygten? For bordet vokser, og en dag vil jeg støde på en situation, der i princippet ikke længere skyldes en fejl, men på grund af, at data vil ændre sig i så stor en mængde, at jeg simpelthen ikke har nok hukommelse på serveren. Og så vil serveren falde ind i OOM under fusionen. Desuden kan jeg annullere mutationen, men fusionen er væk.

Du ved, når du fusionerer, vil serveren ikke falde ind i OOM, for når du fusionerer, bruges mængden af ​​RAM kun til et lille dataområde. Så alt vil være fint uanset mængden af ​​data.

Vladimir Kolobaev: Bøde. Her er øjeblikket sådan, at efter at vi lavede en fejlrettelse, downloadede jeg en ny version til mig selv, og på et andet bord, mindre, hvor der er mange partitioner, lavede jeg en lignende handling. Og under fusionen blev der brændt omkring 100 GB RAM på serveren. Jeg havde 150 travlt, spiste 100, og der var et 50 GB vindue tilbage, så jeg faldt ikke i OOM.

Hvad beskytter mig i øjeblikket mod at falde i OOM, hvis den virkelig bruger 100 GB RAM? Hvad skal man gøre i en situation, hvis RAM på merdzh pludselig løber tør?

Alexey Milovidov: Der er et sådant problem, at forbruget af RAM ikke er begrænset til merdzhi. Og det andet problem er, at hvis en fletning er blevet tildelt, så skal den udføres, fordi den skrives til replikeringsloggen. Replikeringsloggen er de handlinger, der er nødvendige for at bringe replikaen i en konsistent tilstand. Hvis du ikke foretager manuelle manipulationer, som denne replikeringslog vil rulle tilbage, skal fletningen udføres på den ene eller den anden måde.

Det ville selvfølgelig ikke være overflødigt at have en begrænsning på RAM, som "just in case" beskytter mod OOM. Det hjælper ikke sammenlægningen, den starter igen, når en eller anden tærskel, smider en undtagelse og starter så igen - det kommer der ikke noget godt ud af. Men i princippet ville det være nyttigt at indføre denne begrænsning.

Hvordan vil udviklingen af ​​Golang-driveren til ClickHouse foregå?

Golang-driveren skrevet af Kirill Shvakov er nu officielt støttet af ClickHouse-teamet. Han i ClickHouse-lageret, han er nu stor og ægte.

En lille note. Der er et vidunderligt og elsket lager af normale former for uendelig orden - dette er Vertica. De har også deres egen officielle python-driver, som vedligeholdes af Vertica-udviklere. Og flere gange skete det, at versionerne af lageret og versionerne af driveren skiltes ret brat, og driveren holdt op med at fungere på et tidspunkt. Og det andet øjeblik. Support til denne officielle driver, forekommer det mig, vedligeholdes af "nippel"-systemet - du skriver et problem til dem, og det hænger for evigt.

Jeg har to spørgsmål. Nu er Kirills Golang-driver en næsten standard måde at kommunikere fra Golang med ClickHouse. Medmindre nogen stadig kommunikerer gennem http-grænsefladen, fordi han kan lide det så meget. Hvordan vil denne driver blive udviklet? Vil det blive synkroniseret med nogle brydende ændringer i selve depotet? Og hvad er proceduren for at overveje spørgsmålet?

Kirill Shvakov: Den første er, hvordan alt er indrettet bureaukratisk. Dette punkt er ikke blevet diskuteret, så jeg har ikke noget at svare på.

For at besvare spørgsmålet om problemet har vi brug for en lille historie om chaufføren. Jeg arbejdede for en virksomhed, der havde en masse data. Det var en reklamespinner med et enormt antal begivenheder, der skulle gemmes et sted. Og på et tidspunkt dukkede ClickHouse op. Vi hældte data ind i det, og først var alt fint, men så faldt ClickHouse. På det tidspunkt besluttede vi, at vi ikke havde brug for det.

Et år senere vendte vi tilbage til ideen om at bruge ClickHouse, og vi skulle på en eller anden måde skrive data der. Indspillet var dette - jernet er meget svagt, der er få ressourcer. Men vi har altid arbejdet på denne måde, og derfor kiggede vi mod den indfødte protokol.

Da vi arbejdede på Go, var det klart, at vi havde brug for en Go-chauffør. Jeg gjorde det næsten på fuld tid – det var min arbejdsopgave. Indtil et vist punkt tog vi det op, og i princippet var der ingen, der forventede, at andre end os ville bruge det. Så kom CloudFlare med præcis det samme problem, og i et stykke tid arbejdede vi meget problemfrit med dem, fordi de havde de samme opgaver. Og vi gjorde det både i selve ClickHouse og i driveren.

På et tidspunkt stoppede jeg simpelthen med det, fordi min aktivitet i forhold til ClickHouse og med arbejde har ændret sig lidt. Derfor er spørgsmål ikke lukket. Med jævne mellemrum forpligter folk, der har brug for noget, sig til depotet. Så ser jeg på pull-anmodningen og nogle gange redigerer jeg endda noget selv, men det sker sjældent.

Jeg vil tilbage til chaufføren. For et par år siden, da det hele startede, var ClickHouse også anderledes og med andre funktioner. Nu er der en forståelse for, hvordan man laver driveren om, så den er god. Hvis dette sker, vil version 2 alligevel være inkompatibel på grund af akkumulerede krykker.

Jeg ved ikke, hvordan jeg skal arrangere dette. Jeg har ikke meget tid selv. Hvis nogle mennesker afslutter chaufføren, kan jeg hjælpe dem og fortælle dem, hvad de skal gøre. Men det er Yandex' aktive deltagelse i udviklingen af ​​projektet, der endnu ikke er blevet diskuteret på nogen måde.

Alexey Milovidov: Faktisk er der ikke noget bureaukrati omkring disse chauffører endnu. Det eneste er, at de flyttes til en officiel organisation, det vil sige, at denne driver er anerkendt som den officielle standardløsning for Go. Der er nogle andre drivere, men de kommer separat.

Vi har ikke nogen udvikling for disse chauffører inde. Spørgsmålet er, om vi kan ansætte en person, ikke specifikt til denne chauffør, men til udvikling af alle samfundschauffører, eller om vi kan finde nogen udenfor.

Ekstern ordbog er ikke hævet efter genstart med lazy_load aktiveret. Hvad skal man gøre?

Vi har lazy_load-indstillingen aktiveret, og efter at serveren er genstartet, rejser selve ordbogen sig ikke. Den hæves først, når brugeren har adgang til denne ordbog. Og det giver en fejl ved det første opkald. Er det muligt på en eller anden måde automatisk at indlæse ordbøger ved hjælp af ClickHouse, eller skal du altid selv kontrollere deres beredskab, så brugerne ikke modtager fejl?

Måske har vi en gammel version af ClickHouse, så ordbogen blev ikke automatisk indlæst. Kunne det være?

For det første kan ordbøger tvangsindlæses ved hjælp af forespørgslen system genindlæs ordbøger. For det andet om fejlen - hvis ordbogen allerede er indlæst, vil forespørgslerne arbejde på de data, der blev indlæst. Hvis ordbogen endnu ikke er blevet indlæst, vil den blive indlæst lige på tidspunktet for anmodningen.

For tunge ordbøger er dette ikke særlig praktisk. For eksempel skal du hente en million rækker fra MySQL. Nogen foretager et simpelt valg, men dette valg venter på den samme million rækker. Der er to løsninger her. Den første er at slå lazy_load fra. Det andet er, når serveren stiger, før du tænder for belastningen på den, gør system genindlæs ordbog eller bare udføre en forespørgsel, der bruger en ordbog. Så vil ordbogen blive indlæst. Du skal kontrollere tilgængeligheden af ​​ordbøger med lazy_load indstillingen aktiveret, fordi ClickHouse ikke trækker dem op automatisk.

Svaret på det sidste spørgsmål er enten versionen er gammel, eller også skal den fejlfindes.

Hvad med det faktum, at systemgenindlæser ordbøger ikke indlæser nogen af ​​de mange ordbøger, hvis mindst en af ​​dem går ned med en fejl?

Der er et andet spørgsmål om systemgenindlæsningsordbøger. Vi har to ordbøger - den ene er ikke indlæst, den anden er indlæst. Systemgenindlæsningsordbøger i dette tilfælde indlæser ingen ordbog, og du skal indlæse en specifik ordbog punkt-til-punkt ved dens navn ved at bruge systemgenindlæsningsordbogen. Er dette også relateret til ClickHouse-versionen?

Jeg vil gerne behage. Denne adfærd har ændret sig. Så hvis du opdaterer ClickHouse, ændres det også. Hvis du ikke er tilfreds med den nuværende adfærd system genindlæs ordbøger, opdater, og lad os håbe, at det ændrer sig til det bedre.

Er der en måde at konfigurere detaljerne i ClickHouse-konfigurationen på, men ikke tænde dem for fejl?

Det næste spørgsmål handler om fejl relateret til ordbogen, nemlig detaljer. Vi har registreret forbindelsesoplysningerne i ClickHouse-konfigurationen til ordbogen, og i tilfælde af en fejl modtager vi disse detaljer og adgangskoden som svar.

Vi løste denne fejl ved at tilføje detaljer til ODBC-driverens konfiguration. Er der en måde at konfigurere detaljerne i ClickHouse-konfigurationen på, men ikke at vise disse detaljer på fejl?

Her er løsningen virkelig - at angive disse legitimationsoplysninger i odbc.ini, og i selve ClickHouse, skal du kun angive ODBC-datakildenavnet. Dette vil ikke ske for andre ordbogskilder - hverken for en ordbog med MySQL, eller for resten, bør du ikke se adgangskoden i fejlmeddelelsen. Til ODBC vil jeg også kigge - hvis der er sådan noget, skal du bare fjerne det.

Bonus: baggrunde for Zuma fra samvær

Ved at klikke på billedet for de mest vedholdende læsere, åbnes bonusbaggrunde fra forsamlinger. Slukker ilden sammen med Avitos teknologi-maskoter, konfererer med kolleger fra systemadministratorens værelse eller en gammeldags computerklub og afholder en daglig under broen på baggrund af graffiti.

ClickHouse for avancerede brugere i spørgsmål og svar

Kilde: www.habr.com

Tilføj en kommentar