ClickHouse i produktion: ingestion, merges och kostnad vid 2 miljarder rader
Vår erfarenhet av att köra ClickHouse i produktion: schemadesign, frågeoptimering och hur vi når analys på under en sekund över mer än 100 miljoner device-events.
När vi började bygga analysnivån för tracio.ai behövde vi en databas som klarade vår specifika arbetslast: ta emot 50 000 device-identifieringsevents per sekund, lagra 2+ miljarder rader och besvara analytiska frågor på under en sekund. Vi utvärderade PostgreSQL (för långsam för aggregeringar i den här skalan), Elasticsearch (för dyr för time-series-analys) och ClickHouse. ClickHouse vann överlägset.
Varför ClickHouse
ClickHouse är en kolumnorienterad OLAP-databas byggd för realtidsanalys. Dess främsta fördel för vår arbetslast är att den bara läser de kolumner som behövs för varje fråga. När en fraud-analytiker frågar "visa fraud-frekvensen per land för de senaste 7 dagarna" läser ClickHouse bara kolumnerna country, timestamp och risk_score — och ignorerar de övriga 40+ kolumnerna i event-tabellen. På en tabell med 2 miljarder rader minskar detta I/O med 95 %.
ClickHouse komprimerar också data extremt bra. Vår event-tabell med 2 miljarder rader upptar 340 GB på disk — ungefär 170 byte per rad komprimerat, mot 1,2 KB per rad okomprimerat. Komprimeringsförhållandet på 7:1 innebär att mer data får plats i minnet, vilket direkt översätts till snabbare frågor.
Schemadesign
Vår primära tabell lagrar en rad per identifieringsevent:
Tabellen använder MergeTree-motorn, ordnad efter (workspace_id, toDate(timestamp), visitor_hash). Denna ordning är avgörande — den innebär att frågor filtrerade på workspace och datumintervall läser minimalt med data. Kolumnen visitor_hash möjliggör snabba uppslagningar på visitor-ID utan ett sekundärt index.
Vi valde LowCardinality(String) för country, device_type, browser_family och os_family eftersom dessa kolumner har färre än 10 000 distinkta värden. ClickHouse lagrar LowCardinality-kolumner som dictionary-kodade heltal, vilket minskar lagringen med 80 % jämfört med vanliga strängar och snabbar upp GROUP BY-operationer.
Sharding-strategi
Vi shardar event-tabellen över 6 noder med hjälp av en hash av workspace_id. Detta säkerställer att alla events för en given kund ligger på samma shard, vilket innebär att de flesta frågor (filtrerade på workspace_id) träffar en enda shard. Frågor över flera shards behövs bara för intern analys.
Varje shard har 2 repliker för hög tillgänglighet. Replikeringen använder ClickHouses inbyggda ReplicatedMergeTree-motor med ZooKeeper-koordinering. Failover är automatiskt — om en shard går ner dirigeras frågor till repliken utan några ändringar på klientsidan.
Ingestion-pipeline
Events flödar från vårt Kafka-topic in i ClickHouse via en egen Go-tjänst som batchar inserts. Vi infogar i batchar om 10 000 rader var 500:e ms — detta balanserar ingestion-latens (under en sekund) mot insert-effektivitet (ClickHouse presterar bäst med stora batchar).
Ingestion-tjänsten hanterar back-pressure elegant. Om ClickHouse är långsam med att ta emot inserts (under merges eller tung frågelast) buffrar tjänsten upp till 1 miljon events i minnet och applicerar back-pressure på Kafka-konsumenten. På 18 månader i produktion har vi aldrig förlorat ett event.
Frågeoptimering
Materialized views
För vanliga dashboard-frågor använder vi materialized views som föraggregerar data. Vår fraud-frekvens-dashboard läser till exempel från en materialized view som aggregerar fraud_detected-räkningar per workspace, country och timme. Vyn minskar den data som skannas för denna fråga från 2 miljarder rader till 5 miljoner rader.
Projection-ordning
ClickHouse-projections låter oss definiera alternativa sorteringsordningar för en tabell utan att duplicera data. Vi lade till en projection ordnad efter (workspace_id, visitor_hash, timestamp) för visitor-timeline-frågor. Utan projectionen skannade dessa frågor hela datumintervall. Med den läser de bara de block som innehåller den sökta besökaren.
Approximativa funktioner
För dashboard-frågor där exakta räkningar inte är kritiska använder vi ClickHouses approximativa funktioner: uniqCombined för distinkta räkningar (2 % felmarginal, 10x snabbare än uniqExact) och quantileTDigest för percentilberäkningar. Fraud-analytics-dashboarden använder uteslutande approximativa funktioner, vilket håller alla dashboard-frågor under 200 ms.
Prestandasiffror
Här är representativa fråge-benchmarks på vårt produktionskluster med 2 miljarder rader:
Fraud-frekvens per land, senaste 7 dagarna: 120 ms. Visitor-timeline (50 events): 8 ms. Unika besökare per dag, senaste 30 dagarna: 340 ms. Fördelning av risk-score, senaste 24 timmarna: 95 ms. Topp 100 enheter efter event-antal, senaste 30 dagarna: 210 ms.
Dessa siffror inkluderar nätverkets tur och retur från våra applikationsservrar till ClickHouse-klustret. Ren frågekörningstid är typiskt 30–50 % lägre.
Driftlärdomar
Lärdom 1: Övervaka merge-eftersläpning
ClickHouses MergeTree-motor slår kontinuerligt samman små data-parts till större. Om merges hamnar på efterkälken (på grund av hög insert-frekvens eller disk-I/O-konkurrens) försämras frågeprestandan eftersom frågorna måste skanna fler parts. Vi övervakar antalet parts per partition och larmar när det överstiger 300.
Lärdom 2: Undvik stora ALTER TABLE-operationer
Att lägga till en kolumn i en tabell med 2 miljarder rader i ClickHouse är omedelbart (det rör bara metadata). Men att ändra en kolumntyp kräver att alla data-parts skrivs om — en process som tog 6 timmar på vårt kluster. Vi behandlar nu schemat som append-only: nya kolumner läggs till fritt, men typändringar går genom en migrationstabell.
Lärdom 3: TTL med försiktighet
ClickHouse stöder automatisk datautgång via TTL. Vi satte en TTL på 90 dagar på vår event-tabell. Haken: TTL-radering sker under merges, vilket innebär att raderad data kan finnas kvar i timmar eller dagar efter att TTL:en löpt ut. För efterlevnadskritisk radering kör vi explicita ALTER TABLE DELETE-frågor enligt schema.
Kostnad
Vårt ClickHouse-kluster med 6 noder (varje nod: 32 vCPU, 128 GB RAM, 2 TB NVMe) kostar cirka 8 400 USD/månad på bare metal-hosting. Detta lagrar 2 miljarder rader med 90 dagars retention och hanterar 50 000 inserts/sekund plus 200 samtidiga dashboard-frågor. Kostnaden per lagrat event är 0,0000042 USD — flera storleksordningar billigare än jämförbar analys på managed molndatabaser.