Menjalankan ClickHouse di Produksi: Ingestion, Merge & Biaya pada 2 Miliar Baris
Pengalaman kami menjalankan ClickHouse di produksi: desain skema, optimasi query, dan cara kami mencapai analitik sub-detik di lebih dari 100 juta event perangkat.
Ketika kami mulai membangun lapisan analitik tracio.ai, kami membutuhkan basis data yang mampu menangani beban kerja spesifik kami: melakukan ingest 50.000 event identifikasi perangkat per detik, menyimpan 2+ miliar baris, dan menjawab query analitis dalam kurang dari satu detik. Kami mengevaluasi PostgreSQL (terlalu lambat untuk agregasi pada skala ini), Elasticsearch (terlalu mahal untuk analitik time-series), dan ClickHouse. ClickHouse menang telak.
Mengapa ClickHouse
ClickHouse adalah basis data OLAP berorientasi kolom yang dirancang untuk analitik real-time. Keunggulan utamanya untuk beban kerja kami adalah ia hanya membaca kolom yang diperlukan untuk setiap query. Ketika seorang analis fraud bertanya "tunjukkan tingkat fraud per negara untuk 7 hari terakhir", ClickHouse hanya membaca kolom country, timestamp, dan risk_score — mengabaikan 40+ kolom lain di tabel event. Pada tabel 2 miliar baris, ini mengurangi I/O sebesar 95%.
ClickHouse juga mengompresi data dengan sangat baik. Tabel event 2 miliar baris kami menempati 340 GB di disk — sekitar 170 byte per baris terkompresi, dibandingkan 1,2 KB per baris tanpa kompresi. Rasio kompresi 7:1 berarti lebih banyak data muat di memori, yang secara langsung berujung pada query yang lebih cepat.
Desain Skema
Tabel utama kami menyimpan satu baris per event identifikasi:
Tabel ini menggunakan engine MergeTree, diurutkan berdasarkan (workspace_id, toDate(timestamp), visitor_hash). Pengurutan ini sangat penting — artinya query yang difilter berdasarkan workspace dan rentang tanggal membaca data seminimal mungkin. Kolom visitor_hash memungkinkan pencarian cepat berdasarkan visitor ID tanpa indeks sekunder.
Kami memilih LowCardinality(String) untuk country, device_type, browser_family, dan os_family karena kolom-kolom ini memiliki kurang dari 10.000 nilai berbeda. ClickHouse menyimpan kolom LowCardinality sebagai integer yang dienkode kamus (dictionary-encoded), mengurangi penyimpanan hingga 80% dibandingkan string biasa dan mempercepat operasi GROUP BY.
Strategi Sharding
Kami melakukan sharding pada tabel event di 6 node menggunakan hash dari workspace_id. Ini memastikan semua event untuk pelanggan tertentu berada pada shard yang sama, yang berarti sebagian besar query (difilter berdasarkan workspace_id) menyentuh satu shard saja. Query lintas shard hanya diperlukan untuk analitik internal.
Setiap shard memiliki 2 replika untuk ketersediaan tinggi (high availability). Replikasi menggunakan engine ReplicatedMergeTree bawaan ClickHouse dengan koordinasi ZooKeeper. Failover berlangsung otomatis — jika sebuah shard down, query dialihkan ke replika tanpa perubahan di sisi klien.
Pipeline Ingestion
Event mengalir dari topik Kafka kami ke ClickHouse melalui layanan Go khusus yang melakukan batch pada insert. Kami melakukan insert dalam batch berisi 10.000 baris setiap 500ms — ini menyeimbangkan latensi ingestion (sub-detik) dengan efisiensi insert (ClickHouse berkinerja terbaik dengan batch besar).
Layanan ingestion menangani back-pressure dengan baik. Jika ClickHouse lambat menerima insert (selama merge atau beban query berat), layanan menyangga hingga 1 juta event di memori dan menerapkan back-pressure ke konsumer Kafka. Dalam 18 bulan produksi, kami tidak pernah kehilangan satu event pun.
Optimasi Query
Materialized View
Untuk query dashboard yang umum, kami menggunakan materialized view yang melakukan pra-agregasi data. Dashboard tingkat fraud kami, misalnya, membaca dari materialized view yang mengagregasi jumlah fraud_detected berdasarkan workspace, country, dan jam. View tersebut mengurangi data yang dipindai untuk query ini dari 2 miliar baris menjadi 5 juta baris.
Pengurutan Projection
Projection ClickHouse memungkinkan kami mendefinisikan urutan pengurutan alternatif untuk sebuah tabel tanpa menduplikasi data. Kami menambahkan projection yang diurutkan berdasarkan (workspace_id, visitor_hash, timestamp) untuk query linimasa visitor. Tanpa projection, query-query ini memindai seluruh rentang tanggal. Dengan projection, mereka hanya membaca blok yang berisi visitor target.
Fungsi Aproksimasi
Untuk query dashboard yang jumlah persisnya tidak kritis, kami menggunakan fungsi aproksimasi ClickHouse: uniqCombined untuk penghitungan nilai berbeda (margin kesalahan 2%, 10x lebih cepat daripada uniqExact) dan quantileTDigest untuk kalkulasi persentil. Dashboard analitik fraud menggunakan fungsi aproksimasi secara eksklusif, yang menjaga semua query dashboard di bawah 200ms.
Angka Kinerja
Berikut adalah benchmark query representatif pada cluster produksi 2 miliar baris kami:
Tingkat fraud per negara, 7 hari terakhir: 120ms. Linimasa visitor (50 event): 8ms. Visitor unik per hari, 30 hari terakhir: 340ms. Distribusi risk score, 24 jam terakhir: 95ms. 100 perangkat teratas berdasarkan jumlah event, 30 hari terakhir: 210ms.
Angka-angka ini mencakup round-trip jaringan dari server aplikasi kami ke cluster ClickHouse. Waktu eksekusi query murni biasanya 30-50% lebih rendah.
Pelajaran Operasional
Pelajaran 1: Pantau merge lag
Engine MergeTree ClickHouse terus-menerus menggabungkan part data kecil menjadi part yang lebih besar. Jika merge tertinggal (akibat laju insert tinggi atau kontensi I/O disk), kinerja query menurun karena query harus memindai lebih banyak part. Kami memantau jumlah part per partisi dan memberi peringatan ketika melebihi 300.
Pelajaran 2: Hindari operasi ALTER TABLE besar
Menambahkan kolom ke tabel 2 miliar baris di ClickHouse berlangsung instan (hanya metadata). Namun mengubah tipe kolom memerlukan penulisan ulang semua part data — proses yang memakan 6 jam pada cluster kami. Kami kini memperlakukan skema sebagai append-only: kolom baru ditambahkan dengan bebas, tetapi perubahan tipe melewati tabel migrasi.
Pelajaran 3: TTL dengan hati-hati
ClickHouse mendukung kedaluwarsa data otomatis via TTL. Kami menetapkan TTL 90 hari pada tabel event kami. Jebakannya: penghapusan TTL terjadi selama merge, yang berarti data terhapus mungkin bertahan berjam-jam atau berhari-hari setelah TTL kedaluwarsa. Untuk penghapusan yang kritis bagi kepatuhan (compliance), kami menjalankan query ALTER TABLE DELETE eksplisit secara terjadwal.
Biaya
Cluster ClickHouse 6 node kami (setiap node: 32 vCPU, 128 GB RAM, 2 TB NVMe) menghabiskan sekitar $8.400/bulan pada hosting bare metal. Ini menyimpan 2 miliar baris dengan retensi 90 hari dan menangani 50 ribu insert/detik plus 200 query dashboard bersamaan. Biaya per event tersimpan adalah $0,0000042 — beberapa kali lipat lebih murah daripada analitik sebanding pada basis data cloud terkelola.