ClickHouse for avanserte brukere i spørsmål og svar

I april samlet Avito-ingeniører seg for nettmøter med den viktigste ClickHouse-utvikleren Alexey Milovidov og Kirill Shvakov, en Golang-utvikler fra Integros. Vi diskuterte hvordan vi bruker et databasestyringssystem og hvilke vanskeligheter vi møter.

Basert på møtet har vi satt sammen en artikkel med eksperters svar på våre og publikums spørsmål om sikkerhetskopiering, omdeling av data, eksterne ordbøker, Golang-driveren og oppdatering av ClickHouse-versjoner. Det kan være nyttig for utviklere som allerede jobber aktivt med Yandex DBMS og er interessert i nåtiden og fremtiden. Som standard er svarene av Alexey Milovidov, med mindre annet er skrevet.

Vær forsiktig, det er mye tekst under snittet. Vi håper at innholdet med spørsmål vil hjelpe deg å navigere.

ClickHouse for avanserte brukere i spørsmål og svar

Innhold

Hvis du ikke vil lese teksten, kan du se opptaket av samlingene på vår YouTube-kanal. Tidskoder er i den første kommentaren under videoen.

ClickHouse oppdateres kontinuerlig, men våre data er det ikke. Hva skal man gjøre med det?

ClickHouse oppdateres kontinuerlig, og våre data, som ble optimalisert sluttbehandlet, er ikke oppdatert og er i en sikkerhetskopi.

La oss si at vi hadde et problem og at dataene gikk tapt. Vi bestemte oss for å gjenopprette, og det viste seg at de gamle partisjonene, som er lagret på backup-serverne, er veldig forskjellige fra den gjeldende versjonen av ClickHouse. Hva skal man gjøre i en slik situasjon, og er det mulig?

En situasjon der du gjenopprettet data fra en sikkerhetskopi i et gammelt format, men den ikke kobles til den nye versjonen, er umulig. Vi sørger for at dataformatet i ClickHouse alltid forblir bakoverkompatibelt. Dette er mye viktigere enn bakoverkompatibilitet når det gjelder funksjonalitet hvis oppførselen til noen sjelden brukte funksjoner har endret seg. Den nye versjonen av ClickHouse skal alltid kunne lese dataene som er lagret på disken. Dette er loven.

Hva er gjeldende beste praksis for sikkerhetskopiering av data fra ClickHouse?

Hvordan lage sikkerhetskopier, tatt i betraktning at vi har optimalisert endelige operasjoner, en enorm database med terabyte, og data som er oppdatert, for eksempel, for de siste tre dagene, og så skjer ingen prosedyrer med det?

Vi kan lage vår egen løsning og skrive på bash: samle disse sikkerhetskopiene på en slik og en måte. Kanskje det ikke er nødvendig å krykke noe, og sykkelen ble oppfunnet for lenge siden?

La oss starte med de beste fremgangsmåtene. Mine kolleger anbefaler alltid, som svar på spørsmål om sikkerhetskopiering, å minne dem om Yandex.Cloud-tjenesten, hvor dette problemet allerede er løst. Så bruk den hvis mulig.

Det finnes ingen komplett løsning for sikkerhetskopiering, hundre prosent innebygd i ClickHouse. Det er noen emner som kan brukes. For å få en komplett løsning må du enten tukle litt manuelt, eller lage wrappers i form av skript.

Jeg starter med de enkleste løsningene og avslutter med de mest sofistikerte, avhengig av datavolumet og klyngens størrelse. Jo større klyngen er, desto mer kompleks blir løsningen.

Hvis tabellen med data kun opptar noen få gigabyte, kan sikkerhetskopiering gjøres slik:

  1. Lagre tabelldefinisjon, dvs. metadata − vis opprett tabell.
  2. Lag en dump med ClickHouse-klienten - velg * fra bordet å lagre. Som standard vil du motta en fil i TabSeparated-format. Hvis du vil være mer effektiv, kan du gjøre det i Native-format.

Hvis mengden data er større, vil sikkerhetskopieringen ta mer tid og mye plass. Dette kalles en logisk sikkerhetskopi; den er ikke knyttet til ClickHouse-dataformatet. Hvis det er det, kan du som en siste utvei ta en sikkerhetskopi og laste den opp til MySQL for gjenoppretting.

For mer avanserte tilfeller har ClickHouse en innebygd mulighet til å lage et øyeblikksbilde av partisjoner i det lokale filsystemet. Denne funksjonen er tilgjengelig på forespørsel endre tabell fryse partisjon. Eller rett og slett endre bordfrysing - Dette er et øyeblikksbilde av hele tabellen.

Øyeblikksbildet vil bli opprettet konsekvent for én tabell på én shard, det vil si at det er umulig å lage et konsistent øyeblikksbilde av hele klyngen på denne måten. Men for de fleste oppgaver er det ikke noe slikt behov, og det er nok å utføre en forespørsel på hvert shard og få et konsistent øyeblikksbilde. Den er laget i form av hardlinks og tar derfor ikke opp ekstra plass. Deretter kopierer du dette øyeblikksbildet til backupserveren eller til lagringen du bruker for sikkerhetskopiering.

Å gjenopprette en slik sikkerhetskopi er ganske enkelt. Lag først tabeller ved å bruke eksisterende tabelldefinisjoner. Kopier deretter de lagrede øyeblikksbildene av partisjonene til Directory-Detached for disse tabellene og kjør spørringen fest partisjon. Denne løsningen er ganske egnet for de mest seriøse datamengdene.

Noen ganger trenger du noe enda kulere - i tilfeller der du har titalls eller hundrevis av terabyte på hver server og hundrevis av servere. Det er en løsning her som jeg plukket opp fra mine kolleger fra Yandex.Metrica. Jeg vil ikke anbefale det til alle – les det og avgjør selv om det passer eller ikke.

Først må du lage flere servere med store diskhyller. Deretter, på disse serverne, heve flere ClickHouse-servere og konfigurere dem slik at de fungerer som en annen replika for de samme shards. Og bruk deretter et filsystem eller et verktøy på disse serverne som lar deg lage øyeblikksbilder. Det er to alternativer her. Det første alternativet er LVM-øyeblikksbilder, det andre alternativet er ZFS på Linux.

Etter det, hver dag du trenger å lage et øyeblikksbilde, vil det ligge og ta opp litt plass. Naturligvis, hvis dataene endres, vil mengden plass øke over tid. Dette øyeblikksbildet kan tas ut når som helst og dataene gjenopprettes, en så merkelig løsning. I tillegg må vi også begrense disse replikaene i konfigurasjonen slik at de ikke prøver å bli ledere.

Vil det være mulig å organisere et kontrollert etterslep av replikaer i skaftene?

I år planlegger du å lage skaft i ClickHouse. Vil det være mulig å organisere et kontrollert etterslep av replikaer i dem? Vi vil gjerne bruke den til å beskytte oss mot negative scenarier med endringer og andre endringer.

Er det mulig å gjøre en slags tilbakestilling for endringer? For eksempel, i en eksisterende sjakt, ta og si at inntil dette øyeblikket bruker du endringene, og fra dette øyeblikket slutter du å bruke endringene?

Hvis en kommando kom til klyngen vår og brøt den, så har vi en betinget replika med en times forsinkelse, der vi kan si at la oss bruke den for øyeblikket, men vi vil ikke bruke endringer på den de siste ti minuttene?

Først om det kontrollerte etterslepet av replikaer. Det var en slik forespørsel fra brukere, og vi opprettet et problem på Github med forespørselen: "Hvis noen trenger dette, liker det, legg et hjerte." Ingen leverte, og saken ble avsluttet. Du kan imidlertid allerede få denne muligheten ved å sette opp ClickHouse. Riktignok, bare fra og med versjon 20.3.

ClickHouse utfører hele tiden datasammenslåing i bakgrunnen. Når en sammenslåing er fullført, erstattes et visst sett med databiter med en større del. Samtidig fortsetter databiter som var der før å forbli på disken en stund.

For det første fortsetter de å lagres så lenge det er utvalgte spørringer som bruker dem, for å gi ikke-blokkerende operasjon. Utvalgte søk leses enkelt fra gamle biter.

For det andre er det også en tidsterskel - gamle databiter ligger på disken i åtte minutter. Disse åtte minuttene kan tilpasses og til og med gjøres om til én dag. Dette vil koste diskplass: Avhengig av dataflyten, viser det seg at den siste dagen vil dataene ikke bare dobles, de kan bli fem ganger mer. Men hvis det er et alvorlig problem, kan du stoppe ClickHouse-serveren og ordne opp i alt.

Nå oppstår spørsmålet om hvordan dette beskytter mot endringer. Det er verdt å ta en dypere titt her, for i eldre versjoner av ClickHouse fungerte alteret på en slik måte at det ganske enkelt byttet deler direkte. Det er et stykke data med noen filer, og vi gjør f.eks. endre slippkolonne. Deretter fjernes denne kolonnen fysisk fra alle biter.

Men fra og med versjon 20.3 har endringsmekanismen blitt fullstendig endret, og nå er databiter alltid uforanderlige. De endres ikke i det hele tatt - endringer fungerer nå omtrent på samme måte som sammenslåinger. I stedet for å erstatte en del på stedet, lager vi en ny. I den nye delen blir filer som ikke har endret seg hardlinks, og hvis vi sletter en kolonne vil den rett og slett mangle i den nye delen. Det gamle stykket vil bli slettet som standard etter åtte minutter, og her kan du justere innstillingene nevnt ovenfor.

Det samme gjelder endringer som mutasjoner. Når du gjør det endre slett eller endre oppdatering, det endrer ikke stykket, men skaper et nytt. Og sletter så den gamle.

Hva om tabellstrukturen har endret seg?

Hvordan gjenopprette en sikkerhetskopi som ble laget med den gamle ordningen? Og det andre spørsmålet handler om saken med øyeblikksbilder og filsystemverktøy. Er Btrfs bra her i stedet for ZFS på Linux LVM?

Hvis du gjør fest partisjon partisjoner med en annen struktur, vil ClickHouse fortelle deg at dette ikke er mulig. Dette er løsningen. Den første er å lage en midlertidig tabell av typen MergeTree med den gamle strukturen, legge ved data der ved å bruke attach, og foreta en endringsspørring. Deretter kan du enten kopiere eller overføre disse dataene og legge ved på nytt, eller bruke en forespørsel endre tabell flytte partisjon.

Nå er det andre spørsmålet om Btrfs kan brukes. Til å begynne med, hvis du har LVM, er LVM-øyeblikksbilder nok, og filsystemet kan være ext4, det spiller ingen rolle. Med Btrts avhenger alt av din erfaring med å bruke den. Dette er et modent filsystem, men det er fortsatt noen mistanker om hvordan alt vil fungere i praksis i et bestemt scenario. Jeg vil ikke anbefale å bruke dette med mindre du har Btrfs i produksjon.

Hva er de nåværende beste fremgangsmåtene for omdeling av data?

Spørsmålet om resharding er komplekst og mangefasettert. Det er flere mulige svar her. Du kan gå fra den ene siden og si dette – ClickHouse har ikke en innebygd funksjon for omharding. Men jeg er redd dette svaret ikke vil passe noen. Derfor kan du gå fra den andre siden og si at ClickHouse har mange måter å resharde data på.

Hvis klyngen går tom for plass eller den ikke kan håndtere belastningen, legger du til nye servere. Men disse serverne er tomme som standard, det er ingen data på dem, det er ingen belastning. Du må omorganisere dataene slik at de blir jevnt spredt over den nye, større klyngen.

Den første måten dette kan gjøres på er å kopiere deler av partisjonene til nye servere ved å bruke en forespørsel endre tabellhentingspartisjon. For eksempel hadde du partisjoner etter måned, og du tar den første måneden av 2017 og kopierer den til en ny server, og kopierer deretter den tredje måneden til en annen ny server. Og dette gjør du til det blir mer eller mindre jevnt.

Overføring kan bare utføres for de partisjonene som ikke endres under opptak. For nye partisjoner må opptak deaktiveres, fordi overføringen deres ikke er atomær. Ellers vil du ende opp med duplikater eller hull i dataene. Imidlertid er denne metoden praktisk og fungerer ganske effektivt. Ferdige komprimerte partisjoner overføres over nettverket, det vil si at dataene ikke komprimeres eller omkodes.

Denne metoden har en ulempe, og den avhenger av skjæringsordningen, om du lovet denne skjæringsordningen, hvilken skjæringsnøkkel du hadde. I ditt eksempel for tilfellet med beregninger, er sharding-nøkkelen hashen til banen. Når du velger en distribuert tabell, går den til alle shards i klyngen samtidig og tar data derfra.

Dette betyr at det faktisk ikke spiller noen rolle for deg hvilke data som havnet på hvilken shard. Hovedsaken er at data langs en vei havner på ett skår, men hvilken er ikke viktig. I dette tilfellet er overføring av ferdige partisjoner perfekt, fordi med utvalgte spørringer vil du også motta fullstendige data - enten før omdeling eller etter, spiller ordningen ingen rolle.

Men det er saker som er mer komplekse. Hvis du på applikasjonslogikknivået er avhengig av en spesiell sharding-ordning, at denne klienten er plassert på en slik og en shard, og forespørselen kan sendes direkte dit, og ikke til den distribuerte tabellen. Eller du bruker en ganske ny versjon av ClickHouse og har aktivert innstillingen optimalisere hoppe over ubrukte skår. I dette tilfellet, under valgspørringen, vil uttrykket i where-delen bli analysert, og det vil bli beregnet hvilke shards som må brukes i henhold til sharding-skjemaet. Dette fungerer forutsatt at dataene er partisjonert nøyaktig i henhold til dette skjæringsskjemaet. Hvis du omorganiserte dem manuelt, kan korrespondansen endres.

Så dette er metode nummer én. Og jeg venter på svaret ditt, om metoden er egnet, eller la oss gå videre.

Vladimir Kolobaev, hovedsystemadministrator hos Avito: Alexey, metoden du nevnte fungerer ikke særlig bra når du trenger å spre belastningen, inkludert lesing. Vi kan ta en partisjon som er månedlig og kan ta forrige måned til en annen node, men når det kommer en forespørsel om disse dataene, vil vi bare laste dem. Men vi vil gjerne laste hele klyngen, for ellers vil hele lesebelastningen i noen tid bli behandlet av to shards.

Alexey Milovidov: Svaret her er merkelig - ja, det er dårlig, men det kan fungere. Jeg skal forklare nøyaktig hvordan. Det er verdt å se på belastningsscenarioet som kommer bak dataene dine. Hvis dette er overvåkingsdata, kan vi nesten helt sikkert si at de aller fleste forespørsler er for ferske data.

Du installerte nye servere, migrerte gamle partisjoner, men endret også hvordan ferske data registreres. Og ferske data vil bli spredt over hele klyngen. Etter bare fem minutter vil derfor forespørsler for de siste fem minuttene laste klyngen jevnt; etter en dag vil forespørsler i XNUMX timer laste klyngen jevnt. Og forespørsler for forrige måned vil dessverre bare gå til deler av klyngeserverne.

Men ofte vil du ikke ha forespørsler spesifikt for februar 2019. Mest sannsynlig, hvis forespørsler går inn i 2019, vil de være for hele 2019 - i en lang periode, og ikke for et lite utvalg. Og slike forespørsler vil også kunne belaste klyngen jevnt. Men generelt sett er påpekningen din helt riktig om at dette er en ad hoc-løsning som ikke sprer dataene helt jevnt.

Jeg har noen flere punkter for å svare på spørsmålet. En av dem handler om hvordan man i utgangspunktet skal utforme et skjæringsskjema slik at re-sharding vil forårsake mindre smerte. Dette er ikke alltid mulig.

For eksempel har du overvåkingsdata. Overvåkingsdata vokser av tre grunner. Den første er akkumulering av historiske data. Det andre er trafikkvekst. Og den tredje er en økning i antall ting som er gjenstand for overvåking. Det er nye mikrotjenester og beregninger som må lagres.

Det er mulig at av disse er den største økningen knyttet til den tredje årsaken – økningen i bruken av overvåking. Og i dette tilfellet er det verdt å se på belastningens art, hva er de viktigste utvalgsspørsmålene. Grunnleggende utvalgsspørringer vil mest sannsynlig være basert på noen delsett av beregninger.

For eksempel CPU-bruk på noen servere av en tjeneste. Det viser seg at det er en viss undergruppe av nøkler som du får disse dataene med. Og selve forespørselen om disse dataene er mest sannsynlig ganske enkel og fullføres på titalls millisekunder. Brukes til overvåkingstjenester og dashbord. Jeg håper jeg forstår dette riktig.

Vladimir Kolobaev: Faktum er at vi veldig ofte appellerer til historiske data, siden vi sammenligner dagens situasjon med den historiske i sanntid. Og det er viktig for oss å ha rask tilgang til en stor mengde data, og ClickHouse gjør en utmerket jobb med dette.

Du har helt rett, vi opplever de fleste leseforespørslene den siste dagen, som ethvert overvåkingssystem. Men samtidig er belastningen på historiske data også ganske stor. Det er i utgangspunktet fra et varslingssystem som går rundt hvert trettiende sekund og sier til ClickHouse: «Gi meg dataene for de siste seks ukene. Bygg meg nå et slags glidende gjennomsnitt fra dem, og la oss sammenligne den nåværende verdien med den historiske."

Jeg vil gjerne si at for slike nylige forespørsler har vi en annen liten tabell der vi lagrer bare to dager med data, og de viktigste forespørslene flyr inn i den. Vi sender kun store historiske forespørsler til det store sønderdelte bordet.

Alexey Milovidov: Dessverre viser det seg å være dårlig anvendelig for scenarioet ditt, men jeg vil fortelle deg en beskrivelse av to dårlige og komplekse skjæringsordninger som ikke trenger å brukes, men som brukes i mine venners tjeneste.

Det er en hovedklynge med Yandex.Metrica-arrangementer. Hendelser er sidevisninger, klikk og konverteringer. De fleste forespørsler går til et bestemt nettsted. Du åpner Yandex.Metrica-tjenesten, du har et nettsted - avito.ru, gå til rapporten, og det sendes en forespørsel om nettstedet ditt.

Men det er andre forespørsler - analytiske og globale - som kommer fra interne analytikere. For sikkerhets skyld merker jeg at interne analytikere bare forespørsler om Yandex-tjenester. Men ikke desto mindre opptar selv Yandex-tjenester en betydelig andel av all data. Dette er forespørsler ikke for spesifikke tellere, men for bredere filtrering.

Hvordan organisere data på en slik måte at alt fungerer effektivt for én teller, og globale spørringer også? En annen vanskelighet er at antallet forespørsler i ClickHouse for Metrics-klyngen er flere tusen per sekund. Samtidig kan ikke én ClickHouse-server håndtere ikke-trivielle forespørsler, for eksempel flere tusen per sekund.

Klyngestørrelsen er seks hundre-noe servere. Hvis du ganske enkelt trekker en distribuert tabell over denne klyngen og sender flere tusen forespørsler dit, vil det bli enda verre enn å sende dem til én server. På den annen side blir muligheten for at dataene fordeles jevnt, og vi går og ber om fra alle servere, umiddelbart avvist.

Det er et alternativ som er diametralt motsatt. Tenk om vi deler dataene på tvers av nettsteder, og en forespørsel om ett nettsted går til ett shard. Nå vil klyngen være i stand til å håndtere ti tusen forespørsler per sekund, men på én shard vil enhver forespørsel fungere for sakte. Det vil ikke lenger skalere når det gjelder gjennomstrømning. Spesielt hvis dette er nettstedet avito.ru. Jeg vil ikke avsløre hemmeligheten hvis jeg sier at Avito er en av de mest besøkte sidene i RuNet. Og å behandle det på ett skår ville være galskap.

Derfor er skjæringsordningen utformet på en mer utspekulert måte. Hele klyngen er delt inn i en rekke klynger, som vi kaller lag. Hver klynge inneholder fra et dusin til flere dusin skår. Det er tretti-ni slike klynger totalt.

Hvordan skalerer alt dette? Antall klynger endres ikke - som det var trettini for noen år siden, er det fortsatt slik. Men innenfor hver av dem øker vi gradvis antall shards etter hvert som vi samler data. Og sharding-ordningen som helhet er slik: disse klyngene er delt inn i nettsider, og for å forstå hvilken nettside som ligger på hvilken klynge, brukes en egen metabase i MySQL. Ett sted - på en klynge. Og inne i den skjer sharding i henhold til besøkendes IDer.

Ved opptak deler vi dem med resten av delingen av besøks-ID. Men når du legger til et nytt shard, endres sharding-ordningen; vi fortsetter å dele, men med resten av divisjonen med et annet tall. Dette betyr at én besøkende allerede er plassert på flere servere, og du kan ikke stole på dette. Dette gjøres utelukkende for å sikre at dataene blir bedre komprimert. Og når vi sender forespørsler, går vi til tabellen Distribuert, som ser på klyngen og får tilgang til dusinvis av servere. Dette er et så dumt opplegg.

Men historien min vil være ufullstendig hvis jeg ikke sier at vi forlot denne ordningen. I den nye ordningen endret vi alt og kopierte alle dataene ved hjelp av clickhouse-kopimaskin.

I den nye ordningen er alle tomter delt inn i to kategorier - store og små. Jeg vet ikke hvordan terskelen ble valgt, men resultatet var at store nettsteder er registrert på en klynge, der det er 120 shards med tre replikaer hver - det vil si 360 servere. Og skjæringsordningen er slik at enhver forespørsel går til alle skjærene på en gang. Hvis du nå åpner en rapportside for avito.ru i Yandex.Metrica, vil forespørselen gå til 120 servere. Det er få store nettsteder i RuNet. Og forespørslene er ikke tusen per sekund, men enda mindre enn hundre. Alt dette tygges stille opp av Distributed-tabellen, som hver av dem behandler med 120 servere.

Og den andre klyngen er for små nettsteder. Her er et shardingskjema basert på nettsteds-IDen, og hver forespørsel går til nøyaktig ett shard.

ClickHouse har et klikkhus-kopiverktøy. Kan du fortelle oss om henne?

Jeg vil si med en gang at denne løsningen er mer tungvint og noe mindre produktiv. Fordelen er at den smører dataene helt i henhold til mønsteret du spesifiserer. Men ulempen med verktøyet er at det ikke omharder i det hele tatt. Den kopierer data fra ett klyngeskjema til et annet klyngeskjema.

Det betyr at for at det skal fungere må du ha to klynger. De kan være plassert på de samme serverne, men likevel vil dataene ikke flyttes trinnvis, men kopieres.

For eksempel var det fire servere, nå er det åtte. Du oppretter en ny distribuert tabell på alle servere, nye lokale tabeller og starter clickhouse-copier, og angir i den arbeidsskjemaet som den skal lese derfra, godtar det nye skjæringsskjemaet og overfører dataene dit. Og på gamle servere vil du trenge halvannen ganger mer plass enn det er nå, fordi de gamle dataene må forbli på dem, og halvparten av de samme gamle dataene kommer på toppen av dem. Hvis du på forhånd trodde at dataene må omskjæres og det er plass, er denne metoden egnet.

Hvordan fungerer clickhouse-kopimaskin inne? Den deler opp alt arbeidet i et sett med oppgaver for å behandle en partisjon av en tabell på ett skjær. Alle disse oppgavene kan utføres parallelt, og clickhouse-kopimaskin kan kjøres på forskjellige maskiner i flere tilfeller, men det den gjør for én partisjon er ikke noe mer enn et innsettingsvalg. Dataene leses, dekomprimeres, partisjoneres på nytt, deretter komprimeres igjen, skrives et sted og sorteres på nytt. Dette er en tøffere avgjørelse.

Du hadde en pilotting som heter resharding. Hva med henne?

Tilbake i 2017 hadde du en pilotting som heter resharding. Det er til og med et alternativ i ClickHouse. Slik jeg forstår det tok det ikke av. Kan du fortelle meg hvorfor dette skjedde? Det ser ut til å være veldig relevant.

Hele problemet er at hvis det er nødvendig å omskjære data på plass, kreves det svært kompleks synkronisering for å gjøre dette atomært. Da vi begynte å se på hvordan denne synkroniseringen fungerer, ble det klart at det var grunnleggende problemer. Og disse grunnleggende problemene er ikke bare teoretiske, men begynte umiddelbart å vise seg i praksis i form av noe som kan forklares veldig enkelt - ingenting fungerer.

Er det mulig å slå sammen alle datastykker før de flyttes til trege disker?

Spørsmål om TTL med overgangen til slow disk-alternativet i forbindelse med fusjoner. Er det en annen måte enn via cron å slå sammen alle delene til én før du flytter dem til trege disker?

Svaret på spørsmålet er at det på en eller annen måte automatisk limer alle bitene i en før du overfører dem - nei. Jeg tror ikke dette er nødvendig. Du trenger ikke å slå sammen alle delene til én, men bare stole på at de automatisk blir overført til trege disker.

Vi har to kriterier for overgangsregler. Den første er som den er fylt. Hvis det gjeldende lagringsnivået har mindre enn en viss prosentandel ledig plass, velger vi én del og flytter den til tregere lagring. Eller rettere sagt, ikke tregere, men den neste - ettersom du konfigurerer.

Det andre kriteriet er størrelse. Det handler om å flytte store brikker. Du kan justere terskelen i henhold til ledig plass på hurtigdisken, og dataene overføres automatisk.

Hvordan migrere til nye versjoner av ClickHouse hvis det ikke er noen måte å sjekke kompatibiliteten på forhånd?

Dette temaet diskuteres jevnlig i ClickHouse telegramchat tar hensyn til ulike versjoner, og fortsatt. Hvor trygt er det å oppgradere fra versjon 19.11 til 19.16 og for eksempel fra 19.16 til 20.3. Hva er den beste måten å migrere til nye versjoner uten å kunne sjekke kompatibilitet i sandkassen på forhånd?

Det er flere "gyldne" regler her. Først - les endringsloggen. Den er stor, men det er egne avsnitt om endringer som ikke er kompatible bakover. Ikke behandle disse punktene som et rødt flagg. Dette er vanligvis mindre inkompatibiliteter som involverer noen kantfunksjonalitet som du sannsynligvis ikke bruker.

For det andre, hvis det ikke er noen måte å sjekke kompatibilitet i sandkassen, og du vil oppdatere umiddelbart i produksjonen, er anbefalingen at du ikke trenger å gjøre dette. Lag først en sandkasse og test. Hvis det ikke er noe testmiljø, så har du mest sannsynlig ikke et veldig stort selskap, noe som betyr at du kan kopiere noen av dataene til din bærbare datamaskin og sørge for at alt fungerer som det skal på den. Du kan til og med heve flere replikaer lokalt på maskinen din. Eller du kan hente en ny versjon et sted i nærheten og laste opp noen av dataene der – det vil si lage et improvisert testmiljø.

En annen regel er å ikke oppdatere før en uke etter utgivelsen av versjonen på grunn av feil i produksjonen og påfølgende hurtigreparasjoner. La oss finne ut nummereringen av ClickHouse-versjoner for ikke å bli forvirret.

Det er versjon 20.3.4. Tallet 20 indikerer produksjonsåret - 2020. Fra synspunktet til hva som er inne, spiller dette ingen rolle, så vi vil ikke ta hensyn til det. Neste - 20.3. Vi øker det andre tallet - i dette tilfellet 3 - hver gang vi slipper en utgivelse med litt ny funksjonalitet. Hvis vi ønsker å legge til en funksjon til ClickHouse, må vi øke dette tallet. Det vil si at i versjon 20.4 vil ClickHouse fungere enda bedre. Det tredje sifferet er 20.3.4. Her 4 er antall patchutgivelser der vi ikke la til nye funksjoner, men fikset noen feil. Og 4 betyr at vi gjorde det fire ganger.

Ikke tro at dette er noe forferdelig. Vanligvis kan brukeren installere den nyeste versjonen og den vil fungere uten problemer med oppetid per år. Men forestill deg at i en funksjon for behandling av punktgrafikk, som ble lagt til av våre kinesiske kamerater, krasjer serveren når du sender feil argumenter. Vi har et ansvar for å fikse dette. Vi vil gi ut en ny oppdateringsversjon og ClickHouse vil bli mer stabil.

Hvis du har ClickHouse kjørende i produksjon, og en ny versjon av ClickHouse er utgitt med tilleggsfunksjoner - for eksempel er 20.4.1 den aller første, ikke skynd deg å sette den i produksjon den første dagen. Hvorfor er det i det hele tatt nødvendig? Hvis du ikke allerede bruker ClickHouse, kan du installere det, og mest sannsynlig vil alt være bra. Men hvis ClickHouse allerede fungerer stabilt, så hold øye med patcher og oppdateringer for å se hvilke problemer vi fikser.

Kirill Shvakov: Jeg vil gjerne legge til litt om testmiljøer. Alle er veldig redde for testmiljøer og av en eller annen grunn tror de at hvis du har en veldig stor ClickHouse-klynge, så bør testmiljøet være ikke mindre eller minst ti ganger mindre. Det er ikke sånn i det hele tatt.

Jeg kan fortelle deg fra mitt eget eksempel. Jeg har et prosjekt, og det er ClickHouse. Testmiljøet vårt er bare for ham - dette er en liten virtuell maskin i Hetzner for tjue euro, hvor absolutt alt er utplassert. For å gjøre dette har vi full automatisering i Ansible, og derfor spiller det i prinsippet ingen rolle hvor du skal gå - til maskinvareservere eller bare distribuere i virtuelle maskiner.

Hva kan bli gjort? Det ville vært fint å gi et eksempel i ClickHouse-dokumentasjonen på hvordan du distribuerer en liten klynge i ditt eget hjem - i Docker, i LXC, kanskje lag en Ansible-spillebok, fordi forskjellige mennesker har forskjellige distribusjoner. Dette vil forenkle mye. Når du tar og distribuerer en klynge på fem minutter, er det mye lettere å prøve å finne ut av noe. Dette er mye mer praktisk, fordi å skyve inn i en produksjonsversjon som du ikke har testet er en vei til ingensteds. Noen ganger fungerer det og noen ganger ikke. Og derfor er det dårlig å håpe på suksess.

Maxim Kotyakov, senior backend-ingeniør Avito: Jeg vil legge til litt om testmiljøer fra en rekke problemer store selskaper står overfor. Vi har en fullverdig ClickHouse akseptklynge, når det gjelder dataoppsett og innstillinger, er det en nøyaktig kopi av det som er i produksjon. Denne klyngen er distribuert i ganske nedslitte containere med et minimum av ressurser. Vi skriver en viss prosentandel av produksjonsdataene der, heldigvis er det mulig å replikere strømmen i Kafka. Alt der er synkronisert og skalert – både når det gjelder kapasitet og flyt, og i teorien skal det, alt annet likt, oppføre seg som produksjon når det gjelder metrikk. Alt potensielt eksplosivt rulles først inn på dette stativet og står der i flere dager til det er klart. Men naturlig nok er denne løsningen dyr, vanskelig og har ikke-null støttekostnader.

Alexey Milovidov: Jeg skal fortelle deg hvordan testmiljøet til vennene våre fra Yandex.Metrica er. En klynge hadde 600 servere, en annen hadde 360, og det er en tredje og flere klynger. Testmiljøet for en av dem er rett og slett to skår med to replikaer hver. Hvorfor to skår? Slik at du ikke er alene. Og det skal være kopier også. Bare et visst minimumsbeløp du har råd til.

Dette testmiljøet lar deg sjekke om søkene dine fungerer og om noe større er ødelagt. Men ofte oppstår det problemer av en helt annen karakter, når alt fungerer, men det er noen små endringer i belastningen.

La meg gi deg et eksempel. Vi bestemte oss for å installere en ny versjon av ClickHouse. Det har blitt lagt ut på et testmiljø, automatiserte tester er fullført i selve Yandex.Metrica, som sammenligner data på den gamle versjonen og den nye, som kjører hele pipelinen. Og selvfølgelig grønne tester av vår CI. Ellers ville vi ikke engang foreslått denne versjonen.

Alt er bra. Vi begynner å gå over i produksjon. Jeg får melding om at belastningen på grafene har økt flere ganger. Vi ruller tilbake versjonen. Jeg ser på grafen og ser: belastningen økte faktisk flere ganger under utrullingen, og sank tilbake når de rullet ut. Så begynte vi å rulle tilbake versjonen. Og belastningen økte på samme måte og falt tilbake på samme måte. Så konklusjonen er denne: belastningen har økt på grunn av oppsettet, ikke noe overraskende.

Da var det vanskelig å overbevise kolleger om å installere den nye versjonen. Jeg sier: «Det er greit, rull ut. Krysser fingrene, alt ordner seg. Nå har belastningen på grafene økt, men alt er i orden. Hold ut." Generelt gjorde vi dette, og det er det - versjonen ble utgitt for produksjon. Men nesten med hver layout oppstår lignende problemer.

Kill-query skal drepe spørringer, men det gjør den ikke. Hvorfor?

En bruker, en slags analytiker, kom til meg og opprettet en forespørsel som satte ClickHouse-klyngen min. Noen node eller hele klyngen, avhengig av hvilken replika eller shard forespørselen gikk til. Jeg ser at alle CPU-ressursene på denne serveren er i en hylle, alt er rødt. Samtidig svarer ClickHouse selv på forespørsler. Og jeg skriver: "Vennligst vis meg, prosessliste, hvilken forespørsel som genererte denne galskapen."

Jeg finner denne forespørselen og skriver drep til den. Og jeg ser at det ikke skjer noe. Serveren min er i en hylle, ClickHouse gir meg noen kommandoer, viser at serveren er i live, og alt er bra. Men jeg har degradering i alle brukerforespørsler, degradering begynner med poster i ClickHouse, og min kill-forespørsel fungerer ikke. Hvorfor? Jeg trodde kill-query var ment å drepe spørringer, men det gjør det ikke.

Nå kommer det et ganske merkelig svar. Poenget er at kill-query ikke dreper spørringer.

Kill-query merker av i en liten boks kalt "Jeg vil at denne spørringen skal bli drept." Og selve forespørselen ser på dette flagget ved behandling av hver blokk. Hvis den er satt, slutter forespørselen å fungere. Det viser seg at ingen dreper forespørselen, han må selv sjekke alt og stoppe. Og dette bør fungere i alle tilfeller der forespørselen er i tilstanden til å behandle blokker med data. Den vil behandle neste blokk med data, sjekke flagget og stoppe.

Dette fungerer ikke i tilfeller der forespørselen er blokkert på en operasjon. Riktignok er dette mest sannsynlig ikke ditt tilfelle, fordi det, ifølge deg, bruker massevis av serverressurser. Det er mulig at dette ikke fungerer ved ekstern sortering og i enkelte andre detaljer. Men generelt burde dette ikke skje, det er en feil. Og det eneste jeg kan anbefale er å oppdatere ClickHouse.

Hvordan beregne responstid under lesebelastning?

Det er en tabell som lagrer vareaggregater - ulike tellere. Antall linjer er omtrent hundre millioner. Er det mulig å regne med en forutsigbar responstid hvis du heller 1K RPS for 1K varer?

Etter konteksten å dømme snakker vi om lesebelastningen, fordi det ikke er noen problemer med å skrive - til og med tusen, til og med hundre tusen, og noen ganger flere millioner rader kan settes inn.

Leseforespørsler er veldig forskjellige. I utvalg 1 kan ClickHouse utføre omtrent titusenvis av forespørsler per sekund, så selv forespørsler om én nøkkel vil allerede kreve noen ressurser. Og slike punktspørringer vil være vanskeligere enn i noen nøkkelverdidatabaser, fordi det for hver lesing er nødvendig å lese en blokk med data etter indeks. Indeksen vår adresserer ikke hver post, men hvert område. Det vil si at du må lese hele området - dette er 8192 linjer som standard. Og du må dekomprimere den komprimerte datablokken fra 64 KB til 1 MB. Vanligvis tar slike målrettede søk noen få millisekunder å fullføre. Men dette er det enkleste alternativet.

La oss prøve litt enkel aritmetikk. Hvis du ganger noen få millisekunder med tusen, får du noen sekunder. Det er som om det er umulig å holde tritt med tusen forespørsler per sekund, men faktisk er det mulig, fordi vi har flere prosessorkjerner. Så i prinsippet kan ClickHouse noen ganger holde 1000 RPS, men for korte forespørsler, spesifikt målrettede.

Hvis du trenger å skalere en ClickHouse-klynge etter antall enkle forespørsler, så anbefaler jeg det enkleste - øk antall replikaer og send forespørsler til en tilfeldig replika. Hvis én replika har fem hundre forespørsler per sekund, noe som er helt realistisk, vil tre replikaer håndtere halvannet tusen.

Noen ganger kan du selvfølgelig konfigurere ClickHouse for maksimalt antall punktavlesninger. Hva trengs for dette? Den første er å redusere granulariteten til indeksen. I dette tilfellet skal det ikke reduseres til én, men på grunnlag av at antall oppføringer i indeksen vil være flere millioner eller titalls millioner per server. Hvis tabellen har hundre millioner rader, kan granulariteten settes til 64.

Du kan redusere størrelsen på den komprimerte blokken. Det finnes innstillinger for dette min komprimeringsblokkstørrelse, maks komprimeringsblokkstørrelse. De kan reduseres, fylles på nytt med data, og deretter vil målrettede søk være raskere. Men fortsatt er ikke ClickHouse en nøkkelverdidatabase. Et stort antall små forespørsler er et belastningsantimønster.

Kirill Shvakov: Jeg vil gi råd i tilfelle det er vanlige kontoer der. Dette er en ganske standard situasjon når ClickHouse lagrer en slags disk. Jeg har en bruker, han er fra et slikt og et slikt land, og et tredje felt, og jeg må øke noe gradvis. Ta MySQL, lag en unik nøkkel - i MySQL er det en duplikatnøkkel, og i PostgreSQL er det en konflikt - og legg til et plusstegn. Dette vil fungere mye bedre.

Når du ikke har mye data, er det ikke mye vits i å bruke ClickHouse. Det er vanlige databaser og de gjør dette bra.

Hva kan jeg justere i ClickHouse slik at mer data er i hurtigbufferen?

La oss forestille oss en situasjon - serverne har 256 GB RAM, i den daglige rutinen tar ClickHouse omtrent 60-80 GB, på topp - opptil 130. Hva kan aktiveres og justeres slik at mer data er i hurtigbufferen, og følgelig, det er færre turer til disken?

Vanligvis gjør operativsystemets sidebuffer en god jobb med dette. Hvis du bare åpner toppen, ser der cached eller ledig - det står også hvor mye som er cache - så vil du legge merke til at alt ledig minne blir brukt til cachen. Og når du leser disse dataene, vil de ikke bli lest fra disken, men fra RAM. Samtidig kan jeg si at cachen brukes effektivt fordi det er de komprimerte dataene som cache.

Men hvis du vil øke hastigheten på noen enkle spørringer enda mer, er det mulig å aktivere en cache i de dekomprimerte dataene inne i ClickHouse. Det kalles ukomprimert cache. I konfigurasjonsfilen config.xml, sett den ukomprimerte cache-størrelsen til verdien du trenger - jeg anbefaler ikke mer enn halvparten av ledig RAM, fordi resten vil gå under sidebufferen.

I tillegg er det to forespørselsnivåinnstillinger. Første innstilling - bruk ukomprimert cache - inkluderer bruken. Det anbefales å aktivere det for alle forespørsler, bortsett fra tunge, som kan lese alle dataene og tømme hurtigbufferen. Og den andre innstillingen er noe sånt som maksimalt antall linjer for å bruke cachen. Den begrenser automatisk store søk slik at de omgår hurtigbufferen.

Hvordan kan jeg konfigurere storage_configuration for lagring i RAM?

I den nye ClickHouse-dokumentasjonen leste jeg avsnittet relatert med datalagring. Beskrivelsen inneholder et eksempel med rask SSD.

Jeg lurer på hvordan det samme kan konfigureres med volum varmt minne. Og ett spørsmål til. Hvordan fungerer select med denne dataorganisasjonen, vil den lese hele settet eller bare den som er på disken, og er disse dataene komprimert i minnet? Og hvordan fungerer prewhere-seksjonen med en slik dataorganisasjon?

Denne innstillingen påvirker lagringen av databiter, og formatet deres endres ikke på noen måte.
La oss ta en nærmere titt.

Du kan konfigurere datalagring i RAM. Alt som er konfigurert for disken er banen. Du oppretter en tmpfs-partisjon som er montert til en bane i filsystemet. Du spesifiserer denne banen som banen for lagring av data for den hotteste partisjonen, databiter begynner å komme og skrives der, alt er i orden.

Men jeg anbefaler ikke å gjøre dette på grunn av lav pålitelighet, men hvis du har minst tre replikaer i forskjellige datasentre, så er det mulig. Hvis noe skjer, vil dataene bli gjenopprettet. La oss forestille oss at serveren plutselig ble slått av og slått på igjen. Skilleveggen ble montert igjen, men det var ingenting der. Når ClickHouse-serveren starter, ser den at den ikke har disse delene, selv om de ifølge ZooKeeper-metadata burde være der. Han ser på hvilke kopier som har dem, ber om dem og laster dem ned. På denne måten vil dataene bli gjenopprettet.

Slik sett er lagring av data i RAM ikke fundamentalt forskjellig fra lagring på disk, fordi når data skrives til disk, havner det også først i sidebufferen og blir fysisk skrevet senere. Dette avhenger av filsystemets monteringsalternativ. Men i tilfelle vil jeg si at ClickHouse ikke fsynkroniserer når du setter inn.

I dette tilfellet lagres dataene i RAM-en i nøyaktig samme format som på disken. Select-spørringen velger på samme måte brikkene som må leses, velger de nødvendige dataområdene i brikkene og leser dem. Og prewhere fungerer nøyaktig likt, uansett om dataene var i RAM eller på disk.

Opp til hvor mange unike verdier er Low Cardinality effektiv?

Low Cardinality er smart utformet. Den kompilerer dataordbøker, men de er lokale. For det første er det forskjellige ordbøker for hvert stykke, og for det andre, selv innenfor ett stykke kan de være forskjellige for hvert område. Når antallet unike verdier når et terskeltall – én million, tror jeg – blir ordboken ganske enkelt skrinlagt og en ny opprettes.

Svaret er generelt: for hver lokal rekkevidde - for eksempel for hver dag - et sted er opptil en million unike verdier lav kardinalitet effektiv. Etterpå blir det rett og slett en fallback, der mange forskjellige ordbøker vil bli brukt, og ikke bare én. Det vil fungere omtrent det samme som en vanlig strengkolonne, kanskje litt mindre effektiv, men det vil ikke være noen alvorlig ytelsesforringelse.

Hva er de beste fremgangsmåtene for fulltekstsøk i en tabell med fem milliarder rader?

Det er forskjellige svar. Den første er å si at ClickHouse ikke er en fulltekst søkemotor. Det finnes spesielle systemer for dette, f.eks. Elasticsearch и Sphinx. Imidlertid ser jeg i økende grad at folk sier at de bytter fra Elasticsearch til ClickHouse.

Hvorfor skjer dette? De forklarer dette med at Elasticsearch slutter å takle belastningen ved noen volumer, og starter med konstruksjonen av indekser. Indekser blir for tungvinte, og overfører man bare dataene til ClickHouse, viser det seg at de blir lagret flere ganger mer effektivt volummessig. Samtidig var søk ofte ikke slik at det var nødvendig å finne en setning i hele datavolumet, tatt i betraktning morfologi, men helt andre. Finn for eksempel noen etterfølger av byte i loggene de siste timene.

I dette tilfellet oppretter du en indeks i ClickHouse, hvor det første feltet vil være dato og klokkeslett. Og det største dataavskjæringspunktet vil være basert på datoperioden. Innenfor det valgte datointervallet er det som regel allerede mulig å utføre et fulltekstsøk, selv ved bruk av brute force-metoden med like. Like-operatøren i ClickHouse er den mest effektive like-operatøren du kan finne. Hvis du finner noe bedre, fortell meg.

Men likevel, som en full skanning. Og full skanning kan være treg, ikke bare på CPU, men også på disken. Hvis du plutselig har én terabyte med data per dag, og du søker etter et ord i løpet av dagen, må du skanne terabyten. Og det er sannsynligvis på vanlige harddisker, og til slutt vil de bli lastet på en slik måte at du ikke vil få tilgang til denne serveren via SSH.

I dette tilfellet er jeg klar til å tilby enda et lite triks. Det er eksperimentelt - det kan fungere, kanskje ikke. ClickHouse har fulltekstindekser i form av trigram Bloom-filtre. Våre kolleger i Arenadata har allerede prøvd disse indeksene, og de fungerer ofte akkurat etter hensikten.

For å bruke dem riktig, bør du ha en god forståelse av nøyaktig hvordan de fungerer: hva et trigram Bloom-filter er og hvordan du velger størrelse. Jeg kan si at de vil hjelpe for spørsmål om noen sjeldne fraser, understrenger som sjelden finnes i dataene. I dette tilfellet vil underområder velges av indekser og mindre data vil bli lest.

Nylig har ClickHouse lagt til enda mer avanserte funksjoner for fulltekstsøk. Dette er for det første et søk etter en haug med understrenger på en gang i ett pass, inkludert alternativer som skiller mellom store og små bokstaver, ikke skiller mellom store og små bokstaver, med støtte for UTF-8 eller bare for ASCII. Velg den mest effektive du trenger.

Søk etter flere regulære uttrykk i ett pass har også dukket opp. Du trenger ikke å skrive X som én delstreng eller X som en annen delstreng. Du skriver med en gang, og alt gjøres så effektivt som mulig.

For det tredje er det nå et omtrentlig søk etter regexps og et omtrentlig søk etter understrenger. Hvis noen har stavet feil, vil det bli søkt etter maksimalt samsvar.

Hva er den beste måten å organisere tilgang til ClickHouse for et stort antall brukere?

Fortell oss hvordan vi best kan organisere tilgangen for et stort antall forbrukere og analytikere. Hvordan danne en kø, prioritere maks samtidige søk, og med hvilke verktøy?

Hvis klyngen er stor nok, vil en god løsning være å heve ytterligere to servere, som vil bli et inngangspunkt for analytikere. Det vil si, ikke la analytikere få tilgang til spesifikke shards i klyngen, men bare opprette to tomme servere, uten data, og konfigurere tilgangsrettigheter på dem. I dette tilfellet blir brukerinnstillinger for distribuerte forespørsler overført til eksterne servere. Det vil si at du konfigurerer alt på disse to serverne, og innstillingene har effekt på hele klyngen.

I prinsippet har disse serverne ingen data, men mengden RAM på dem er veldig viktig for å utføre forespørsler. Disken kan også brukes til midlertidige data hvis ekstern aggregering eller ekstern sortering er aktivert.

Det er viktig å se på innstillingene som er knyttet til alle mulige grenser. Hvis jeg nå går til Yandex.Metrica-klyngen som analytiker og ber om en forespørsel velg antall treff, da vil jeg umiddelbart få et unntak om at jeg ikke kan utføre forespørselen. Maksimalt antall rader jeg har lov til å skanne er hundre milliarder, og totalt er det femti billioner av dem i en tabell på klyngen. Dette er den første begrensningen.

La oss si at jeg fjerner radgrensen og kjører spørringen på nytt. Da vil jeg se følgende unntak - innstilling aktivert kraftindeks etter dato. Jeg kan ikke fullføre spørringen hvis jeg ikke har angitt en datoperiode. Du trenger ikke stole på analytikere for å spesifisere det manuelt. Et typisk tilfelle er når en datoperiode er skrevet der hendelsesdatoen mellom uke. Og så spesifiserte de ganske enkelt en brakett på feil sted, og i stedet for og viste det seg å være eller - eller URL-match. Hvis det ikke er noen grense, vil den gjennomsøke URL-kolonnen og bare kaste bort massevis av ressurser.

I tillegg har ClickHouse to prioriterte innstillinger. Dessverre er de veldig primitive. Den ene heter rett og slett prioritet. Hvis prioritet ≠ 0, og forespørsler med en viss prioritet blir utført, men en forespørsel med en prioritetsverdi på mindre enn, som betyr en høyere prioritet, blir utført, vil en forespørsel med en prioritetsverdi på større, som betyr en lavere prioritet , er ganske enkelt suspendert og vil ikke fungere i det hele tatt i løpet av denne tiden.

Dette er en veldig grov innstilling og er ikke egnet for tilfeller der klyngen har konstant belastning. Men hvis du har korte, spreke forespørsler som er viktige, og klyngen stort sett er inaktiv, er dette oppsettet egnet.

Den neste prioritetsinnstillingen kalles OS trådprioritet. Den setter ganske enkelt den fine verdien for alle tråder for utførelse av forespørsel for Linux-planleggeren. Det fungerer så som så, men det fungerer fortsatt. Hvis du setter minimum nice-verdi - den er størst i verdi, og derfor lavest prioritet - og setter -19 for forespørsler med høy prioritet, så vil CPU-en konsumere lavprioriterte forespørsler omtrent fire ganger mindre enn høyprioriterte.

Du må også konfigurere maksimal forespørselsutførelsestid - for eksempel fem minutter. Minimumshastigheten for utførelse av spørringer er det kuleste. Denne innstillingen har eksistert i lang tid, og det kreves ikke bare for å hevde at ClickHouse ikke bremser ned, men for å tvinge den.

Tenk deg, du setter opp: Hvis noen spørringer behandler mindre enn én million rader per sekund, kan du ikke gjøre det. Dette vanære vårt gode navn, vår gode database. La oss bare forby dette. Det er faktisk to innstillinger. Den ene heter min utførelseshastighet - i linjer per sekund, og den andre kalles timeout før du sjekker min utførelseshastighet - femten sekunder som standard. Det vil si at femten sekunder er mulig, og så, hvis det går sakte, er det bare å kaste et unntak og avbryte forespørselen.

Du må også sette opp kvoter. ClickHouse har en innebygd kvotefunksjon som teller ressursforbruk. Men, dessverre, ikke maskinvareressurser som CPU, disker, men logiske - antall behandlede forespørsler, linjer og byte lest. Og du kan for eksempel konfigurere maksimalt hundre forespørsler innen fem minutter og tusen forespørsler i timen.

Hvorfor er det viktig? Fordi noen analysespørringer vil bli utført manuelt direkte fra ClickHouse-klienten. Og alt blir bra. Men hvis du har avanserte analytikere i bedriften din, vil de skrive et manus, og det kan være en feil i manuset. Og denne feilen vil føre til at forespørselen blir utført i en uendelig sløyfe. Det er dette vi må beskytte oss mot.

Er det mulig å gi resultatene av én spørring til ti klienter?

Vi har flere brukere som liker å komme inn med veldig store forespørsler på samme tidspunkt. Forespørselen er stor og i prinsippet utført raskt, men på grunn av at det er mange slike forespørsler samtidig, blir det veldig smertefullt. Er det mulig å utføre den samme forespørselen, som kom ti ganger på rad, én gang, og gi resultatet til ti klienter?

Problemet er at vi ikke har resultatene av cachen eller cachen til mellomdata. Det er en sidebuffer for operativsystemet, som vil forhindre deg i å lese data fra disken igjen, men dessverre vil dataene fortsatt bli dekomprimert, deserialisert og behandlet på nytt.

Jeg vil på en eller annen måte unngå dette, enten ved å bufre mellomdata, eller ved å stille opp lignende spørringer i en slags kø og legge til en resultatbuffer. Vi har for øyeblikket én pull-forespørsel under utvikling som legger til en forespørselsbuffer, men kun for underspørringer i in- og join-delene – det vil si at løsningen er ufullstendig.

Men vi står også overfor en slik situasjon. Et spesielt kanonisk eksempel er paginerte spørringer. Det er en rapport, den har flere sider, og det er en forespørsel om grense 10. Så det samme, men grense 10,10. Så en annen neste side. Og spørsmålet er hvorfor vi teller alt dette hver gang? Men nå er det ingen løsning, og det er ingen måte å unngå det på.

Det er en alternativ løsning som plasseres som sidevogn ved siden av ClickHouse - ClickHouse Proxy.

Kirill Shvakov: ClickHouse Proxy har en innebygd hastighetsbegrenser og en innebygd resultatbuffer. Mange innstillinger ble gjort der fordi et lignende problem ble løst. Proxy lar deg begrense forespørsler ved å sette dem i kø og konfigurere hvor lenge forespørselsbufferen varer. Hvis forespørslene virkelig var de samme, vil Proxy sende dem mange ganger, men vil bare gå til ClickHouse én gang.

Nginx har også en cache i gratisversjonen, og dette vil også fungere. Nginx har til og med innstillinger om at hvis forespørsler kommer samtidig, vil det bremse andre til en er fullført. Men det er i ClickHouse Proxy at oppsettet gjøres mye bedre. Det ble laget spesielt for ClickHouse, spesielt for disse forespørslene, så det er mer egnet. Vel, det er enkelt å installere.

Hva med asynkrone operasjoner og materialiserte visninger?

Det er et problem at operasjoner med replay-motoren er asynkrone - først blir dataene skrevet, så kollapser de. Hvis et materialisert nettbrett med noen aggregater lever under skiltet, vil duplikater bli skrevet til det. Og hvis det ikke er noen kompleks logikk, vil dataene bli duplisert. Hva kan du gjøre med det?

Det er en åpenbar løsning - å implementere en trigger på en viss klasse mattevisninger under en asynkron kollapsoperasjon. Er det noen sølvkuler eller planer om å implementere lignende funksjonalitet?

Det er verdt å forstå hvordan deduplisering fungerer. Det jeg skal fortelle deg nå er ikke relevant for spørsmålet, men bare i tilfelle det er verdt å huske.

Når du setter inn i en replikert tabell, er det deduplisering av hele de innsatte blokkene. Hvis du setter inn den samme blokken som inneholder samme antall av de samme radene i samme rekkefølge, dedupliseres dataene. Du vil motta "Ok" som svar på å sette inn, men faktisk vil en pakke med data bli skrevet, og den vil ikke bli duplisert.

Dette er nødvendig for sikkerhet. Hvis du mottar "Ok" under innsetting, er dataene dine satt inn. Hvis du mottar en feilmelding fra ClickHouse, betyr det at de ikke ble satt inn, og du må gjenta innsettingen. Men hvis tilkoblingen blir brutt under innsetting, så vet du ikke om dataene ble satt inn eller ikke. Det eneste alternativet er å gjenta innsettingen på nytt. Hvis dataene faktisk ble satt inn og du satte dem inn på nytt, er det blokkdeduplisering. Dette er nødvendig for å unngå duplikater.

Og det er også viktig hvordan det fungerer for materialiserte synspunkter. Hvis dataene ble deduplisert når de ble satt inn i hovedtabellen, vil de heller ikke gå inn i den materialiserte visningen.

Nå om spørsmålet. Situasjonen din er mer komplisert fordi du registrerer duplikater av individuelle linjer. Det vil si at det ikke er hele pakken som er duplisert, men spesifikke linjer, og de kollapser i bakgrunnen. Faktisk vil dataene kollapse i hovedtabellen, men de ikke-sammenslåtte dataene vil gå til den materialiserte visningen, og under sammenslåinger vil ingenting skje med de materialiserte visningene. Fordi en materialisert visning ikke er noe mer enn en innsettingsutløser. Under andre operasjoner skjer det ikke noe mer med den.

Og jeg kan ikke gjøre deg glad her. Du trenger bare å se etter en spesifikk løsning for denne saken. Er det for eksempel mulig å spille det av i en materialisert visning, og dedupliseringsmetoden kan fungere på samme måte. Men dessverre ikke alltid. Hvis det aggregeres, vil det ikke fungere.

Kirill Shvakov: Vi hadde også krykkekonstruksjon tilbake i dag. Det var et problem at det er annonsevisninger, og det er noen data vi kan vise i sanntid – dette er bare visninger. De dupliseres sjelden, men hvis dette skjer, vil vi kollapse dem senere uansett. Og det var ting som ikke kunne dupliseres - klikk og hele denne historien. Men jeg ville også vise dem nesten umiddelbart.

Hvordan ble de materialiserte synspunktene laget? Det var visninger der det ble skrevet direkte – det ble skrevet til rådata, og skrevet til visninger. Der er dataene på et tidspunkt lite korrekte, de er duplisert, og så videre. Og det er en andre del av tabellen, der de ser nøyaktig ut som materialiserte visninger, det vil si at de er helt identiske i struktur. En gang i blant regner vi dataene på nytt, teller dataene uten duplikater, skriver til de tabellene.

Vi gikk gjennom API - dette vil ikke fungere i ClickHouse manuelt. Og API-en ser ut: når jeg har datoen for siste tillegg til tabellen, hvor det er garantert at de riktige dataene allerede er beregnet, og den sender en forespørsel til en tabell og til en annen tabell. Fra den ene velger forespørselen opp til en viss tid, og fra den andre får den det som ennå ikke er beregnet. Og det fungerer, men ikke gjennom ClickHouse alene.

Hvis du har en slags API - for analytikere, for brukere - så er dette i prinsippet et alternativ. Du teller alltid, teller alltid. Dette kan gjøres en gang om dagen eller på et annet tidspunkt. Du velger selv et utvalg du ikke trenger og ikke er kritisk.

ClickHouse har mange logger. Hvordan kan jeg se alt som skjer med serveren på et øyeblikk?

ClickHouse har et veldig stort antall forskjellige logger, og dette antallet øker. I nye versjoner er noen av dem til og med aktivert som standard; i eldre versjoner må de aktiveres ved oppdatering. Imidlertid er det flere og flere av dem. Til syvende og sist vil jeg gjerne se hva som skjer med serveren min nå, kanskje på et slags sammendragsdashbord.

Har du et ClickHouse-team, eller teamene til vennene dine, som støtter noen funksjonalitet til ferdige dashboards som viser disse loggene som et ferdig produkt? Til syvende og sist er det flott å bare se på logger i ClickHouse. Men det ville vært veldig kult om det allerede var forberedt i form av et dashbord. Jeg ville fått et kick av det.

Det finnes dashbord, selv om de ikke er standardiserte. I vårt selskap bruker rundt 60 team ClickHouse, og det merkeligste er at mange av dem har dashbord som de har laget for seg selv, og litt forskjellige. Noen lag bruker en intern Yandex.Cloud-installasjon. Det er noen ferdige rapporter, men ikke alle nødvendige. Andre har sine egne.

Mine kolleger fra Metrica har sitt eget dashbord i Grafana, og jeg har mitt eget for deres klynge. Jeg ser på ting som cache-treff for serif-cachen. Og enda vanskeligere er det at vi bruker forskjellige verktøy. Jeg laget dashbordet mitt ved å bruke et veldig gammelt verktøy kalt Graphite-web. Han er helt stygg. Og jeg bruker det fortsatt på denne måten, selv om Grafana nok ville vært mer praktisk og vakkert.

Det grunnleggende i dashbord er det samme. Dette er systemmålinger for klyngen: CPU, minne, disk, nettverk. Andre - antall samtidige forespørsler, antall samtidige sammenslåinger, antall forespørsler per sekund, maksimalt antall biter for MergeTree-tabellpartisjoner, replikeringsforsinkelse, replikeringskøstørrelse, antall innsatte rader per sekund, antall innsatte blokker per sekund. Dette er alt som ikke hentes fra logger, men fra beregninger.

Vladimir Kolobaev: Alexey, jeg vil gjerne korrigere det litt. Der er Grafana. Grafana har en datakilde, som er ClickHouse. Det vil si at jeg kan komme med forespørsler fra Grafana direkte til ClickHouse. ClickHouse har en tabell med logger, den er lik for alle. Som et resultat vil jeg få tilgang til denne loggtabellen i Grafana og se forespørslene som serveren min gjør. Det ville vært flott å ha et dashbord som dette.

Jeg syklet den selv. Men jeg har et spørsmål - hvis alt er standardisert, og Grafana brukes av alle, hvorfor har ikke Yandex et så offisielt dashbord?

Kirill Shvakov: Faktisk støtter datakilden som går til ClickHouse nå Altinity. Og jeg vil bare gi en vektor for hvor man skal grave og hvem man skal presse. Du kan spørre dem, fordi Yandex fortsatt lager ClickHouse, og ikke historien rundt det. Altinity er hovedselskapet som for tiden markedsfører ClickHouse. De vil ikke forlate ham, men støtte ham. For i prinsippet, for å laste opp et dashbord til Grafana-nettstedet, trenger du bare å registrere deg og laste det opp - det er ingen spesielle problemer.

Alexey Milovidov: I løpet av det siste året har ClickHouse lagt til mange funksjoner for søkeprofilering. Det er beregninger for hver forespørsel om ressursbruk. Og nylig har vi lagt til en spørringsprofiler på enda lavere nivå for å se hvor en spørring bruker hvert millisekund. Men for å bruke denne funksjonaliteten, må jeg åpne konsollklienten og skrive inn en forespørsel, som jeg alltid glemmer. Jeg har lagret det et sted og glemmer hvor nøyaktig hvor.

Jeg skulle ønske det var et verktøy som nettopp sa, her er de tunge spørsmålene dine, gruppert etter spørringsklasse. Jeg trykket på en, og de ville fortelle meg at det er derfor den er tung. Det er ingen slik løsning nå. Og det er egentlig ganske rart at når folk spør meg: «Fortell meg, finnes det noen ferdige dashboards for Grafana?», så sier jeg: «Gå til Grafana-nettstedet, det er et «Dashboards»-fellesskap, og det er et dashbord fra Dimka, det er et dashbord fra Kostyan. Jeg vet ikke hva det er, jeg har ikke brukt det selv."

Hvordan påvirke sammenslåinger slik at serveren ikke krasjer inn i OOM?

Jeg har en tabell, det er bare en partisjon i tabellen, det er ReplaceingMergeTree. Jeg har skrevet data inn i den i fire år. Jeg trengte å gjøre en endring i den og slette noen data.

Jeg gjorde dette, og under behandlingen av denne forespørselen ble alt minnet på alle serverne i klyngen konsumert, og alle serverne i klyngen gikk inn i OOM. Så reiste de seg alle sammen, begynte å slå sammen denne samme operasjonen, denne datablokken, og falt inn i OOM igjen. Så reiste de seg igjen og falt igjen. Og dette stoppet ikke.

Så viste det seg at dette faktisk var en feil som gutta fikset. Dette er veldig kult, tusen takk. Men en rest gjensto. Og nå, når jeg tenker på å lage en slags sammenslåing i tabellen, har jeg et spørsmål - hvorfor kan jeg ikke på en eller annen måte påvirke disse sammenslåingene? Begrens dem for eksempel med mengden RAM som kreves, eller, i prinsippet, med mengden som skal behandle denne spesielle tabellen.

Jeg har en tabell som heter "Metrics", bearbeid den for meg i to tråder. Det er ikke nødvendig å lage ti eller fem sammenslåinger parallelt, gjør det i to. Jeg tror at jeg har nok minne til to, men det er kanskje ikke nok til å behandle ti. Hvorfor forblir frykten? Fordi tabellen vokser, og en dag vil jeg stå overfor en situasjon som i prinsippet ikke lenger skyldes en feil, men fordi dataene vil endre seg i så stor mengde at jeg rett og slett ikke vil ha nok minne på server. Og så vil serveren krasje inn i OOM ved sammenslåing. Dessuten kan jeg avbryte mutasjonen, men Merji er ikke der lenger.

Du vet, når du slår sammen, vil ikke serveren falle inn i OOM, fordi når du slår sammen, brukes mengden RAM bare for ett lite dataområde. Så alt blir bra uansett datamengde.

Vladimir Kolobaev: Fint. Her er øyeblikket slik at etter at feilen ble fikset, lastet jeg ned en ny versjon for meg selv, og på et annet bord, et mindre, hvor det er mange partisjoner, utførte jeg en lignende operasjon. Og under sammenslåingen ble omtrent 100 GB RAM brent på serveren. Jeg hadde 150 opptatt, 100 spist og et vindu på 50 GB igjen, så jeg falt ikke inn i OOM.

Hva beskytter meg for øyeblikket fra å falle inn i OOM hvis den faktisk bruker 100 GB RAM? Hva skal jeg gjøre hvis RAM-en på sammenslåingene plutselig går tom?

Alexey Milovidov: Det er et slikt problem at forbruket av RAM spesielt for sammenslåing ikke er begrenset. Og det andre problemet er at hvis en slags sammenslåing har blitt tildelt, må den utføres fordi den er registrert i replikeringsloggen. Replikeringsloggen er handlingene som er nødvendige for å bringe replikaen til en konsistent tilstand. Hvis du ikke gjør manuelle manipulasjoner som vil rulle tilbake denne replikeringsloggen, må sammenslåingen utføres på en eller annen måte.

Selvfølgelig ville det ikke være overflødig å ha en RAM-begrensning som "i tilfelle" beskytter mot OOM. Det vil ikke hjelpe sammenslåingen å fullføre, den vil starte på nytt, nå en terskel, kaste et unntak, og så starte på nytt - det vil ikke komme noe godt ut av dette. Men i prinsippet vil det være nyttig å innføre denne begrensningen.

Hvordan vil Golang-driveren for ClickHouse bli utviklet?

Golang-driveren, som ble skrevet av Kirill Shvakov, er nå offisielt støttet av ClickHouse-teamet. Han i ClickHouse-depotet, han er nå stor og ekte.

En liten notis. Det er et fantastisk og elsket depot av normale former for uendelig rekkefølge - dette er Vertica. De har også sin egen offisielle python-driver, som støttes av Vertica-utviklerne. Og flere ganger skjedde det at lagringsversjonene og driverversjonene divergerte ganske dramatisk, og driveren sluttet på et tidspunkt å fungere. Og det andre punktet. Støtte for denne offisielle sjåføren, ser det ut til, utføres av "nippel"-systemet - du skriver et problem til dem, og det henger for alltid.

Jeg har to spørsmål. Nå er Kirills Golang-driver nesten standardmåten for å kommunisere fra Golang med ClickHouse. Med mindre noen fortsatt kommuniserer via http-grensesnittet fordi han liker det på den måten. Hvordan vil utviklingen av denne driveren forløpe? Vil det bli synkronisert med eventuelle brytende endringer i selve depotet? Og hva er prosedyren for å vurdere et problem?

Kirill Shvakov: Den første er hvordan alt er organisert byråkratisk. Dette punktet ble ikke diskutert, så jeg har ingenting å svare på.

For å svare på spørsmålet om problemet trenger vi en liten historie om sjåføren. Jeg jobbet for et selskap som hadde mye data. Det var en reklamespinner med et enormt antall arrangementer som måtte lagres et sted. Og på et tidspunkt dukket ClickHouse opp. Vi fylte den med data, og først var alt bra, men så krasjet ClickHouse. I det øyeblikket bestemte vi oss for at vi ikke trengte det.

Et år senere kom vi tilbake til ideen om å bruke ClickHouse, og vi trengte å skrive data der på en eller annen måte. Den innledende meldingen var denne: maskinvaren er veldig svak, det er få ressurser. Men vi har alltid jobbet på denne måten, og derfor så vi mot den innfødte protokollen.

Siden vi jobbet i Go, var det tydelig at vi trengte en Go-sjåfør. Jeg gjorde det nesten på heltid – det var arbeidsoppgaven min. Vi brakte det til et visst punkt, og i prinsippet var det ingen som antok at andre enn oss ville bruke det. Så kom CloudFlare med akkurat det samme problemet, og vi jobbet en stund med dem veldig greit, fordi de hadde de samme oppgavene. Dessuten gjorde vi dette både i ClickHouse selv og i driveren.

På et tidspunkt sluttet jeg rett og slett å gjøre det, fordi aktiviteten min i forhold til ClickHouse og arbeid endret seg litt. Derfor er ikke saker lukket. Med jevne mellomrom forplikter folk som trenger noe selv seg til depotet. Så ser jeg på pull-forespørselen og noen ganger redigerer jeg til og med noe selv, men dette skjer sjelden.

Jeg vil tilbake til sjåføren. For flere år siden, da hele greia begynte, var ClickHouse også annerledes og med andre muligheter. Nå har vi en forståelse for hvordan vi skal lage driveren på nytt slik at den fungerer bra. Hvis dette skjer, vil versjon 2 uansett være inkompatibel på grunn av de akkumulerte krykkene.

Jeg vet ikke hvordan jeg skal organisere denne saken. Jeg har ikke mye tid selv. Hvis noen fullfører sjåføren, kan jeg hjelpe dem og fortelle dem hva de skal gjøre. Men den aktive deltakelsen til Yandex i utviklingen av prosjektet har ennå ikke blitt diskutert.

Alexey Milovidov: Faktisk er det ikke noe byråkrati rundt disse sjåførene ennå. Det eneste er at de sendes til en offisiell organisasjon, det vil si at denne driveren er anerkjent som den offisielle standardløsningen for Go. Det er noen andre sjåfører, men de kommer separat.

Vi har ingen intern utvikling for disse sjåførene. Spørsmålet er om vi kan ansette en enkeltperson, ikke for akkurat denne sjåføren, men for utvikling av alle samfunnsdrivere, eller kan vi finne noen utenfra.

Den eksterne ordboken lastes ikke inn etter en omstart med lazy_load-innstillingen aktivert. Hva å gjøre?

Vi har lazy_load-innstillingen aktivert, og etter at serveren er startet på nytt, laster ikke ordboken av seg selv. Den heves først etter at brukeren har tilgang til denne ordboken. Og første gang jeg får tilgang til det, gir det en feilmelding. Er det mulig å laste inn ordbøker automatisk på en eller annen måte ved hjelp av ClickHouse, eller må du alltid kontrollere deres beredskap selv slik at brukerne ikke får feil?

Kanskje vi har en gammel versjon av ClickHouse, så ordboken lastet ikke automatisk. Kan dette være tilfelle?

For det første kan ordbøker tvinges inn ved hjelp av en spørring systeminnlasting av ordbøker. For det andre, angående feilen - hvis ordboken allerede er lastet, vil spørringene fungere basert på dataene som ble lastet. Hvis ordboken ennå ikke er lastet inn, blir den lastet direkte under forespørselen.

Dette er ikke veldig praktisk for tunge ordbøker. For eksempel må du trekke en million rader fra MySQL. Noen gjør et enkelt valg, men dette valget vil vente på de samme millioner radene. Det er to løsninger her. Den første er å slå av lazy_load. For det andre, når serveren er oppe, før du legger belastningen på den, gjør du det systemopplastingsordbok eller bare gjør en spørring som bruker en ordbok. Da vil ordboken lastes. Du må kontrollere tilgjengeligheten av ordbøker med lazy_load-innstillingen aktivert, fordi ClickHouse ikke laster dem automatisk.

Svaret på det siste spørsmålet er enten at versjonen er gammel eller den må feilsøkes.

Hva skal man gjøre med det faktum at systeminnlasting av ordbøker ikke laster noen av de mange ordbøkene hvis minst én av dem krasjer med en feil?

Det er et annet spørsmål om systeminnlastingsordbøker. Vi har to ordbøker - den ene er ikke lastet inn, den andre er lastet. I dette tilfellet laster ikke System-reload-ordbøker inn noen ordbok, og du må laste inn en bestemt ordbok punkt for punkt etter navnet ved å bruke system-reload-ordboken. Er dette også relatert til ClickHouse-versjonen?

Jeg vil gjøre deg glad. Denne oppførselen var i endring. Dette betyr at hvis du oppdaterer ClickHouse, vil det også endre seg. Hvis du ikke er fornøyd med din nåværende oppførsel systeminnlasting av ordbøker, oppdater, og la oss håpe det endrer seg til det bedre.

Er det en måte å konfigurere detaljer i ClickHouse-konfigurasjonen, men ikke vise dem i tilfelle feil?

Det neste spørsmålet handler om feil knyttet til ordboken, nemlig detaljer. Vi har spesifisert tilkoblingsdetaljene i ClickHouse-konfigurasjonen for ordboken, og hvis det er en feil, mottar vi disse opplysningene og passordet som svar.

Vi løste denne feilen ved å legge til detaljer i ODBC-driverkonfigurasjonen. Er det noen måte å konfigurere detaljene i ClickHouse-konfigurasjonen, men ikke vise disse detaljene i tilfelle feil?

Den virkelige løsningen her er å spesifisere disse legitimasjonene i odbc.ini, og i ClickHouse selv spesifisere kun ODBC-datakildenavnet. Dette vil ikke skje for andre ordbokkilder - verken for ordboken med MySQL, eller for de andre, skal du ikke se passordet når du får en feilmelding. For ODBC vil jeg også se - hvis det finnes, trenger du bare å fjerne det.

Bonus: bakgrunner for Zoom fra samlinger

Ved å klikke på bildet åpnes bonusbakgrunner fra samlingene for de mest iherdige leserne. Vi slukker brannen sammen med Avito-teknologimaskotene, vi konfererer med kolleger fra systemadministratorens rom eller den gamle skolens dataklubb, og vi gjennomfører daglige møter under broen på bakgrunn av graffiti.

ClickHouse for avanserte brukere i spørsmål og svar

Kilde: www.habr.com

Legg til en kommentar