Provoz ClickHouse v produkci: ingestce, merge a náklady při 2 miliardách řádků
Naše zkušenosti s provozem ClickHouse v produkci: návrh schématu, optimalizace dotazů a jak dosahujeme sub-sekundové analytiky napříč více než 100M device událostmi.
Když jsme začali stavět analytickou vrstvu tracio.ai, potřebovali jsme databázi, která zvládne naši specifickou zátěž: ingestovat 50 000 událostí identifikace zařízení za sekundu, uložit 2+ miliardy řádků a odpovídat na analytické dotazy pod jednou sekundou. Vyhodnotili jsme PostgreSQL (příliš pomalý pro agregace v tomto měřítku), Elasticsearch (příliš drahý pro time-series analytiku) a ClickHouse. ClickHouse zvítězil jednoznačně.
Proč ClickHouse
ClickHouse je sloupcově orientovaná OLAP databáze navržená pro analytiku v reálném čase. Její klíčovou výhodou pro naši zátěž je, že čte pouze sloupce potřebné pro každý dotaz. Když se fraud analytik zeptá „ukaž mi míru podvodů podle zemí za posledních 7 dní“, ClickHouse přečte jen sloupce country, timestamp a risk_score — a ignoruje zbylých 40+ sloupců v tabulce událostí. Na tabulce s 2 miliardami řádků to sníží I/O o 95 %.
ClickHouse také extrémně dobře komprimuje data. Naše tabulka událostí s 2 miliardami řádků zabírá na disku 340 GB — přibližně 170 bajtů na řádek po kompresi oproti 1,2 KB na řádek bez komprese. Kompresní poměr 7:1 znamená, že do paměti se vejde více dat, což se přímo promítá do rychlejších dotazů.
Návrh schématu
Naše primární tabulka ukládá jeden řádek na každou událost identifikace:
Tabulka používá engine MergeTree, řazený podle (workspace_id, toDate(timestamp), visitor_hash). Toto řazení je zásadní — znamená, že dotazy filtrované podle workspace a rozsahu dat čtou minimum dat. Sloupec visitor_hash umožňuje rychlé vyhledávání podle ID návštěvníka bez sekundárního indexu.
Pro sloupce country, device_type, browser_family a os_family jsme zvolili LowCardinality(String), protože tyto sloupce mají méně než 10 000 unikátních hodnot. ClickHouse ukládá sloupce LowCardinality jako slovníkově zakódovaná celá čísla, čímž snižuje úložiště o 80 % oproti prostým řetězcům a zrychluje operace GROUP BY.
Strategie shardingu
Tabulku událostí shardujeme přes 6 uzlů pomocí hashe z workspace_id. To zajišťuje, že všechny události daného zákazníka jsou na stejném shardu, což znamená, že většina dotazů (filtrovaných podle workspace_id) zasáhne jediný shard. Dotazy napříč shardy jsou potřeba jen pro interní analytiku.
Každý shard má 2 repliky pro vysokou dostupnost. Replikace využívá vestavěný engine ClickHouse ReplicatedMergeTree s koordinací přes ZooKeeper. Failover je automatický — pokud shard vypadne, dotazy jsou přesměrovány na repliku bez jakýchkoli změn na straně klienta.
Ingestní pipeline
Události proudí z našeho Kafka topicu do ClickHouse skrze vlastní službu v Go, která dávkuje vkládání. Vkládáme v dávkách po 10 000 řádcích každých 500 ms — to vyvažuje latenci ingestce (pod sekundu) s efektivitou vkládání (ClickHouse podává nejlepší výkon s velkými dávkami).
Ingestní služba zvládá zpětný tlak elegantně. Pokud je ClickHouse pomalý v přijímání vkládání (během merge nebo vysoké zátěže dotazy), služba bufferuje až 1 milion událostí v paměti a aplikuje zpětný tlak na Kafka consumera. Za 18 měsíců v produkci jsme nikdy neztratili událost.
Optimalizace dotazů
Materializované pohledy
Pro běžné dashboardové dotazy používáme materializované pohledy, které data předagregují. Náš dashboard míry podvodů například čte z materializovaného pohledu, který agreguje počty fraud_detected podle workspace, země a hodiny. Pohled sníží objem dat prohledávaných tímto dotazem z 2 miliard řádků na 5 milionů řádků.
Řazení projekcí
Projekce ClickHouse nám umožňují definovat alternativní pořadí řazení pro tabulku bez duplikace dat. Pro dotazy na časovou osu návštěvníka jsme přidali projekci řazenou podle (workspace_id, visitor_hash, timestamp). Bez projekce tyto dotazy prohledávaly celé rozsahy dat. S ní čtou pouze bloky obsahující cílového návštěvníka.
Přibližné funkce
Pro dashboardové dotazy, kde přesné počty nejsou kritické, používáme přibližné funkce ClickHouse: uniqCombined pro počty unikátních hodnot (2% chybová marže, 10x rychlejší než uniqExact) a quantileTDigest pro výpočty percentilů. Dashboard fraud analytiky používá výhradně přibližné funkce, což udrží všechny dashboardové dotazy pod 200 ms.
Výkonnostní čísla
Zde jsou reprezentativní benchmarky dotazů na našem produkčním clusteru s 2 miliardami řádků:
Míra podvodů podle zemí, posledních 7 dní: 120 ms. Časová osa návštěvníka (50 událostí): 8 ms. Unikátní návštěvníci za den, posledních 30 dní: 340 ms. Distribuce risk score, posledních 24 hodin: 95 ms. Top 100 zařízení podle počtu událostí, posledních 30 dní: 210 ms.
Tato čísla zahrnují síťový round-trip z našich aplikačních serverů do clusteru ClickHouse. Čistý čas provedení dotazu je typicky o 30–50 % nižší.
Provozní lekce
Lekce 1: Sledujte zpoždění merge
Engine MergeTree v ClickHouse průběžně slučuje malé data party do větších. Pokud merge zaostávají (kvůli vysoké rychlosti vkládání nebo soupeření o diskové I/O), výkon dotazů klesá, protože dotazy musí prohledávat více partů. Sledujeme počet partů na partici a alertujeme, když překročí 300.
Lekce 2: Vyhněte se velkým operacím ALTER TABLE
Přidání sloupce do tabulky s 2 miliardami řádků je v ClickHouse okamžité (týká se jen metadat). Ale změna typu sloupce vyžaduje přepsání všech data partů — proces, který na našem clusteru trval 6 hodin. Se schématem nyní zacházíme jako s append-only: nové sloupce přidáváme volně, ale změny typu procházejí přes migrační tabulku.
Lekce 3: TTL s opatrností
ClickHouse podporuje automatickou expiraci dat přes TTL. Na naší tabulce událostí jsme nastavili TTL 90 dní. Zádrhel: mazání přes TTL probíhá během merge, což znamená, že smazaná data mohou přetrvávat hodiny nebo dny po vypršení TTL. Pro mazání kritické z hlediska compliance spouštíme explicitní dotazy ALTER TABLE DELETE podle plánu.
Náklady
Náš šestiuzlový cluster ClickHouse (každý uzel: 32 vCPU, 128 GB RAM, 2 TB NVMe) stojí zhruba 8 400 USD měsíčně na bare-metal hostingu. Ukládá 2 miliardy řádků s 90denní retencí a zvládá 50K vkládání za sekundu plus 200 souběžných dashboardových dotazů. Náklad na uloženou událost je 0,0000042 USD — o řády levněji než srovnatelná analytika na spravovaných cloudových databázích.