Membangun analitik yang menjawab dalam detik: perbedaan OLAP real-time dari warehouse konvensional, ClickHouse sebagai database analitik kolumnar, streaming analytics, dan praktik membangun dashboard real-time dari stream event

Warehouse yang kalian bangun di episode 9 menjawab pertanyaan "berapa penjualan bulan ini?" dengan baik — dalam hitungan detik. Tapi bagaimana dengan pertanyaan seperti "berapa pengguna online sekarang?" atau "berapa transaksi di 5 menit terakhir?" Warehouse konvensional tidak dirancang untuk ini: latency refresh-nya menit hingga jam. Inilah domain real-time analytics.
Episode 23 memperkenalkan kelas database yang berbeda: OLAP real-time — ClickHouse dan Druid. Kalian akan memahami mengapa ia bisa secepat itu, kapan memakainya (dan kapan tidak), serta membangun dashboard real-time dari stream event.
Konteksnya penting: warehouse modern (Snowflake/BigQuery) sebenarnya sangat cepat untuk query — yang lambat adalah pembaruan data dan latency end-to-end. Alur klasiknya: event → Kafka → pipeline batch → warehouse → dashboard = menit hingga jam. Untuk analitik real-time, alurnya harus: event → pipeline streaming langsung ke DB analitik → dashboard = detik.
| Aspek | Warehouse (OLAP batch) | Real-time OLAP (ClickHouse/Druid) |
|---|---|---|
| Latency data | Menit-jam (refresh berkala) | Detik (insert langsung) |
| Beban tulis | Batch, jarang | Continuous, tinggi |
| Query pola | Agregasi kompleks, besar | Agregasi rolling, banyak user |
| Contoh | BigQuery, Snowflake | ClickHouse, Druid, Pinot |
Keduanya kolumnar dan SQL — bedanya di kecepatan ingesti dan target latency.
ClickHouse adalah database kolumnar open-source yang dirancang untuk agregasi super cepat pada data besar. Kecepatannya lahir dari kombinasi:
Menjalankan ClickHouse dan membuat tabel untuk streaming:
docker run -d --name clickhouse -p 8123:8123 -p 9000:9000 clickhouse/clickhouse-server:24.8CREATE TABLE analytics.events (
event_time DateTime,
event_type String,
user_id UInt64,
country String,
amount Float64
) ENGINE = MergeTree()
PARTITION BY toYYYYMMDD(event_time)
ORDER BY (event_time, event_type);Dua kunci performa terlihat di sini:
PARTITION BY toYYYYMMDD(event_time) — query per hari hanya menyentuh partisi itu.ORDER BY (event_time, event_type) — menentukan urutan penyimpanan (sekaligus primary index) yang mempercepat filter pada kedua kolom.Cara paling umum mengalirkan data ke ClickHouse adalah Kafka Engine Table — tabel ClickHouse yang langsung membaca dari Kafka:
-- 1. Tabel Kafka: jembatan ke topic events
CREATE TABLE kafka.events_kafka (
event_time DateTime,
event_type String,
user_id UInt64,
country String,
amount Float64
) ENGINE = Kafka
SETTINGS
kafka_broker_list = 'kafka:9092',
kafka_topic_list = 'events',
kafka_group_name = 'clickhouse_analytics',
kafka_format = 'JSONEachRow';
-- 2. Materialized view: salin otomatis dari Kafka ke tabel analitik
CREATE MATERIALIZED VIEW analytics.events_mv
TO analytics.events AS
SELECT * FROM kafka.events_kafka;Setiap event di topic Kafka events kini muncul di tabel analitik dalam hitungan detik, tanpa satu baris kode Python pun. Ini pola klasik 2026: Kafka sebagai transport, ClickHouse sebagai serving.
Tip
Gunakan engine Kafka + materialized view untuk MVP real-time. Untuk kebutuhan yang lebih kompleks (transformasi, deduplikasi), gunakan pipeline streaming (Flink/Spark Streaming) yang menulis ke ClickHouse — seperti pola di episode 11.
Kekuatan ClickHouse terlihat pada agregasi rolling yang berat — yang di warehouse bisa membuat database menangis:
SELECT
toStartOfTenSeconds(event_time) AS bucket,
country,
COUNT(*) AS events,
SUM(amount) AS revenue
FROM analytics.events
WHERE event_time >= now() - INTERVAL 15 MINUTE
GROUP BY bucket, country
ORDER BY bucket DESC
LIMIT 10;Coba jalankan pada puluhan juta baris — hasilnya kembali dalam milidetik. Inilah perbedaan kelasnya: bukan "lebih cepat dari BigQuery", melainkan dirancang untuk beban ini.
Real-time analytics bukan jawaban untuk semua masalah. Framework keputusannya:
Pakai ClickHouse/Druid ketika:
Tetap di warehouse ketika:
Pola hybrid paling umum: event stream → ClickHouse untuk metrik real-time, sementara warehouse tetap menjadi sumber kebenaran untuk analisis historis. Keduanya hidup berdampingan.
Rangkai pipeline real-time lengkap:
import clickhouse_connect
client = clickhouse_connect.get_client(host="localhost", port=8123)
def recent_events(minutes: int = 15) -> list:
result = client.query("""
SELECT
toStartOfMinute(event_time) AS minute,
country,
COUNT(*) AS events,
SUM(amount) AS revenue
FROM analytics.events
WHERE event_time >= now() - INTERVAL {m} MINUTE
GROUP BY minute, country
ORDER BY minute DESC
""", parameters={"m": minutes})
return result.result_rows
# Dashboard polling tiap 5 detik
while True:
print(recent_events(15))
time.sleep(5)Dashboard yang mem-pooling query ini akan selalu menunjukkan metrik terbaru dalam beberapa detik — pengalaman "live" yang tidak mungkin diulang warehouse batch.
Real-time untuk segalanya. Menambah ClickHouse di samping warehouse = biaya infra ganda. Ukur kebutuhan latency dulu.
Mengabaikan retention. ClickHouse menyimpan semuanya tanpa lifecycle = disk penuh. Set TTL untuk event bergulir:
ALTER TABLE analytics.events
MODIFY TTL event_time + INTERVAL 90 DAY;Query tanpa memanfaatkan ordering. Filter pada kolom yang tidak ada di ORDER BY = full scan. Desain ORDER BY berdasarkan pola filter dominan.
Dashboard polling terlalu sering. Query tiap 1 detik dari 50 dashboard = beban tak perlu. Agregasikan di backend dan cache.
Di episode 23 ini kalian telah masuk ke analitik real-time:
Di episode 24 selanjutnya kita membahas pola organisasi: data mesh & data product — domain ownership, data as a product, self-serve platform, dan praktik mendesain data product contract. Sampai jumpa di episode 24!