ClickHouse pro pokročilé uživatele v otázkách a odpovědích

V dubnu se inženýři Avito sešli na online setkání s Alexejem Milovidovem, hlavním vývojářem ClickHouse, a Kirillem Shvakovem, vývojářem Golang ze společnosti Integros. Diskutovali jsme o tom, jak používáme systém správy databází a s jakými potížemi se potýkáme.

Na základě schůzky jsme dali dohromady článek s odpověďmi odborníků na naše i posluchačské otázky týkající se zálohování, předělání dat, externích slovníků, ovladače Golang a aktualizací verzí ClickHouse. Může být užitečný pro vývojáře, kteří již aktivně pracují s Yandex DBMS a zajímají se o jeho současnost a budoucnost. Odpovědi Alekseye Milovidova standardně, pokud není uvedeno jinak.

Pozor, pod řezem je hodně textu. Doufáme, že obsah s otázkami vám pomůže se zorientovat.

ClickHouse pro pokročilé uživatele v otázkách a odpovědích

Obsah

Pokud se vám nechce číst text, můžete se podívat na záznam shromáždění na našem youtube kanálu. Časová razítka jsou v prvním komentáři pod videem.

ClickHouse je neustále aktualizován, ale naše data nikoli. co s tím dělat?

ClickHouse je neustále aktualizován a naše data, která byla zpracována optimalizací final, nejsou aktualizována a jsou v záloze.

Předpokládejme, že jsme měli nějaký problém a data byla ztracena. Rozhodli jsme se obnovit a ukázalo se, že staré oddíly, které jsou uloženy na záložních serverech, se velmi liší od aktuálně používané verze ClickHouse. Co dělat v takové situaci a je to možné?

Situace, kdy jste obnovili data ze zálohy ve starém formátu, ale v nové verzi nejsou připojena, je nemožná. Dbáme na to, aby formát dat v ClickHouse zůstal vždy zpětně kompatibilní. To je mnohem důležitější než zpětná kompatibilita ve funkčnosti, pokud se změnilo chování některé zřídka používané funkce. Data, která jsou uložena na disku, by nová verze ClickHouse měla vždy umět přečíst. Toto je zákon.

Jaké jsou aktuální osvědčené postupy pro zálohování dat z ClickHouse?

Jak dělat zálohy s přihlédnutím k tomu, že máme optimalizovat finální operace, obrovskou databázi terabajtů a data, která se aktualizují dejme tomu za poslední tři dny a pak se s nimi nedějí žádné procedury?

Můžeme si dát dohromady vlastní řešení a napsat si na hlavu: sbírejte tyto zálohy takovým a takovým způsobem. Možná nepotřebujete nic o berli a kolo bylo vynalezeno už dávno?

Začněme osvědčenými postupy. Moji kolegové vždy v odpovědi na otázky týkající se záloh radí, aby jim připomněli službu Yandex.Cloud, kde je tento úkol již vyřešen. Takže pokud je to možné, použijte to.

Neexistuje žádné kompletní řešení, stoprocentně zabudované do ClickHouse, pro zálohování. Existuje několik mezer, které můžete použít. Chcete-li získat kompletní řešení, budete muset buď trochu pohrát ručně, nebo vytvořit obaly ve formě skriptů.

Začnu nejjednoduššími řešeními a skončím těmi nejsofistikovanějšími v závislosti na množství dat a velikosti clusteru. Čím je shluk větší, tím je řešení obtížnější.

Pokud datová tabulka zabírá pouze několik gigabajtů, zálohu lze provést takto:

  1. Uložte definici tabulek, tedy metadata − zobrazit vytvořit tabulku.
  2. Vytvořte výpis pomocí klienta ClickHouse − vybrat * ze stolu do souboru. Ve výchozím nastavení obdržíte soubor ve formátu TabSeparated. Pokud chcete být efektivnější, můžete použít nativní formát.

Pokud je objem dat větší, záloha zabere více času a místa. Říká se tomu logická záloha, není vázána na formát dat ClickHouse. Pokud ano, můžete si v krátkém čase udělat zálohu a nahrát ji do MySQL pro obnovení.

Pro pokročilejší případy má ClickHouse vestavěnou schopnost vytvořit snímek oddílů v místním souborovém systému. Tato funkce je k dispozici na vyžádání. změnit oddíl zmrazení tabulky. Nebo jednoduše změnit zmrazení stolu je snímek celé tabulky.

Snímek bude vytvořen konzistentní pro jednu tabulku na jednom datovém fragmentu, to znamená, že tímto způsobem nelze vytvořit konzistentní snímek celého clusteru. Ale pro většinu úloh to není potřeba a stačí provést požadavek na každém fragmentu a získat konzistentní snímek. Je vytvořen ve formě hardlinků, a proto nezabírá další místo. Poté zkopírujte tento snímek na záložní server nebo do úložiště, které používáte pro zálohování.

Obnovení takové zálohy je celkem snadné. Nejprve vytvoříte tabulky podle existujících definic tabulek. Dále zkopírujte uložené snímky diskových oddílů pro tyto tabulky do Directory-Detached a spusťte dotaz připojit oddíl. Toto řešení je docela vhodné pro nejzávažnější objemy dat.

Někdy potřebujete něco ještě chladnějšího - v případech, kdy máte desítky nebo dokonce stovky terabajtů na každém serveru a stovky serverů. Existuje zde řešení, které jsem sledoval od kolegů z Yandex.Metrica. Nedoporučoval bych to všem - přečtěte si to a sami se rozhodněte, zda je to vhodné nebo ne.

Nejprve musíte vytvořit několik serverů s velkými policemi na disky. Dále zvedněte několik serverů ClickHouse na těchto serverech a nakonfigurujte je tak, aby fungovaly jako další replika pro stejné fragmenty. A pak použijte souborový systém na těchto serverech nebo nějaký nástroj, který vám umožní vytvářet snímky. Zde jsou dvě možnosti. První možností jsou snímky LVM, druhou možností je ZFS na Linuxu.

Poté musíte každý den vytvořit snímek, bude ležet a zabere trochu místa. Přirozeně, pokud se data změní, časem se prostor zvětší. Tento snímek můžete kdykoli získat a obnovit data, takové zvláštní rozhodnutí. Navíc je stále potřeba omezit tyto repliky v konfiguraci, aby se nepokoušely stát se lídry.

Bude možné zorganizovat řízené nahromadění replik v šachtách?

Letos plánujete výrobu šachet v ClickHouse. Bude v nich možné organizovat řízený nahromadění replik? Rádi bychom jej využili k ochraně před negativními scénáři s úpravami a jinými změnami.

Je možné provést nějaký druh vrácení zpět pro změny? Například v existující šachtě vezměte a řekněte, že do tohoto okamžiku aplikujte změny a od tohoto okamžiku přestaňte uplatňovat změny?

Pokud by nám do clusteru přišel příkaz a porušil ho, tak máme podmíněnou repliku s hodinovým zpožděním, kde můžeme říct, že ho v tuto chvíli použijeme, ale nebudeme v něm aplikovat změny za posledních deset minut?

Pro začátek o řízeném nahromadění replik. Byl tu takový požadavek od uživatelů a my jsme na Github vytvořili problém s požadavkem: „Pokud to někdo potřebuje, dejte like, dejte srdíčko.“ Nikdo nevsadil a problém byl uzavřen. Tuto příležitost však již můžete získat zřízením ClickHouse. Pravda, teprve od verze 20.3.

ClickHouse neustále slučuje data na pozadí – merge. Při sloučení je některá sada datových bloků nahrazena větším blokem. Zároveň kusy dat, které byly předtím, zůstávají na disku ještě nějakou dobu.

Za prvé, budou nadále ukládány, dokud existují vybrané dotazy, které je používají, aby byl zajištěn neblokující provoz. Vybrané požadavky se tiše čtou ze starých bloků.

Za druhé je tu také časový práh – staré kusy dat leží na disku osm minut. Těchto osm minut lze přizpůsobit a proměnit v jeden den. To bude stát místo na disku: v závislosti na datovém toku se ukáže, že za poslední den se data nejen zdvojnásobí, ale mohou být až pětkrát více. Ale v případě vážného problému můžete server ClickHouse zastavit a vše řešit.

Nyní je otázkou, jak to chrání před změnami. Zde stojí za to se podívat hlouběji, protože ve starších verzích ClickHouse alter fungoval tak, že prostě přímo měnil kusy. U některých souborů je kus dat a my děláme např. alter drop sloupec. Poté je tento sloupec fyzicky odstraněn ze všech bloků.

Ale od verze 20.3 byl mechanismus změny zcela změněn a nyní jsou datové bloky vždy neměnné. Nemění se vůbec - změny nyní fungují v podstatě stejným způsobem jako sloučení. Místo výměny kusu na místě vytvoříme nový. V novém bloku se soubory, které se nezměnily, stanou pevnými odkazy, a pokud sloupec odstraníme, bude v novém bloku jednoduše chybět. Starý kus bude ve výchozím nastavení smazán po osmi minutách a zde můžete doladit výše zmíněná nastavení.

Totéž platí pro altery, jako jsou mutace. Když to uděláte změnit odstranit nebo změnit aktualizaci, nezmění kus, ale vytvoří nový. A pak smaže ten starý.

Co když se struktura tabulky změnila?

Jak vytvořit zálohu, která byla vytvořena se starým schématem? A druhá otázka se týká případu se snímky a nástroji souborového systému. Je zde vhodné Btrfs místo ZFS na Linux LVM?

Pokud udelas připojit oddíl oddíly s jinou strukturou, pak vám ClickHouse řekne, že to není možné. Řešením je toto. První je vytvořit dočasnou tabulku typu MergeTree se starou strukturou, připojit tam data pomocí připojit a zadat alter dotaz. Poté můžete tato data buď zkopírovat nebo přenést a znovu připojit, nebo použít dotaz změnit tabulku přesunout oddíl.

Nyní je druhá otázka, zda je možné použít Btrfs. Pro začátek, pokud máš LVM, tak stačí snapshoty LVM a souborový systém může být ext4, to je jedno. U Btrts vše záleží na vašich zkušenostech s ním. Jedná se o vyzrálý souborový systém, ale stále existují určitá podezření, jak vše bude v praxi v konkrétním scénáři fungovat. Nedoporučoval bych to používat, pokud nemáte Btrfs ve výrobě.

Jaké jsou současné osvědčené postupy pro opětovné sdílení dat?

Otázka reshardingu je složitá a mnohostranná. Zde můžete odpovědět na několik možností najednou. Můžete vstoupit z jedné strany a říci toto – v ClickHouse není žádná vestavěná možnost předělání. Obávám se ale, že tato odpověď nebude nikomu vyhovovat. Proto můžete jít z druhé strany a říci, že ClickHouse má mnoho způsobů, jak data předělat.

Pokud clusteru dojde místo nebo nezvládne zatížení, přidáte nové servery. Ale tyto servery jsou ve výchozím nastavení prázdné, nejsou na nich žádná data, není zátěž. Je třeba posunout data tak, aby se rovnoměrně rozprostřela v novém větším clusteru.

První způsob, jak to udělat, je zkopírovat část oddílů na nové servery pomocí dotazu změnit oddíl načtení tabulky. Například jste měli oddíly podle měsíců a vezmete první měsíc roku 2017 a zkopírujete jej na nový server a poté zkopírujete třetí měsíc na jiný nový server. A tak to děláte, dokud to nebude víceméně vyrovnané.

Migraci lze provést pouze pro ty oddíly, které se během nahrávání nemění. U nových oddílů bude muset být zakázán zápis, protože jejich přenos není atomický. V opačném případě skončíte s duplikáty nebo mezerami v datech. Tato metoda je však praktická a funguje poměrně efektivně. Hotové komprimované oddíly se přenášejí po síti, to znamená, že data nejsou komprimována ani překódována.

Tato metoda má jednu nevýhodu a záleží na schématu shardingu, zda jste se zavázali k tomuto schématu shardingu, jaký jste měli shardovací klíč. Ve vašem příkladu pro případ s metrikami je sharding klíč hash cesty. Když vyberete distribuovanou tabulku, přejde do všech fragmentů clusteru najednou a vezme data odtud.

To znamená, že je vám vlastně jedno, jaká data na kterém střepu skončí. Hlavní je, že data podél jedné cesty skončí na jednom střepu, ale která není důležitá. Přenos hotových oddílů je v tomto případě perfektní, protože s vybranými dotazy dostanete i plná data – jak před reshardingem, tak i po něm, na schématu vlastně nezáleží.

Jsou ale případy, které jsou složitější. Pokud na úrovni aplikační logiky spoléháte na speciální schéma shardingu, že tento klient je umístěn na tom a takovém shardu a požadavek lze odeslat okamžitě tam, a ne do tabulky Distributed. Nebo používáte poměrně nedávnou verzi ClickHouse a povolili jste nastavení optimalizovat přeskočit nepoužívané úlomky. V tomto případě bude během výběrového dotazu analyzován výraz v sekci where a bude vypočítáno, na které shardy přejít podle schématu shardingu. To funguje za předpokladu, že data jsou rozložena přesně podle tohoto schématu shardingu. Pokud jste je posunuli ručně, korespondence se může změnit.

Takže to je způsob číslo jedna. A čekám na vaši odpověď, zda je metoda vhodná, nebo pokračujte.

Vladimir Kolobaev, hlavní správce systému v Avitu: Alexeji, metoda, kterou jsi zmínil, se moc nehodí, když potřebuješ rozložit zátěž, včetně čtení. Můžeme vzít oddíl, který je měsíční, a můžeme vzít předchozí měsíc do jiného uzlu, ale když přijde požadavek na tato data, pouze je načteme. Chtěl bych ale načíst celý cluster, protože jinak bude po nějakou dobu celé zatížení čtení zpracovávat dva úlomky.

Alexey Milovidov: Zde je odpověď zvláštní – ano, je to špatné, ale může to fungovat. Vysvětlím přesně jak. Vyplatí se podívat na scénář zatížení, který je dodáván s vašimi daty. Pokud se jedná o monitorovací data, pak je téměř jisté, že naprostá většina požadavků je na čerstvá data.

Nainstalovali jste nové servery, migrovali staré oddíly, ale také jste změnili způsob zápisu čerstvých dat. A čerstvá data se budou šířit po celém clusteru. Po pěti minutách tedy požadavky na posledních pět minut zatíží cluster rovnoměrně, po dni požadavky na den zatíží cluster rovnoměrně. A požadavky za předchozí měsíc bohužel půjdou jen na část clusterových serverů.

Často ale nebudete mít požadavky na únor 2019. S největší pravděpodobností, pokud požadavky půjdou do roku 2019, pak budou na celý rok 2019 - na velký časový interval, a ne na nějaký malý rozsah. A takové požadavky budou také schopny rovnoměrně zatížit cluster. Obecně je ale vaše poznámka zcela správná, že se jedná o ad hoc řešení, které nešíří data úplně rovnoměrně.

K odpovědi na otázku mám ještě pár bodů. Jeden z nich je o tom, jak zpočátku vytvořit schéma shardingu tak, aby bylo méně bolestné z reshardingu. To není vždy možné.

Máte například monitorovací data. Monitorovací data rostou ze tří důvodů. První je shromažďování historických dat. Druhým je nárůst dopravy. A třetím je nárůst počtu věcí, které podléhají sledování. Jsou zde nové mikroslužby a metriky, které je třeba uložit.

Je možné, že z nich je největší nárůst způsoben třetím důvodem – tím je nárůst využívání monitoringu. A v tomto případě stojí za to podívat se na povahu zátěže, jaké jsou hlavní požadavky na výběr. Hlavní výběrové dotazy budou pravděpodobně sledovat určitou podmnožinu metrik.

Například využití CPU na některých serverech nějakou službou. Ukazuje se, že existuje nějaká podmnožina klíčů, pomocí kterých tato data získáváte. A samotný požadavek na tato data je s největší pravděpodobností docela jednoduchý a běží v řádu desítek milisekund. Používá se pro monitorovací služby, pro dashboardy. Doufám, že tomu rozumím správně.

Vladimír Kolobajev: Faktem je, že velmi často apelujeme na historická data, protože v reálném čase porovnáváme aktuální pozici s tou historickou. A je pro nás důležité mít rychlý přístup k velkému množství dat a ClickHouse s tím odvádí skvělou práci.

Máte naprostou pravdu, většina požadavků na čtení, které zažíváme za poslední den, jako každý monitorovací systém. Zároveň je ale zatížení historickými daty také poměrně velké. Je to většinou z varovného systému, který chodí každých třicet sekund a říká ClickHouse: „Dejte mi data za posledních šest týdnů. A teď mi z nich sestavte nějaký klouzavý průměr a pojďme porovnat současnou hodnotu s historickou hodnotou.

Rád bych řekl, že pro takové velmi čerstvé požadavky máme další malou tabulku, do které ukládáme pouze dva dny dat a hlavní požadavky do ní létají. Na velkou střepinu zasíláme pouze velké historické dotazy.

Alexey Milovidov: Bohužel se ukazuje, že je pro váš scénář špatně použitelný, ale popíšu dvě špatná a složitá schémata shardingu, která není nutné používat, ale používají se ve službě mých přátel.

Existuje hlavní cluster s událostmi Yandex.Metrica. Události jsou zobrazení stránky, kliknutí a přechody. Většina požadavků směřuje na konkrétní web. Otevřete službu Yandex.Metrica, máte webovou stránku - avito.ru, přejděte na zprávu a je vytvořen požadavek na váš web.

Existují však další požadavky - analytické a globální, které podávají interní analytici. Jen pro případ, poznamenávám, že interní analytici podávají požadavky pouze na služby Yandex. Nicméně i služby Yandex zabírají významný podíl všech dat. Nejsou to požadavky na konkrétní čítače, ale na širší filtrování.

Jak uspořádat data tak, aby vše fungovalo efektivně pro jeden čítač a také globální dotazy? Další problém spočívá ve skutečnosti, že počet požadavků v ClickHouse pro cluster Metrics je několik tisíc za sekundu. Jeden server ClickHouse zároveň nezpracovává netriviální požadavky, například několik tisíc za sekundu.

Velikost clusteru je šest set a něco serverů. Pokud jednoduše natáhnete distribuovanou tabulku přes tento cluster a pošlete tam několik tisíc požadavků, bude to ještě horší než jejich odeslání na jeden server. Na druhou stranu možnost, že data jsou rozložena rovnoměrně a my jdeme a žádáme ze všech serverů, je okamžitě zamítnuta.

Existuje diametrálně opačná možnost. Představte si, že sdílíme data podle webu a požadavek na jeden web přejde na jeden fragment. Nyní bude cluster schopen vytáhnout deset tisíc požadavků za sekundu, ale na jednom úlomku bude jeden požadavek fungovat příliš pomalu. Už se nebude škálovat v šířce pásma. Zvláště pokud se jedná o web avito.ru. Neprozradím tajemství, když řeknu, že Avito je jednou z nejnavštěvovanějších stránek Runetu. A zpracovat to na jednom střepu by bylo šílené.

Proto je schéma shardingu uspořádáno složitějším způsobem. Celý shluk je rozdělen do řady shluků, které nazýváme vrstvy. Uvnitř každého shluku je od deseti do několika desítek střepů. Takových shluků je celkem třicet devět.

Jak se to všechno škáluje? Počet shluků se nemění – jako před devětatřiceti lety zůstává stejný. Ale v rámci každého z nich postupně zvyšujeme počet shardů, jak se data hromadí. A schéma shardingu jako celku je toto - rozdělení do těchto clusterů probíhá podle webových stránek, a abychom pochopili, který web je na kterém clusteru, obecně se používá samostatná metabáze v MySQL. Jedno místo – na jednom clusteru. A uvnitř ní probíhá shardování podle identifikátorů návštěvníků.

Při nahrávání je rozdělíme podle zbytku ID návštěvníka. Ale když je přidán nový útržek, schéma dělení se změní, pokračujeme v dělení, ale se zbytkem dělení jiným číslem. To znamená, že jeden návštěvník se již nachází na několika serverech a nelze na něj sázet. To se provádí výhradně proto, aby byla data lépe komprimována. A při dotazování přejdeme do tabulky Distributed, která se dívá na cluster a přistupuje k desítkám serverů. To je tak hloupé schéma.

Můj příběh však nebude úplný, pokud neřeknu, že jsme od tohoto schématu upustili. V novém schématu jsme vše změnili a všechna data zkopírovali pomocí clickhouse-copier.

V novém schématu jsou všechny weby rozděleny do dvou kategorií – velké a malé. Nevím, jak tam byla zvolena prahová hodnota, ale ve výsledku se ukázalo, že velké weby jsou zaznamenány na jednom clusteru, kde je 120 fragmentů se třemi replikami v každém - tedy 360 serverů. A schéma shardingu je takové, že jakýkoli požadavek jde na všechny shardy najednou. Pokud nyní otevřete libovolnou stránku s přehledem pro avito.ru v Yandex.Metrica, požadavek půjde na 120 serverů. V Runetu je málo velkých míst. A požadavky nejsou tisíc za vteřinu, ale dokonce méně než sto. To vše tiše žvýká distribuovaný stůl, který každý z nich zpracovává 120 serverů.

A druhý cluster je pro malé weby. Zde je schéma sdílení podle ID webu a každý požadavek jde přesně na jeden fragment.

ClickHouse má nástroj clickhouse-copier. Můžeš o ní říct?

Hned musím říci, že toto řešení je těžkopádnější a poněkud méně produktivní. Výhodou je, že rozmazává data kompletně podle vámi zadaného schématu. Nevýhodou utility je ale to, že se vůbec nepředělává. Kopíruje data z jednoho klastrového schématu do jiného klastrového schématu.

To znamená, že aby to fungovalo, musíte mít dva clustery. Mohou být umístěny na stejných serverech, ale přesto se data nebudou přesouvat postupně, ale budou zkopírována.

Například servery byly čtyři, nyní je jich osm. Vytvoříte novou distribuovanou tabulku na všech serverech, nové lokální tabulky a spustíte clickhouse-copier, přičemž v ní určíte schéma práce, které má odtud číst, přijmete nové schéma shardingu a přenesete tam data. A na starých serverech budete potřebovat jedenapůlkrát více místa, než máte nyní, protože stará data na nich musí zůstat a polovina stejně starých dat na ně přijde. Pokud jste si předem mysleli, že je potřeba data předělat a je tam místo, tak je tento způsob vhodný.

Jak funguje clickhouse-copier uvnitř? Rozdělí veškerou práci do sady úloh pro zpracování jednoho oddílu jedné tabulky na jednom střepu. Všechny tyto úlohy mohou běžet paralelně a clickhouse-copier může spouštět více instancí na různých počítačích, ale to, co dělá pro jeden oddíl, není nic jiného než výběr vložení. Data se přečtou, dekomprimují, přerozdělí, poté znovu zkomprimují, někam zapíší, přetřídí. To je těžší rozhodnutí.

Měli jste pilotní věc zvanou resharding. Co s ní?

V roce 2017 jste měli pilotní věc zvanou resharding. V ClickHouse je dokonce možnost. Chápu, že to nezabralo. Můžete říct, proč se to stalo? Zdá se, že je to velmi relevantní.

Celý problém je v tom, že pokud potřebujete data předělat na místě, je k tomu nutná velmi složitá synchronizace, aby to bylo možné provést atomicky. Když jsme se začali zabývat tím, jak tato synchronizace funguje, bylo jasné, že existují zásadní problémy. A tyto zásadní problémy nejsou jen teoretické, ale okamžitě se začaly projevovat v praxi v podobě něčeho, co lze velmi jednoduše vysvětlit – nic nefunguje.

Je možné sloučit všechny části dat dohromady před přesunem na pomalé disky?

Otázka ohledně TTL s možností přechodu na pomalý disk v kontextu sloučení. Existuje jiný způsob než cron, jak sloučit všechny části do jedné před přechodem na pomalé disky?

Odpověď na otázku, zda je možné nějak automaticky všechny dílky před přenosem slepit do jednoho, zní ne. Zdá se mi, že to není nutné. Nemůžete sloučit všechny části do jedné, ale jednoduše se spolehnout na to, že se automaticky přenesou na pomalé disky.

Pro pravidla přestupu máme dvě kritéria. První je, jak se plní. Pokud má aktuální úroveň úložiště méně než určité procento volného místa, vybereme jeden blok a přesuneme ho do pomalejšího úložiště. Nebo spíš ne pomalejší, ale následující - jak si to nastavíte.

Druhým kritériem je velikost. Mluví o přenosu velkých kusů. Práh můžete upravit podle volného místa na rychlém disku a data budou migrována automaticky.

Jak migrovat na nové verze ClickHouse, pokud neexistuje způsob, jak předem ověřit kompatibilitu?

Toto téma je pravidelně diskutováno v telegramovém chatu ClickHouse s přihlédnutím k různým verzím a přesto. Jak bezpečný je upgrade z verze 19.11 na 19.16 a např. z 19.16 na 20.3. Jaký je nejlepší způsob, jak přejít na nové verze, aniž byste si mohli předem ověřit kompatibilitu v sandboxu?

Platí zde několik zlatých pravidel. První - číst changelog. Je velký, ale existují samostatné body o zpětně nekompatibilních změnách. Nepovažujte tyto položky za červenou vlajku. Obvykle se jedná o drobné nekompatibility, které souvisí s nějakou okrajovou funkcí, kterou pravděpodobně nepoužíváte.

Za druhé, pokud neexistuje způsob, jak zkontrolovat kompatibilitu v karanténě a chcete provést upgrade okamžitě v produkci, doporučujeme, abyste to nemuseli dělat. Nejprve vytvořte sandbox a otestujte. Pokud neexistuje testovací prostředí, pak s největší pravděpodobností nemáte příliš velkou společnost, což znamená, že si můžete zkopírovat některá data do svého notebooku a ujistit se, že na něm vše funguje správně. Můžete dokonce vyvolat několik replik lokálně na vašem počítači. Nebo můžete někde poblíž vyzvednout novou verzi a nahrát tam nějaká data – tedy vytvořit improvizované testovací prostředí.

Dalším pravidlem je neaktualizovat do týdne po vydání verze z důvodu vychytávání chyb ve výrobě a následných rychlých oprav. Pojďme pochopit číslování verzí ClickHouse, abychom se nepletli.

Existuje verze 20.3.4. Číslice 20 označuje rok výroby - 2020. Z hlediska toho, co je uvnitř, je to jedno, takže se tomu nebudeme věnovat. Dále - 20.3. Druhé číslo – v tomto případě 3 – zvyšujeme pokaždé, když vydáváme vydání s nějakou novou funkcí. Pokud chceme do ClickHouse přidat nějakou funkci, musíme toto číslo zvýšit. To znamená, že ve verzi 20.4 bude ClickHouse fungovat ještě lépe. Třetí číslice je 20.3.4. Zde 4 je počet vydání oprav, ve kterých jsme nepřidali nové funkce, ale opravili některé chyby. A 4 znamená, že jsme to udělali čtyřikrát.

Nemyslete si, že je to něco hrozného. Obvykle si uživatel může nainstalovat nejnovější verzi a ta bude fungovat bez problémů s dobou provozu za rok. Představte si ale, že v nějaké funkci pro zpracování bitmap, kterou přidali naši čínští soudruzi, při předání nesprávných argumentů dojde k pádu serveru. Musíme to opravit. Vydáme novou verzi opravy a ClickHouse bude stabilnější.

Pokud máte ClickHouse pracující ve výrobě a je vydána nová verze ClickHouse s dalšími funkcemi - například 20.4.1 je úplně první, nespěchejte s jejím uvedením do výroby hned první den. Proč je vůbec potřeba? Pokud ClickHouse ještě nepoužíváte, můžete si jej nainstalovat a s největší pravděpodobností bude vše v pořádku. Ale pokud ClickHouse již funguje stabilně, pak zůstaňte naladěni na opravy a aktualizace - jaké problémy opravujeme.

Kirill Shvakov: Chci přidat něco o testovacích prostředích. Každý se velmi bojí testovacích prostředí a z nějakého důvodu věří, že pokud máte velmi velký cluster ClickHouse, pak by testovací prostředí nemělo být menší nebo alespoň desetkrát menší. Vůbec to tak není.

Mohu to říct na svém příkladu. Mám projekt a tam je ClickHouse. Naším testovacím prostředím je pro něj malý virtuální stroj v Hetzneru za dvacet eur, kde je nasazeno úplně všechno. K tomu máme v Ansible plnou automatizaci, a proto v zásadě není žádný rozdíl, kam rolovat - na železné servery nebo jen nasadit na virtuální stroje.

co se dá dělat? Bylo by hezké udělat v dokumentaci ClickHouse příklad, jak nasadit malý cluster vlastními silami - v Dockeru, v LXC si možná vytvořte Ansible playbook, protože různí lidé mají různá nasazení. Spoustu věcí si tím usnadníte. Když vezmete a nasadíte cluster za pět minut, je mnohem jednodušší pokusit se něco vymyslet. Je to mnohem pohodlnější, protože uvedení verze, kterou jste neotestovali, do výroby je cesta nikam. Někdy to jde a někdy ne. A tak doufat v úspěch je špatné.

Maxim Kotyakov, senior backendový inženýr Avito: Přidám něco málo o testovacích prostředích ze série problémů pro velké společnosti. Máme plnohodnotný akceptační cluster ClickHouse, podle datových schémat a nastavení, přesnou kopii toho, co je ve výrobě. Tento cluster je nasazen v poněkud prohnilých kontejnerech s minimem zdrojů. Zapisujeme tam určité procento produkčních dat, protože existuje možnost replikovat stream v Kafce. Všechno je tam synchronizováno a škálováno – jak z hlediska kapacity, tak toku, a teoreticky by se při zachování ostatních věcí mělo chovat jako produkce z hlediska metrik. Vše potenciálně výbušné se nejprve navalí na tento stojan a několik dní se tam louhuje, dokud není připraveno. Toto řešení je ale samozřejmě drahé, těžké a s nenulovými náklady na podporu.

Alexey Milovidov: Řeknu vám, jaké je testovací prostředí našich přátel z Yandex.Metrica. Jeden cluster měl přibližně 600 serverů, druhý měl 360 a existuje třetí a několik clusterů. Testovací prostředí pro jeden z nich jsou pouze dva střepy se dvěma replikami v každém. Proč dva střepy? Aby nebyl sám. A repliky také, aby byly. Jen nějaká minimální částka, kterou si můžete dovolit.

Toto testovací prostředí vám umožňuje kontrolovat stav požadavků a zda není něco ve velkém rozbito. Často ale vznikají problémy úplně jiného charakteru, kdy vše funguje, ale se zátěží dochází k nějakým drobným změnám.

Dám vám příklad. Rozhodli jsme se nainstalovat novou verzi ClickHouse. Je rozvržen na testovací prostředí, v samotném Yandex.Metrica procházejí automatizované testy, které porovnávají data na staré verzi a na nové, přičemž běží celý kanál. A samozřejmě zelené testy naší CI. Jinak bychom tuto verzi ani nenavrhovali.

Vše je v pořádku. Začínáme se pouštět do výroby. Dostávám zprávu, že se zatížení na grafech několikrát zvýšilo. Vracíme verzi zpět. Podívám se na graf a vidím: zatížení se během zavádění skutečně několikrát zvýšilo a po spuštění se zase snížilo. Pak jsme začali verzi vrátit zpět. A zátěž se stejným způsobem zvýšila a stejným způsobem klesla zpět. Takže závěr je takový - zátěž se v souvislosti s výpočtem zvýšila, nic překvapivého.

Pak už bylo těžké přesvědčit kolegy, aby si novou verzi přece jen nainstalovali. Říkám: „To je v pořádku, vyvalte se. Držte nám palce, vše klapne. Nyní se zatížení na grafech zvýšilo, ale vše je v pořádku. Vydrž." Obecně jsme to udělali, a to je vše - verze je zveřejněna na produkčním webu. Téměř s každým výpočtem se ale objevují podobné problémy.

Kill query má zabíjet dotazy, ale nedělá to. Proč?

Přišel za mnou uživatel, nějaký analytik, a vytvořil určitý požadavek, který vložil můj cluster ClickHouse. Nějaký uzel nebo celý cluster, podle toho, do které repliky nebo fragmentu se požadavek dostal. Vidím, že všechny prostředky CPU na tomto serveru jsou v poličce, vše je červené. Na požadavky přitom reaguje i samotný ClickHouse. A píšu: "Prosím, ukažte mi seznam procesů, který požadavek vyvolal toto šílenství."

Najdu tento požadavek a napíšu k němu kill. A vidím, že se nic neděje. Můj server je v poličce, ClickHouse mi pak dává nějaké příkazy, ukazuje, že server je naživu a vše je v pořádku. Ale mám degradaci ve všech uživatelských požadavcích, začíná degradace záznamem v ClickHouse a můj dotaz na zabití nefunguje. Proč? Myslel jsem, že kill query měl zabíjet dotazy, ale nestalo se tak.

Teď přijde dost zvláštní odpověď. Jde o to, že zabíjecí dotaz nezabije dotazy.

Kill query umístí malé zaškrtávací políčko s názvem "Chci, aby byl tento dotaz zabit". A samotný požadavek se při zpracování každého bloku dívá na tento příznak. Pokud je nastaven, požadavek přestane fungovat. Ukáže se, že žádost nikdo nezabije, on sám musí vše zkontrolovat a zastavit. A to by mělo fungovat ve všech případech, kdy je požadavek ve stavu blokového zpracování. Zpracuje další blok dat, zkontroluje příznak a zastaví se.

Toto nefunguje v případech, kdy je požadavek na některé operaci blokován. Je pravda, že to s největší pravděpodobností není váš případ, protože podle vás používá spoustu serverových zdrojů. Je možné, že to nefunguje v případě externího třídění a v některých dalších detailech. Ale obecně by to nemělo být, toto je chyba. A jediné, co mohu poradit, je aktualizovat ClickHouse.

Jak vypočítat dobu odezvy při zatížení čtení?

Existuje tabulka, která ukládá agregáty položek – různé počítadla. Počet linek je asi sto milionů. Je možné počítat s předvídatelnou dobou odezvy, pokud nalijete 1K RPS na 1K položek?

Soudě podle kontextu mluvíme o čtecí zátěži, protože nejsou problémy se zápisem - lze vložit minimálně tisíc, minimálně sto tisíc a někdy i několik milionů řádků.

Požadavky na čtení jsou velmi odlišné. Ve výběru 1 může ClickHouse provádět asi desítky tisíc požadavků za sekundu, takže i požadavky na jeden klíč již budou vyžadovat určité zdroje. A takové bodové dotazy budou obtížnější než v některých databázích klíč-hodnota, protože pro každé čtení je nutné číst data blok po indexu. Náš index neřeší každý záznam, ale každý rozsah. To znamená, že musíte přečíst celý rozsah - ve výchozím nastavení je to 8192 řádků. A musíte dekomprimovat blok komprimovaných dat z 64 KB na 1 MB. Takové bodové dotazy obvykle trvají několik milisekund. Ale to je nejjednodušší možnost.

Zkusme jednoduchou aritmetiku. Pokud vynásobíte několik milisekund tisíci, dostanete několik sekund. Jako by nebylo možné udržet tisíc požadavků za sekundu, ale ve skutečnosti je to možné, protože máme několik procesorových jader. Takže v zásadě 1000 RPS ClickHouse někdy pojme, ale na krátké požadavky, konkrétně bodové.

Pokud potřebujete škálovat ClickHouse cluster podle počtu jednoduchých požadavků, pak doporučuji to nejjednodušší – zvýšit počet replik a poslat požadavky na náhodnou repliku. Pokud jedna replika pojme pět set požadavků za sekundu, což je zcela reálné, pak tři repliky pojmou jeden a půl tisíce.

Někdy samozřejmě můžete také nakonfigurovat ClickHouse na maximální počet bodů. Co je k tomu potřeba? Prvním je snížení granularity indexu. Zároveň by neměl být redukován na jeden, ale na základě toho, že počet záznamů v indexu bude několik milionů nebo desítek milionů na server. Pokud má tabulka sto milionů řádků, lze jako úroveň podrobnosti nastavit 64.

Velikost komprimovaného bloku můžete zmenšit. K tomu existují nastavení. minimální velikost komprimovaného bloku, maximální velikost komprimovaného bloku. Můžete je snížit, znovu načíst data a pak budou bodové dotazy rychlejší. ClickHouse však přesto není databáze klíč-hodnota. Velké množství malých požadavků je anti-vzor zatížení.

Kirill Shvakov: Poradím v případě, že jsou obyčejní účetní. To je celkem standardní situace, kdy je v ClickHouse uložen nějaký druh počítadla. Mám uživatele, je z takové a takové země, nějaký další třetí obor a potřebuji postupně něco zvýšit. Vezměte MySQL, vytvořte jedinečný klíč - v MySQL je to duplicitní klíč a v PostgreSQL je to konflikt - a přidejte znaménko plus. To bude fungovat mnohem lépe.

Když máte málo dat, nemá moc smysl používat ClickHouse. Existují pravidelné databáze a dělají to dobře.

Co vyladit v ClickHouse, aby bylo v mezipaměti více dat?

Představme si situaci - servery mají 256 GB RAM, v denní rutině zabírá ClickHouse asi 60-80 GB, ve špičce - až 130. Co lze povolit a vyladit, aby bylo v mezipaměti více dat a podle toho , je méně výletů na disk?

Mezipaměť stránek operačního systému tento úkol zpravidla dobře plní. Pokud jen otevřete horní část, podíváte se tam do mezipaměti nebo do volného místa - je tam také uvedeno, kolik je v mezipaměti - pak můžete vidět, že všechna volná paměť je použita pro mezipaměť. A při čtení těchto dat se nebudou číst z disku, ale z RAM. Zároveň mohu říci, že cache je využívána efektivně, protože právě komprimovaná data se ukládají do mezipaměti.

Pokud však chcete některé jednoduché dotazy ještě více urychlit, je možné povolit mezipaměť v dekomprimovaných datech uvnitř ClickHouse. To se nazývá nekomprimovaná mezipaměť. V konfiguračním souboru config.xml nastavte velikost nekomprimované mezipaměti na hodnotu, kterou potřebujete – radím maximálně polovinu volné RAM, protože zbytek půjde pod mezipaměť stránky.

Kromě toho existují dvě nastavení úrovně požadavku. První nastavení - použít nekomprimovanou mezipaměť - zahrnuje jeho použití. Doporučuje se povolit pro všechny požadavky, kromě těžkých, které dokážou přečíst všechna data a vyprázdnit tuto mezipaměť. A druhé nastavení je něco jako maximální počet řádků pro použití mezipaměti. Automaticky omezuje velké požadavky tak, aby byly za mezipamětí.

Jak mohu nakonfigurovat storage_configuration pro ukládání v RAM?

V nové dokumentaci ClickHouse jsem si přečetl část související s úložištěm dat. V popisu je příklad s rychlým SSD.

Zajímalo by mě, jak můžete nakonfigurovat totéž s objemovou horkou pamětí. A ještě jedna otázka. Jak select pracuje s touto organizací dat, načte celou sadu nebo jen tu na disku a jsou tato data komprimována v paměti? A jak na takové organizaci dat funguje sekce prewhere?

Toto nastavení ovlivňuje ukládání částí dat a jejich formát se nijak nemění.
Pojďme se na to podívat blíže.

Můžete nastavit ukládání dat do paměti RAM. Vše, co je nakonfigurováno pro disk, je jeho cesta. Vytvoříte oddíl tmpfs, který je připojen k nějaké cestě v souborovém systému. Zadejte tuto cestu jako cestu k ukládání dat pro nejžhavější oddíl, začnou přicházet a zapisovat se tam kusy dat, vše je v pořádku.

Ale nedoporučuji to dělat kvůli nízké spolehlivosti, ačkoli pokud máte alespoň tři repliky v různých datových centrech, můžete. Pokud ano, data budou obnovena. Představte si, že se server náhle vypnul a znovu zapnul. Sekce byla znovu namontována, ale je zde prázdno. Při spuštění server ClickHouse vidí, že tyto části chybí, ačkoli podle metadat ZooKeeper by měly být. Podívá se, na kterých replikách jsou, vyžádá si je a stáhne je. Data tak budou obnovena.

V tomto smyslu se ukládání dat do paměti RAM zásadně neliší od jejich ukládání na disk, protože při zápisu dat na disk také nejprve spadnou do mezipaměti stránky a fyzicky se zapisují až později. Záleží na tom, jak je souborový systém připojen. Ale pro každý případ řeknu, že ClickHouse na insertu nesynchronizuje.

V tomto případě jsou data v paměti RAM uložena přesně ve stejném formátu jako na disku. Výběrový dotaz vybere bloky ke čtení stejným způsobem, vybere požadované rozsahy dat v blokech a přečte je. A prewhere funguje úplně stejně, bez ohledu na to, zda byla data v RAM nebo na disku.

Do jakého počtu jedinečných hodnot je nízká kardinalita účinná?

Nízká kardinalita je ošidná. Sestavuje datové slovníky, ale ty jsou lokální. Za prvé jsou slovníky u každého kusu jiné a za druhé i v rámci jednoho kusu mohou být pro každý rozsah jiné. Když počet jedinečných hodnot dosáhne prahové hodnoty - myslím jeden milion - slovník se jednoduše odloží a vytvoří se nový.

Odpověď zní obecně: pro každý místní rozsah – řekněme pro každý den – někde až milion jedinečných hodnot je efektivní Nízká mohutnost. Poté bude následovat pouze záložní, ve kterém bude použito mnoho různých slovníků, nejen jeden. Bude fungovat v podstatě stejně jako běžný sloupec typu string, možná o něco méně efektivně, ale nedojde k žádné vážné degradaci výkonu.

Jaké jsou osvědčené postupy pro fulltextové vyhledávání v tabulce s pěti miliardami řádků?

Existují různé odpovědi. První je říci, že ClickHouse není fulltextový vyhledávač. Na to existují speciální systémy, např. Elastickýsearch и Sfinga. Vidím však stále více lidí, kteří říkají, že přecházejí z Elasticsearch na ClickHouse.

Proč se tohle děje? Vysvětlují to tím, že Elasticsearch přestává zvládat zatížení některých svazků, počínaje vytvářením indexů. Indexy jsou příliš těžkopádné, a pokud data jednoduše přenesete do ClickHouse, ukáže se, že jsou z hlediska objemu uloženy několikrát efektivněji. Vyhledávací dotazy přitom často nebyly takové, aby bylo nutné v celém množství dat najít nějakou frázi s přihlédnutím k morfologii, ale úplně jiné. Například najít posledních několik hodin v protokolech pro nějakou podsekvenci bajtů.

V tomto případě vytvoříte index v ClickHouse, první pole, ve kterém bude datum s časem. A největší limit dat bude přesně pro časové období. Ve zvoleném časovém rozmezí je již zpravidla možné provádět fulltextové vyhledávání i metodou brute-force pomocí like. Podobný příkaz v ClickHouse je nejúčinnější podobný příkaz, jaký můžete najít. Pokud najdete lepší, řekněte mi.

Ale stejně, jako je úplný sken. A plné skenování může být pomalé nejen na CPU, ale i na disku. Pokud najednou máte jeden terabajt dat za den a hledáte slovo za den, budete muset skenovat terabajt. A je to pravděpodobně na obyčejných pevných discích a ve výsledku budou načteny tak, že se na tento server přes SSH nedostanete.

V tomto případě jsem připraven nabídnout ještě jeden malý trik. Je z kategorie experimentální - může fungovat, nebo nemusí. ClickHouse má fulltextové indexy ve formě trigramových květových filtrů. Naši kolegové z Arenadata již tyto indexy vyzkoušeli a často fungují přesně tak, jak mají.

Abyste je mohli správně používat, měli byste dobře rozumět tomu, jak přesně fungují: co je to trigramový Bloomův filtr a jak vybrat jeho velikost. Mohu říci, že pomohou při dotazech na některé vzácné fráze, podřetězce, které se v datech vyskytují jen zřídka. V tomto případě budou podrozsahy vybrány podle indexů a bude načteno méně dat.

ClickHouse nedávno přidal ještě pokročilejší funkce pro fulltextové vyhledávání. Toto je za prvé hledání hromady podřetězců najednou v jednom průchodu, včetně možností rozlišujících malá a velká písmena, nerozlišující malá a velká písmena, podporované UTF-8 nebo pouze ASCII. Vyberte si ten nejúčinnější, který potřebujete.

Došlo také k hledání několika regulárních výrazů v jednom průchodu. Nemusíte psát X jako jeden podřetězec nebo X jako jiný podřetězec. Napište ihned a vše proběhne co nejefektivněji.

Za třetí, nyní existuje přibližné vyhledávání regulárních výrazů a přibližné vyhledávání podřetězců. Pokud někdo napsal slovo s překlepem, bude vyhledáno pro maximální shodu.

Jaký je nejlepší způsob, jak uspořádat přístup ke ClickHouse pro velký počet uživatelů?

Řekněte nám, jak nejlépe zorganizovat přístup pro velký počet spotřebitelů a analytiků. Jak vytvořit frontu, upřednostnit maximální počet souběžných dotazů a pomocí jakých nástrojů?

Pokud je cluster dostatečně velký, pak by bylo dobrým řešením pozvednout dva další servery, které se stanou vstupním bodem pro analytiky. To znamená, nepouštět analytiky do konkrétních shardů clusteru, ale jednoduše vytvořit dva prázdné servery bez dat a na nich již nastavit přístupová práva. Současně jsou uživatelská nastavení přenášena na vzdálené servery během distribuovaných požadavků. To znamená, že vše nakonfigurujete na těchto dvou serverech a nastavení má vliv na celý cluster.

V zásadě jsou tyto servery bez dat, ale velikost paměti RAM na nich je velmi důležitá pro provádění požadavků. Disk lze také použít pro dočasná data, pokud je povolena externí agregace nebo externí třídění.

Je důležité podívat se na nastavení, která jsou spojena se všemi možnými limity. Pokud nyní půjdu do clusteru Yandex.Metrics jako analytik a nastavím dotaz vyberte počet z hitů, pak mi bude okamžitě udělena výjimka, že požadavek nemohu splnit. Maximální počet řádků, které mohu naskenovat, je sto miliard a na clusteru v jedné tabulce je celkem padesát bilionů. Toto je první omezení.

Řekněme, že odstraním omezení počtu řádků a spustím dotaz znovu. Pak se mi zobrazí následující výjimka - nastavení je povoleno index síly podle data. Nemohu spustit dotaz, pokud jsem nezadal časové období. Nemusíte se spoléhat na to, že to analytici zadají ručně. Typický případ - časové období je zapsáno tam, kde je datum události mezi týdnem. A pak tam prostě nespecifikovali závorku a místo toho se ukázalo, že je nebo - nebo shoda URL. Pokud neexistuje žádný limit, projde sloupec URL a vyplýtvá spoustu zdrojů.

Kromě toho má ClickHouse dvě nastavení priority. Bohužel jsou velmi primitivní. Jeden se jmenuje jednoduše priorita. Pokud priorita ≠ 0 a jsou provedeny požadavky s určitou prioritou, ale je proveden požadavek s hodnotou priority, která je nižší, což znamená vyšší prioritu, je proveden požadavek s hodnotou priority vyšší než, což znamená nižší prioritu. jednoduše pozastaveno a nebude během této doby vůbec fungovat.

Toto je velmi hrubé nastavení a není vhodné pro situace, kdy je cluster neustále zatěžován. Ale pokud máte krátké, impulsní požadavky, které jsou důležité, a cluster je většinou nečinný, toto nastavení bude stačit.

Zavolá se další nastavení priority Priorita vlákna OS. Jednoduše vystaví všechna vlákna provádění požadavků příjemné hodnotě pro plánovač Linux. Funguje to tak nějak, ale stále to funguje. Pokud nastavíte minimální hodnotu nice - je to největší hodnota, a tedy nejnižší priorita - a nastavíte -19 pro požadavky s vysokou prioritou, pak CPU spotřebuje požadavky s nízkou prioritou asi čtyřikrát méně než ty s vysokou prioritou.

Musíte také nastavit maximální dobu provádění dotazu – řekněme pět minut. Minimální rychlost provádění požadavku je nejlepší věc. Toto nastavení existuje již dlouhou dobu a je třeba nejen potvrdit, že ClickHouse nezpomaluje, ale vynutit si jej.

Představte si, že nastavujete: pokud dotaz zpracovává méně než jeden milion řádků za sekundu, nemůžete to udělat. To dehonestuje naše dobré jméno, naši dobrou databázi. Prostě to zakažme. Ve skutečnosti existují dvě nastavení. Jeden se jmenuje min rychlost provedení - v řádcích za sekundu a druhý se nazývá časový limit před kontrolou minimální rychlosti provádění - ve výchozím nastavení patnáct sekund. To znamená, že je možné patnáct sekund a pak, pokud pomalu, stačí vyvolat výjimku - zrušit požadavek.

Musíte také nastavit kvóty. ClickHouse má vestavěnou funkci kvót, která počítá spotřebu zdrojů. Ale bohužel ne železné zdroje jako CPU, disky, ale logické - počet zpracovaných požadavků, přečtených řádků a bajtů. A nastavit si můžete třeba maximálně sto požadavků do pěti minut a tisíc požadavků za hodinu.

Proč je to důležité? Protože některé požadavky na analýzu budou prováděny ručně přímo z klienta ClickHouse. A všechno bude dobré. Ale pokud máte ve společnosti pokročilé analytiky, napíší skript a ve skriptu může být chyba. A tato chyba způsobí, že požadavek bude proveden v nekonečné smyčce. To je to, co je třeba chránit.

Je možné dát výsledky jedné žádosti deseti klientům?

Máme několik uživatelů, kteří rádi přicházejí s velmi velkými požadavky současně. Požadavek je velký, v zásadě je vyřízen rychle, ale vzhledem k tomu, že je takových požadavků najednou hodně, stává se velmi bolestivým. Je možné vyřídit stejnou žádost, která přišla desetkrát za sebou, jednou a dát výsledek deseti klientům?

Problém je v tom, že nemáme výsledky mezipaměti ani mezipaměť mezipaměti dat. K dispozici je mezipaměť stránek operačního systému, která vám umožní nečíst data z disku znovu, ale bohužel budou data stále dekomprimována, deserializována a znovu zpracována.

Rád bych se tomu nějak vyhnul, buď cachováním mezilehlých dat, nebo řazením podobných dotazů do nějaké fronty a přidáváním cache výsledků. Nyní máme ve vývoji jeden pull request, který přidává cache požadavků, ale pouze pro dílčí požadavky v sekcích in a join – to znamená, že řešení je podřadné.

Takovou situaci však máme také. Zvláště kanonickým příkladem jsou požadavky se stránkováním. Existuje zpráva, má několik stránek a je tam požadavek limit 10. Pak to samé, ale limit 10,10. Pak další stránka. A otázka je, proč to všechno pokaždé počítáme? Nyní však neexistuje žádné řešení a neexistuje způsob, jak se tomu vyhnout.

Existuje alternativní řešení, které je umístěno jako postranní vozík vedle ClickHouse - ClickHouse Proxy.

Kirill Shvakov: ClickHouse Proxy má vestavěný omezovač rychlosti a vestavěnou mezipaměť výsledků. Bylo tam provedeno hodně nastavení, protože se řešil podobný úkol. Proxy vám umožňuje omezit požadavky jejich zařazením do fronty a nakonfigurovat, jak dlouho žije mezipaměť požadavků. Pokud byly požadavky skutečně stejné, Proxy je poskytne mnohokrát a přejde do ClickHouse pouze jednou.

Nginx má také mezipaměť v bezplatné verzi a bude fungovat také. Nginx má dokonce nastavení, že pokud požadavky přijdou ve stejnou dobu, zastaví ostatní, dokud jeden nedokončí. Ale právě v ClickHouse Proxy je nastavení mnohem lepší. Byl vyroben speciálně pro ClickHouse, konkrétně pro tyto požadavky, takže je vhodnější. No, je snadné to nastavit.

A co asynchronní operace a materializované pohledy?

Je takový problém, že operace s nahrazujícím enginem jsou asynchronní – data se nejprve zapíší, pak se zhroutí. Pokud pod tabletem žije materializovaná tableta s nějakými agregáty, budou do ní zapsány duplikáty. A pokud neexistuje žádná složitá logika, budou data duplikována. Co se s tím dá dělat?

Existuje zřejmé řešení - implementovat spouštěč na konkrétní třídě matview během operace asynchronního sbalení. Existují nějaké „stříbrné odrážky“ na implementaci takové funkce?

Stojí za to pochopit, jak deduplikace funguje. To, co se chystám říci, s otázkou nesouvisí, ale pro každý případ stojí za to si to připomenout.

Při vkládání do replikované tabulky dochází k deduplikaci celých vložených bloků. Pokud znovu vložíte stejný blok obsahující stejný počet stejných řádků ve stejném pořadí, data se deduplikují. Jako odpověď na vložení dostanete "OK", ale jedna dávka dat bude skutečně zapsána a nebude duplikována.

To je nutné pro jistotu. Pokud během vkládání dostanete „OK“, vaše data byla vložena. Pokud obdržíte chybu od ClickHouse, pak nejsou vloženy a musíte opakovat vložení. Pokud se ale spojení během vkládání přeruší, pak nevíte, zda jsou data vložena nebo ne. Jedinou možností je opakování vkládání znovu. Pokud byla data skutečně vložena a vy jste je znovu vložili, došlo k deduplikaci bloku. Je potřeba, aby se předešlo duplicitám.

A u materializovaných pohledů je také důležité, jak to funguje. Pokud byla data při vkládání do hlavní tabulky deduplikována, pak také nepřejdou do materializovaného pohledu.

Nyní k otázce. Vaše situace je složitější, protože píšete duplikáty jednotlivých řádků. To znamená, že se neduplikuje celá sada, ale konkrétní řádky, které se zhroutí na pozadí. Data se skutečně sbalí v hlavní tabulce a nesbalená přejdou do materializovaného pohledu a se zhmotněnými pohledy se během slučování nic nestane. Protože materializovaný pohled není nic jiného než spoušť na insertu. Při dalších operacích se s ním nic jiného neděje.

A já tady nemůžu být šťastný. Jen je potřeba hledat konkrétní řešení pro tento případ. Je například možné jej nahradit v materializovaném pohledu a metoda deduplikace bude možná fungovat stejným způsobem. Ale bohužel ne vždy. Pokud je agregační, pak to nebude fungovat.

Kirill Shvakov: Svého času jsme také měli stavbu kostí. Vyskytl se problém, že existují zobrazení reklam a existují některá data, která můžeme zobrazit v reálném čase – jedná se pouze o zobrazení. Málokdy se duplikují, ale pokud ano, stejně je zhroutíme. A byly věci, které se nedají zopakovat – kliknutí a celý tento příběh. Ale také jsem je chtěl téměř okamžitě ukázat.

Jak vznikaly materializované pohledy? Byly pohledy, kde se to přímo zapisuje – je tam záznam v nezpracovaných datech a ten se zapisuje do pohledů. Tam v určité chvíli nejsou data příliš správná, jsou duplicitní a podobně. A je tu druhá část tabulky, kde vypadají úplně stejně jako zhmotněné pohledy, to znamená, že jsou strukturou úplně stejné. Jednou za čas data přepočítáme, spočítáme data bez duplicit, zapíšeme do těch tabulek.

Prošli jsme API - to nebude fungovat v ClickHouse ručně. A API vypadá: když mám datum posledního přidání do tabulky, kde je zaručeno, že už byla spočítána správná data, a udělá požadavek na jednu tabulku a na druhou tabulku. Z jednoho požadavku vybere až určitý čas a z druhého dostane to, co ještě nebylo spočítáno. A funguje to, ale ne pomocí jednoho ClickHouse.

Pokud máte nějaký druh API - pro analytiky, pro uživatele - pak je to v zásadě možnost. Vždycky počítáš, vždycky počítáš. To lze provést jednou denně nebo jindy. Sami si vyberete sortiment, který nepotřebujete a není kritický.

ClickHouse má spoustu protokolů. Jak mohu vidět vše, co se stane na serveru během okamžiku?

ClickHouse má velmi velký počet různých protokolů a tento počet se zvyšuje. V nových verzích jsou některé dokonce standardně povoleny, ve starších verzích je nutné je povolit při aktualizaci. Je jich však stále více. Chtěl bych konečně vidět, co se teď děje s mým serverem, možná na nějakém souhrnném dashboardu.

Máte v týmu ClickHouse, nebo v týmech svých přátel, kteří podporují nějakou funkcionalitu hotových dashboardů, které by tyto logy zobrazovaly jako hotový produkt? Nakonec, jen pohled na protokoly v ClickHouse je skvělý. Bylo by ale velmi cool, kdyby byl již připraven ve formě palubní desky. V tomhle bych se dostal vysoko.

Existují palubní desky, i když nejsou standardizované. V naší společnosti máme asi 60 týmů, které používají ClickHouse, a nejpodivnější je, že mnoho z nich má dashboardy, které si sami vyrobili a jsou trochu jiné. Některé týmy používají interní instalaci Yandex.Cloud. Existuje několik hotových zpráv, i když ne všechny potřebné. Ostatní mají své.

Moji kolegové z Metrice mají svůj vlastní dashboard v Grafaně a já mám svůj pro jejich vlastní cluster. Dívám se na věci, jako je hledání mezipaměti pro mezipaměť serif. A ještě obtížnější je, že používáme různé nástroje. Svůj řídicí panel jsem vytvořil na velmi starém nástroji s názvem Graphite-web. Je úplně ošklivý. A používám to tak dodnes, i když Grafana by byla asi pohodlnější a krásnější.

Základní věc v dashboardech je stejná. Toto jsou systémové metriky pro cluster: CPU, paměť, disk, síť. Dalšími jsou počet současných požadavků, počet simultánních sloučení, počet požadavků za sekundu, maximální počet chunků pro oddíly tabulky MergeTree, zpoždění replikace, velikost replikační fronty, počet řádků vložených za sekundu, počet vložených bloků za sekundu. To je vše, co se nezíská z protokolů, ale z metrik.

Vladimír Kolobajev: Alexey, rád bych to trochu poopravil. Je tam Grafana. Grafana má zdroj dat, kterým je ClickHouse. To znamená, že mohu zadávat požadavky z Grafany přímo ClickHouse. ClickHouse má tabulku s logy, ta je pro všechny stejná. V důsledku toho chci získat přístup k této tabulce protokolů v Grafaně a zobrazit požadavky, které můj server používá. Bylo by skvělé mít takovou palubní desku.

Sám jsem to jezdil na kole. Ale mám otázku - když je to všechno standardizované a Grafana používá každý, proč Yandex nemá takový oficiální dashboard?

Kirill Shvakov: Ve skutečnosti zdroj dat, který ClickHouse nyní podporuje Altinity. A já chci jen dát vektor, kde kopat a koho tlačit. Můžete se jich zeptat, protože Yandex stále vyrábí ClickHouse, a ne příběh kolem něj. Altinity je hlavní společností, která v současnosti propaguje ClickHouse. Neopustí ho, ale podpoří ho. Protože v zásadě, abyste mohli nahrát dashboard na web Grafana, musíte se pouze zaregistrovat a nahrát jej - neexistují žádné zvláštní problémy.

Alexey Milovidov: Za poslední rok ClickHouse přidal mnoho funkcí pro profilování dotazů. Pro každý požadavek na využití zdroje existují metriky. A nedávno byl přidán profiler dotazů ještě nižší úrovně, aby bylo možné zjistit, kde každou milisekundu dotaz stráví. Ale abych mohl tuto funkci použít, musím otevřít konzolového klienta a zadat dotaz, který stále zapomínám. Někam jsem to uložil a vždy zapomenu, kde přesně.

Přál bych si, aby existoval nástroj, který jen říká - zde jsou vaše těžké dotazy seskupené podle třídy dotazů. Klikl jsem na jeden a oni mi řekli, že je proto těžký. Nyní takové řešení neexistuje. A je opravdu docela zvláštní, že když se mě lidé ptají: „Řekni mi, existují nějaké hotové dashboardy pro Grafanu?“, řeknu: „Přejdi na web Grafany, je tam komunita Dashboards a je tam dashboard od Dimky , tam od Kostjana. Nevím, co to je, sám jsem to nepoužil."

Jak ovlivnit merdzhi, aby server nespadl do OOM?

Mám tabulku, v tabulce je pouze jeden oddíl, je to ReplacingMergeTree. Zapisuji do něj data čtyři roky. Musel jsem v něm provést změnu a vymazat některá data.

Udělal jsem to a v průběhu zpracování tohoto požadavku byla spotřebována veškerá paměť na všech serverech v clusteru a všechny servery v clusteru přešly do OOM společně. Pak se všichni společně zvedli, začali slučovat stejnou operaci, tento datový blok, a znovu spadli do OOM. Pak znovu vstali a zase spadli. A tahle věc se nezastavila.

Pak se ukázalo, že to je vlastně chyba, kterou kluci opravili. To je skvělé, děkuji mnohokrát. Ale zbytek zůstal. A teď, když přemýšlím nad tím, že je potřeba provést určité sloučení v tabulce, mám otázku - proč si tyto sloučení nemohu vzít a nějak je ovlivnit? Omezte je například množstvím požadované paměti RAM nebo v zásadě jejich počtem, který bude zpracovávat tuto konkrétní tabulku.

Mám tabulku s názvem "Metrics", prosím zpracujte mi ji ve dvou proudech. Není třeba vyrábět deset nebo pět sloučení paralelně, udělejte to ve dvou. Myslím, že ve dvou mám paměti dost, ale na zpracování deseti to nemusí stačit. Proč strach zůstává? Protože tabulka roste a jednou se setkám se situací, která už v zásadě není způsobena chybou, ale tím, že se data změní v tak velkém množství, že prostě nemám dostatek paměti server. A pak server během sloučení spadne do OOM. Navíc mohu zrušit mutaci, ale sloučení je pryč.

Víte, při slučování server nespadne do OOM, protože při slučování se množství RAM spotřebuje pouze na jeden malý datový rozsah. Vše tedy bude v pořádku bez ohledu na množství dat.

Vladimír Kolobajev: Pokuta. Tady je moment takový, že poté, co jsme provedli opravu chyby, jsem si stáhl novou verzi pro sebe a na jiném stole, menším, kde je spousta oddílů, jsem provedl podobnou operaci. A během sloučení bylo na serveru vypáleno asi 100 GB RAM. Měl jsem 150 zaneprázdněných, snědl 100 a zbývalo 50 GB okno, takže jsem nespadl do OOM.

Co mě aktuálně chrání před pádem do OOM, když opravdu žere 100 GB RAM? Co dělat v situaci, když náhle dojde RAM na merdzhu?

Alexey Milovidov: Existuje takový problém, že spotřeba RAM není omezena na merdzhi. A druhý problém je, že pokud bylo přiřazeno sloučení, pak se musí provést, protože se zapisuje do protokolu replikace. Protokol replikace představuje akce, které jsou potřebné k uvedení repliky do konzistentního stavu. Pokud neprovedete ruční manipulace, které tento protokol replikace vrátí zpět, sloučení bude muset být provedeno tak či onak.

Samozřejmě by nebylo zbytečné mít omezení na RAM, která „pro jistotu“ chrání před OOM. Sloučení to nepomůže, spustí se znovu, dosáhne nějaké prahové hodnoty, vyvolá výjimku a pak začne znovu – nic dobrého z toho nevzejde. Ale v zásadě by bylo užitečné toto omezení zavést.

Jak bude probíhat vývoj ovladače Golang pro ClickHouse?

Ovladač Golang napsaný Kirillem Shvakovem je nyní oficiálně podporován týmem ClickHouse. On v úložišti ClickHouse, je teď velký a skutečný.

Malá poznámka. Existuje úžasné a milované úložiště normálních forem nekonečného řádu - to je Vertica. Mají také svůj vlastní oficiální python ovladač, který udržují vývojáři Vertica. A několikrát se stalo, že se verze úložiště a verze ovladače docela náhle rozešly a ovladač v určitém okamžiku přestal fungovat. A druhý bod. Zdá se mi, že podpora pro tento oficiální ovladač je udržována systémem „vsuvek“ - napíšete jim problém a navždy zůstane.

Mám dvě otázky. Nyní je Kirillův ovladač Golang téměř výchozím způsobem komunikace z Golang s ClickHouse. Pokud někdo stále nekomunikuje přes http rozhraní, protože se mu to tak líbí. Jak bude tento ovladač vyvíjen? Bude to synchronizováno s nějakými zásadními změnami v samotném úložišti? A jaký je postup při zvažování problému?

Kirill Shvakov: První je, jak je vše byrokraticky uspořádáno. Tento bod nebyl projednán, takže nemám co odpovídat.

Abychom odpověděli na otázku týkající se problému, potřebujeme malou historii ovladače. Pracoval jsem pro společnost, která měla hodně dat. Byl to reklamní spinner s obrovským množstvím akcí, které bylo potřeba někam uložit. A v určitém okamžiku se objevil ClickHouse. Nasypali jsme do něj data a zpočátku bylo vše v pořádku, ale pak spadl ClickHouse. Tehdy jsme se rozhodli, že to nepotřebujeme.

O rok později jsme se vrátili k myšlence používat ClickHouse a potřebovali jsme tam nějak zapisovat data. Vstup byl tento - železo je velmi slabé, je málo zdrojů. Ale my jsme vždy pracovali tímto způsobem, a proto jsme se zaměřili na nativní protokol.

Protože jsme pracovali na Go, bylo jasné, že potřebujeme Go driver. Dělal jsem to skoro na plný úvazek – byl to můj pracovní úkol. Do určitého bodu jsme to vychovali a v zásadě nikdo nečekal, že to využije někdo jiný než my. Pak přišel CloudFlare s úplně stejným problémem a nějakou dobu jsme s nimi pracovali velmi hladce, protože měli stejné úkoly. A udělali jsme to jak v samotném ClickHouse, tak v ovladači.

V určitém okamžiku jsem to prostě přestal dělat, protože moje činnost v rámci ClickHouse a práce se trochu změnila. Problémy proto nejsou uzavřeny. Lidé, kteří sami něco potřebují, se pravidelně zavazují k úložišti. Pak se podívám na pull request a občas i sám něco upravím, ale to se stává málokdy.

Chci se vrátit k řidiči. Před pár lety, když to celé začalo, byl ClickHouse také jiný a s jinými funkcemi. Nyní existuje pochopení, jak předělat ovladač tak, aby byl dobrý. Pokud k tomu dojde, verze 2 bude stejně nekompatibilní kvůli nahromaděným berličkám.

Nevím, jak to zařídit. Já sám nemám moc času. Pokud někteří lidé dokončí ovladač, mohu jim pomoci a říct jim, co mají dělat. Ale o aktivní účasti Yandexu na vývoji projektu se zatím nijak nediskutovalo.

Alexey Milovidov: Ve skutečnosti zatím žádná byrokracie ohledně těchto řidičů neexistuje. Jediná věc je, že jsou přesunuty do oficiální organizace, to znamená, že tento ovladač je uznáván jako oficiální výchozí řešení pro Go. Existuje několik dalších ovladačů, ale jsou dodávány samostatně.

Uvnitř nemáme žádný vývoj pro tyto ovladače. Otázkou je, zda dokážeme najmout jednotlivce, ne konkrétně pro tohoto řidiče, ale pro rozvoj všech komunitních řidičů, nebo najdeme někoho mimo.

Externí slovník se po restartu s povoleným lazy_load nezvedne. Co dělat?

Máme povolené nastavení lazy_load a po restartu serveru se samotný slovník nezvedne. Vyvolá se až poté, co uživatel přistoupí k tomuto slovníku. A při prvním volání to vyhodí chybu. Dají se slovníky pomocí ClickHouse nějak automaticky načítat, nebo je potřeba vždy sami kontrolovat jejich připravenost, aby se uživatelům nezobrazovaly chyby?

Možná máme starou verzi ClickHouse, takže slovník nebyl automaticky načten. To může být?

Nejprve lze pomocí dotazu vynutit načtení slovníků slovníky pro opětovné načtení systému. Za druhé o té chybě - pokud je slovník již načten, budou dotazy fungovat na načtená data. Pokud slovník ještě nebyl načten, bude načten přímo v okamžiku požadavku.

U těžkých slovníků to není příliš pohodlné. Například potřebujete načíst milion řádků z MySQL. Někdo provede jednoduchý výběr, ale tento výběr bude čekat na stejný milion řádků. Zde jsou dvě řešení. První je vypnout lazy_load. Druhým je, když se server zvedne, před zapnutím zátěže na něm udělejte systémový reload slovník nebo stačí provést dotaz, který používá slovník. Poté se slovník načte. Dostupnost slovníků musíte ovládat s povoleným nastavením lazy_load, protože ClickHouse je nevytahuje automaticky.

Odpověď na poslední otázku je, že buď je verze stará, nebo je potřeba ji odladit.

Co na tom, že slovníky pro opětovné načtení systému nenačtou žádný z mnoha slovníků, pokud alespoň jeden z nich spadne s chybou?

Existuje další otázka týkající se slovníků pro obnovení systému. Máme dva slovníky – jeden se nenačte, druhý se načte. Slovníky pro opětovné načtení systému v tomto případě nenačítají žádný slovník a vy musíte konkrétní načíst z bodu do bodu podle jeho názvu pomocí slovníku pro opětovné načtení systému. Souvisí to také s verzí ClickHouse?

chci potěšit. Toto chování se změnilo. Pokud tedy aktualizujete ClickHouse, změní se také. Pokud nejste spokojeni se současným chováním slovníky pro opětovné načtení systému, aktualizujte a doufejme, že se to změní k lepšímu.

Existuje způsob, jak nakonfigurovat podrobnosti v konfiguraci ClickHouse, ale neosvětlit je při chybách?

Další otázka se týká chyb souvisejících se slovníkem, konkrétně podrobností. Zaregistrovali jsme podrobnosti o připojení v konfiguraci ClickHouse do slovníku a v případě chyby obdržíme tyto podrobnosti a heslo jako odpověď.

Tuto chybu jsme vyřešili přidáním podrobností do konfigurace ovladače ODBC. Existuje nějaký způsob, jak nakonfigurovat podrobnosti v konfiguraci ClickHouse, ale nezobrazovat tyto podrobnosti při chybách?

Zde je řešení skutečně - zadat tyto přihlašovací údaje v odbc.ini a v samotném ClickHouse zadat pouze název zdroje dat ODBC. U jiných zdrojů slovníků se to nestane – ani u slovníku s MySQL, ani u ostatních byste heslo v chybové zprávě neměli vidět. U ODBC se také podívám - pokud něco takového existuje, stačí to odstranit.

Bonus: pozadí pro Zuma ze setkání

Kliknutím na obrázek pro nejvytrvalejší čtenáře se otevřou bonusová pozadí ze srazů. Hašení ohně společně s Avitovými technologickými maskoty, konzultování s kolegy z místnosti správce systému nebo oldschoolového počítačového klubu a každodenní pořádání pod mostem na pozadí graffiti.

ClickHouse pro pokročilé uživatele v otázkách a odpovědích

Zdroj: www.habr.com

Přidat komentář