ClickHouse: Cỗ máy phân tích real-time xử lý hàng tỷ rows trong mili-giây
Posted on: 4/21/2026 6:08:32 AM
Table of contents
- ClickHouse là gì và tại sao nó "nhanh đến vô lý"?
- Kiến trúc bên trong: MergeTree và những bí mật tốc độ
- Những cập nhật đáng chú ý 2025–2026
- ClickHouse vs. các giải pháp analytics khác
- Kiến trúc tích hợp: ClickHouse trong hệ thống thực tế
- Tối ưu hiệu năng: 7 nguyên tắc vàng
- ClickHouse Cloud và ClickPipes: Analytics không cần ops
- Tự host ClickHouse: từ single node đến cluster
- Benchmark thực tế: ClickHouse trong production
- Kết luận: ClickHouse — không chỉ là database, mà là analytics platform
Khi hệ thống của bạn sinh ra hàng triệu event mỗi giây — từ click tracking, IoT sensor, transaction log cho đến observability data — câu hỏi không còn là "lưu ở đâu?" mà là "làm sao query được trong vài mili-giây?". ClickHouse chính là câu trả lời mà hàng nghìn công ty từ Cloudflare, Uber, eBay cho đến Spotify đã chọn.
ClickHouse là gì và tại sao nó "nhanh đến vô lý"?
ClickHouse là column-oriented OLAP database (Online Analytical Processing) mã nguồn mở, được Yandex phát triển từ năm 2016. Khác với PostgreSQL hay MySQL (row-oriented — đọc toàn bộ row khi query), ClickHouse lưu trữ dữ liệu theo từng cột, cho phép chỉ đọc đúng những cột cần thiết cho mỗi truy vấn.
graph LR
subgraph Row-Oriented["Row-Oriented (PostgreSQL)"]
R1["Row 1: id | name | city | amount"]
R2["Row 2: id | name | city | amount"]
R3["Row 3: id | name | city | amount"]
end
subgraph Column-Oriented["Column-Oriented (ClickHouse)"]
C1["Column: id → 1, 2, 3, ..."]
C2["Column: name → An, Bình, ..."]
C3["Column: city → HCM, HN, ..."]
C4["Column: amount → 100, 200, ..."]
end
Q["SELECT SUM(amount)
WHERE city = 'HCM'"] --> Column-Oriented
style Q fill:#e94560,stroke:#fff,color:#fff
style R1 fill:#f8f9fa,stroke:#e0e0e0,color:#2c3e50
style R2 fill:#f8f9fa,stroke:#e0e0e0,color:#2c3e50
style R3 fill:#f8f9fa,stroke:#e0e0e0,color:#2c3e50
style C1 fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style C2 fill:#f8f9fa,stroke:#e0e0e0,color:#aaa
style C3 fill:#e94560,stroke:#fff,color:#fff
style C4 fill:#e94560,stroke:#fff,color:#fff
Column-oriented chỉ đọc 2 cột (city + amount) thay vì toàn bộ row — giảm I/O đáng kể
💡 Tại sao column-oriented nhanh hơn cho analytics?
Giả sử bảng có 100 cột, query chỉ cần 3 cột → ClickHouse chỉ đọc 3% dữ liệu từ disk. Thêm vào đó, dữ liệu cùng cột có kiểu giống nhau nên nén cực kỳ hiệu quả (thường đạt tỷ lệ nén 10:1 đến 40:1), giảm I/O thêm một lần nữa.
Kiến trúc bên trong: MergeTree và những bí mật tốc độ
Trái tim của ClickHouse là MergeTree engine family — cơ chế lưu trữ được thiết kế đặc biệt cho workload analytics với write-heavy pattern.
graph TD
A["Client INSERT
batch rows"] --> B["In-memory Buffer"]
B --> C["Write Part
(sorted, compressed)"]
C --> D["Background Merge"]
D --> E["Merged Parts
(optimized, deduped)"]
E --> F["Query Engine
vectorized execution"]
G["Primary Index
(sparse, in-memory)"] --> F
H["Data Skipping Index
(minmax, set, bloom)"] --> F
style A fill:#e94560,stroke:#fff,color:#fff
style B fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style C fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style D fill:#2c3e50,stroke:#fff,color:#fff
style E fill:#16213e,stroke:#fff,color:#fff
style F fill:#e94560,stroke:#fff,color:#fff
style G fill:#f8f9fa,stroke:#4CAF50,color:#2c3e50
style H fill:#f8f9fa,stroke:#4CAF50,color:#2c3e50
Kiến trúc MergeTree: INSERT → buffer → sorted parts → background merge → query
Sparse Primary Index — ít nhưng đủ
Khác với B-Tree index của PostgreSQL (index mỗi row), ClickHouse dùng sparse index — chỉ lưu giá trị đầu tiên của mỗi granule (mặc định 8192 rows). Với bảng 1 tỷ rows, primary index chỉ chiếm ~120K entries — vừa đủ nằm trong RAM, scan cực nhanh.
Vectorized Query Execution
ClickHouse xử lý dữ liệu theo block (batch of column values), tận dụng tối đa SIMD instructions (Single Instruction Multiple Data) của CPU hiện đại. Một phép so sánh WHERE amount > 1000 có thể xử lý 8-16 giá trị cùng lúc trên một CPU cycle thay vì từng giá trị một.
🔧 Các Engine quan trọng trong MergeTree family
| Engine | Mô tả | Use case |
|---|---|---|
| MergeTree | Engine cơ bản, sorted storage + merge | General analytics |
| ReplacingMergeTree | Tự động deduplicate theo sort key | CDC, upsert pattern |
| AggregatingMergeTree | Pre-aggregate khi merge | Materialized views, rollup |
| SummingMergeTree | Tự động SUM các cột numeric | Counter, metrics |
| CollapsingMergeTree | Collapse rows theo sign column | State tracking, mutable data |
Những cập nhật đáng chú ý 2025–2026
ClickHouse không ngừng cải tiến. Dưới đây là những thay đổi lớn nhất trong năm qua mà bạn cần biết.
naturalSortKey, codec nén ALP cho floating-point data, và asynchronous inserts mặc định bật.
ClickHouse vs. các giải pháp analytics khác
Không có "silver bullet" cho mọi bài toán analytics. Dưới đây là so sánh ClickHouse với một số lựa chọn phổ biến dựa trên các tiêu chí thực tế.
| Tiêu chí | ClickHouse | Apache Druid | TimescaleDB | BigQuery |
|---|---|---|---|---|
| Kiểu dữ liệu | Column-oriented | Column-oriented | Row-oriented (PG ext.) | Column-oriented |
| Ingest speed | Hàng triệu rows/s | Cao (qua Kafka) | Trung bình | Streaming (hạn chế) |
| Query latency | Sub-second trên tỷ rows | Sub-second | Giây → phút | Giây (cold start) |
| SQL support | Gần đầy đủ ANSI SQL | SQL-like (hạn chế JOIN) | Full PostgreSQL SQL | Full SQL |
| JOINs | Tốt (cải thiện liên tục) | Hạn chế | Tốt | Tốt |
| Self-hosted | ✅ Miễn phí | ✅ Phức tạp hơn | ✅ (PG extension) | ❌ GCP only |
| Managed cloud | ✅ ClickHouse Cloud | ✅ Imply Cloud | ✅ Timescale Cloud | ✅ Native |
| Tốt nhất cho | Log analytics, BI, observability | Real-time dashboards | Time-series IoT | Ad-hoc analytics lớn |
✅ Khi nào chọn ClickHouse?
Chọn ClickHouse khi bạn cần: (1) Query analytics trên dữ liệu lớn với latency thấp, (2) Ingest volume cao (millions events/second), (3) SQL chuẩn và hệ sinh thái connector phong phú, (4) Khả năng self-host miễn phí hoặc managed cloud linh hoạt. Đặc biệt phù hợp cho log analytics, observability, product analytics, và real-time reporting.
⚠️ Khi nào KHÔNG nên dùng ClickHouse?
ClickHouse không phải OLTP database. Nếu workload của bạn chủ yếu là single-row INSERT/UPDATE/DELETE với transaction ACID (ví dụ: e-commerce order processing), hãy giữ PostgreSQL/.NET EF Core cho phần đó và dùng ClickHouse như analytics layer phía sau.
Kiến trúc tích hợp: ClickHouse trong hệ thống thực tế
Trong thực tế, ClickHouse thường không đứng một mình mà là một phần trong kiến trúc data pipeline lớn hơn. Dưới đây là pattern phổ biến nhất.
graph LR
A["Application
(.NET / Vue.js)"] -->|events| B["Message Queue
(Kafka / RabbitMQ)"]
B --> C["ClickHouse
Ingest"]
C --> D["ClickHouse
MergeTree Tables"]
D --> E["Materialized Views
(pre-aggregated)"]
E --> F["Grafana / BI Tools
Dashboard"]
D --> G["API Layer
(.NET Core)"]
G --> H["Vue.js
Frontend"]
I["PostgreSQL
OLTP"] -->|CDC via ClickPipes| D
style A fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style B fill:#f8f9fa,stroke:#e0e0e0,color:#2c3e50
style C fill:#e94560,stroke:#fff,color:#fff
style D fill:#16213e,stroke:#fff,color:#fff
style E fill:#2c3e50,stroke:#fff,color:#fff
style F fill:#f8f9fa,stroke:#4CAF50,color:#2c3e50
style G fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style H fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style I fill:#f8f9fa,stroke:#e0e0e0,color:#2c3e50
Pattern phổ biến: OLTP (PostgreSQL) → CDC → ClickHouse → Materialized Views → Dashboard/API
Pattern 1: Event Analytics Pipeline
Application gửi event (page view, click, purchase...) qua message queue. ClickHouse ingest trực tiếp từ Kafka thông qua Kafka engine hoặc ClickPipes (managed connector).
-- Tạo bảng lưu raw events
CREATE TABLE events (
event_id UUID DEFAULT generateUUIDv4(),
event_type LowCardinality(String),
user_id UInt64,
session_id String,
page_url String,
properties String, -- JSON string
created_at DateTime64(3) DEFAULT now64(3)
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(created_at)
ORDER BY (event_type, user_id, created_at)
TTL created_at + INTERVAL 90 DAY;
-- Materialized View tự động aggregate
CREATE MATERIALIZED VIEW events_hourly_mv
ENGINE = SummingMergeTree()
PARTITION BY toYYYYMM(hour)
ORDER BY (event_type, hour)
AS SELECT
event_type,
toStartOfHour(created_at) AS hour,
count() AS event_count,
uniqExact(user_id) AS unique_users
FROM events
GROUP BY event_type, hour;
✅ Tip: LowCardinality — vũ khí bí mật
LowCardinality(String) là optimization đặc trưng của ClickHouse. Với các cột có ít giá trị distinct (country, event_type, status...), nó áp dụng dictionary encoding tự động — giảm memory và tăng tốc filter lên đến 10x.
Pattern 2: CDC từ PostgreSQL
Với ClickPipes (hoặc Debezium + Kafka), bạn có thể replicate data từ PostgreSQL sang ClickHouse gần real-time. ClickHouse 2025 đã thêm MySQL CDC, MongoDB CDC, và cải thiện Postgres CDC trong ClickPipes.
-- ReplacingMergeTree cho CDC (upsert pattern)
CREATE TABLE orders_replica (
order_id UInt64,
customer_id UInt64,
total_amount Decimal(18,2),
status LowCardinality(String),
updated_at DateTime64(3),
_version UInt64 -- CDC version for dedup
) ENGINE = ReplacingMergeTree(_version)
ORDER BY order_id;
-- Query với FINAL để đảm bảo deduplication
SELECT
status,
count() AS order_count,
sum(total_amount) AS revenue
FROM orders_replica FINAL
WHERE updated_at >= today() - 30
GROUP BY status;
Pattern 3: Kết nối từ .NET Core
ClickHouse cung cấp official .NET client (ClickHouse.Client) hỗ trợ ADO.NET interface quen thuộc, bulk insert, và async operations.
// NuGet: ClickHouse.Client
using ClickHouse.Client.ADO;
using ClickHouse.Client.Copy;
// Query đơn giản qua ADO.NET
await using var connection = new ClickHouseConnection(
"Host=localhost;Port=8123;Database=analytics");
await connection.OpenAsync();
await using var cmd = connection.CreateCommand();
cmd.CommandText = @"
SELECT event_type, count() AS cnt, uniqExact(user_id) AS users
FROM events
WHERE created_at >= @from
GROUP BY event_type
ORDER BY cnt DESC
LIMIT 20";
cmd.Parameters.AddWithValue("@from", DateTime.UtcNow.AddDays(-7));
await using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
Console.WriteLine($"{reader["event_type"]}: {reader["cnt"]} events, {reader["users"]} users");
}
// Bulk insert hiệu năng cao
using var bulkCopy = new ClickHouseBulkCopy(connection)
{
DestinationTableName = "events",
BatchSize = 100_000
};
var rows = GenerateEvents(); // IEnumerable<object[]>
await bulkCopy.InitAsync();
await bulkCopy.WriteToServerAsync(rows);
Tối ưu hiệu năng: 7 nguyên tắc vàng
ClickHouse nhanh by default, nhưng để khai thác tối đa, bạn cần tuân thủ một số nguyên tắc thiết kế.
📐 7 nguyên tắc tối ưu ClickHouse
1. Chọn ORDER BY đúng: Primary key quyết định thứ tự lưu trữ vật lý. Đặt cột filter thường xuyên nhất lên trước (ví dụ: ORDER BY (tenant_id, event_type, created_at)).
2. Dùng PARTITION BY hợp lý: Thường partition theo tháng (toYYYYMM). Quá nhiều partition (theo ngày trên bảng nhỏ) gây overhead. Rule of thumb: mỗi partition nên có ít nhất 1-10 triệu rows.
3. Batch INSERT: Không bao giờ insert từng row một. Gom batch tối thiểu 1000 rows, lý tưởng là 10K-100K rows mỗi lần. Từ v26.3, asynchronous inserts bật mặc định giúp tự động buffer.
4. LowCardinality cho cột ít distinct values: Country, status, event_type... bất kỳ cột nào có <10K giá trị distinct đều nên dùng LowCardinality(String).
5. Materialized Views cho queries lặp: Thay vì scan toàn bộ bảng raw mỗi lần, tạo materialized view pre-aggregate. Truy vấn trên view nhanh hơn 10-1000x.
6. TTL để quản lý lifecycle: Set TTL tự động xoá hoặc move data cũ sang storage rẻ hơn: TTL created_at + INTERVAL 90 DAY DELETE hoặc TTL created_at + INTERVAL 30 DAY TO VOLUME 'cold'.
7. Tránh SELECT *: Luôn chỉ định cụ thể cột cần lấy. Column-oriented = chỉ đọc cột được chọn, nhưng SELECT * bắt ClickHouse đọc toàn bộ.
ClickHouse Cloud và ClickPipes: Analytics không cần ops
Nếu không muốn tự quản lý cluster, ClickHouse Cloud cung cấp managed service với nhiều tính năng enterprise:
ClickPipes là managed data ingestion — kết nối trực tiếp với Kafka, PostgreSQL (CDC), MySQL (CDC), MongoDB (CDC), Amazon Kinesis, S3, GCS, Azure Blob Storage... mà không cần viết code ETL.
graph LR
A["PostgreSQL
(CDC)"] --> CP["ClickPipes"]
B["Apache Kafka"] --> CP
C["Amazon S3"] --> CP
D["MongoDB
(CDC)"] --> CP
CP --> CH["ClickHouse Cloud"]
CH --> G["Grafana"]
CH --> S["Superset"]
CH --> API["Your .NET API"]
CH --> MB["Metabase"]
style CP fill:#e94560,stroke:#fff,color:#fff
style CH fill:#16213e,stroke:#fff,color:#fff
style A fill:#f8f9fa,stroke:#e0e0e0,color:#2c3e50
style B fill:#f8f9fa,stroke:#e0e0e0,color:#2c3e50
style C fill:#f8f9fa,stroke:#e0e0e0,color:#2c3e50
style D fill:#f8f9fa,stroke:#e0e0e0,color:#2c3e50
style G fill:#f8f9fa,stroke:#4CAF50,color:#2c3e50
style S fill:#f8f9fa,stroke:#4CAF50,color:#2c3e50
style API fill:#f8f9fa,stroke:#4CAF50,color:#2c3e50
style MB fill:#f8f9fa,stroke:#4CAF50,color:#2c3e50
ClickPipes: Managed ingestion từ nhiều nguồn vào ClickHouse Cloud
Tính năng AI và MCP Server
Điểm đáng chú ý là ClickHouse đã tích hợp MCP Server (Model Context Protocol) cho phép AI agents truy vấn trực tiếp vào ClickHouse. Cùng với việc mua lại Langfuse, ClickHouse đang trở thành nền tảng hạ tầng cho cả AI observability — theo dõi LLM tokens, latency, cost, và quality metrics ở quy mô lớn.
-- Ví dụ: bảng LLM observability trên ClickHouse
CREATE TABLE llm_traces (
trace_id UUID,
model LowCardinality(String),
prompt_tokens UInt32,
completion_tokens UInt32,
latency_ms UInt32,
cost_usd Decimal(10,6),
status LowCardinality(String),
created_at DateTime64(3)
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(created_at)
ORDER BY (model, created_at);
-- Dashboard query: chi phí LLM theo model trong 7 ngày
SELECT
model,
count() AS requests,
avg(latency_ms) AS avg_latency,
sum(cost_usd) AS total_cost,
sum(prompt_tokens + completion_tokens) AS total_tokens
FROM llm_traces
WHERE created_at >= now() - INTERVAL 7 DAY
GROUP BY model
ORDER BY total_cost DESC;
Tự host ClickHouse: từ single node đến cluster
ClickHouse hoàn toàn miễn phí để self-host. Dưới đây là cách triển khai nhanh nhất với Docker.
# docker-compose.yml — Single node ClickHouse
version: '3.8'
services:
clickhouse:
image: clickhouse/clickhouse-server:26.3
ports:
- "8123:8123" # HTTP interface
- "9000:9000" # Native TCP
- "9009:9009" # Inter-server replication
volumes:
- ch_data:/var/lib/clickhouse
- ch_logs:/var/log/clickhouse-server
environment:
CLICKHOUSE_DB: analytics
CLICKHOUSE_USER: admin
CLICKHOUSE_PASSWORD: your_secure_password
ulimits:
nofile:
soft: 262144
hard: 262144
deploy:
resources:
limits:
memory: 4G
volumes:
ch_data:
ch_logs:
💡 Sizing guide cho single node
RAM: ClickHouse dùng ~50% RAM cho query processing. 8GB RAM xử lý tốt vài trăm triệu rows. Disk: Với tỷ lệ nén 10:1, 100GB raw data chỉ chiếm ~10GB trên disk. Ưu tiên SSD/NVMe — ClickHouse tận dụng random read cực tốt. CPU: Càng nhiều core càng tốt — ClickHouse parallelize query trên tất cả core.
clickhousectl — CLI mới (beta, v26.3)
ClickHouse vừa release clickhousectl — CLI tool chính thức hỗ trợ cả local installation lẫn cloud deployment. Đặc biệt, nó được thiết kế "built with AI agents in mind" — hỗ trợ OAuth, permissioned API keys, và output format thân thiện với agentic workflows.
# Cài đặt clickhousectl
curl -fsSL https://clickhouse.com/install-ctl | bash
# Quản lý local instance
clickhousectl install --version 26.3
clickhousectl start
clickhousectl status
# Kết nối cloud
clickhousectl cloud login
clickhousectl cloud query "SELECT count() FROM events"
Benchmark thực tế: ClickHouse trong production
Một số case study nổi bật từ production:
| Công ty | Use case | Scale | Kết quả |
|---|---|---|---|
| Cloudflare | DNS analytics, HTTP logs | Hàng chục PB | Sub-second query trên petabytes |
| Uber | Real-time pricing, logging | Hàng tỷ events/ngày | Latency P99 < 1s |
| Goldsky | Blockchain data backfill | Billions of rows | 12x throughput improvement |
| GitLab | Product analytics | Hàng trăm TB | Giảm 90% query cost vs BigQuery |
| Spotify | A/B testing analytics | Trillions of rows | Interactive queries trên experiment data |
Kết luận: ClickHouse — không chỉ là database, mà là analytics platform
Với việc huy động $400M Series D, mua lại Langfuse, và liên tục cải thiện qua các phiên bản 26.x, ClickHouse đang chuyển mình từ một column-oriented database thành một analytics platform toàn diện — từ ingestion (ClickPipes), storage (MergeTree + Data Lake), query (vectorized + materialized views), cho đến AI infrastructure (MCP Server + LLM observability).
Nếu hệ thống của bạn đang gặp bottleneck ở analytics layer — dashboard chậm, query timeout trên bảng lớn, hoặc chi phí BigQuery/Redshift quá cao — ClickHouse là lựa chọn đáng thử nhất trong năm 2026. Với khả năng self-host miễn phí và managed cloud linh hoạt, barrier to entry gần như bằng 0.
✅ Bắt đầu với ClickHouse
Thử ngay tại play.clickhouse.com — playground miễn phí không cần đăng ký. Hoặc dùng Docker compose ở trên để dựng local instance trong 2 phút. Official docs tại clickhouse.com/docs có tutorial step-by-step cho mọi use case phổ biến.
Nguồn tham khảo
Saga Pattern: Quản lý Distributed Transactions trong Microservices
Vue 3.6 Vapor Mode — Loại bỏ Virtual DOM, hiệu năng ngang Solid.js
Disclaimer: The opinions expressed in this blog are solely my own and do not reflect the views or opinions of my employer or any affiliated organizations. The content provided is for informational and educational purposes only and should not be taken as professional advice. While I strive to provide accurate and up-to-date information, I make no warranties or guarantees about the completeness, reliability, or accuracy of the content. Readers are encouraged to verify the information and seek independent advice as needed. I disclaim any liability for decisions or actions taken based on the content of this blog.