Trong series: DevOps
  1. 1 Nginx là gì? Web server, reverse proxy và load balancer trong một
  2. 2 Proxy là gì? Forward Proxy, Reverse Proxy và SOCKS5
  3. 3 Kubernetes là gì? Nền tảng điều phối container phổ biến nhất hiện nay
  4. 4 Subnet và CIDR là gì? Chia mạng IP và định tuyến hiện đại
  5. 5 Serverless là gì? FaaS, Cold Start và khi nào nên dùng Serverless
  6. 6 Kafka là gì? Nền tảng Event Streaming phân tán cho hệ thống lớn
  7. 7 GitLab CI/CD là gì? Pipeline tự động hóa build, test và deploy
  8. 8 NAT là gì? Network Address Translation trong mạng máy tính
  9. 9 API Gateway là gì? Cổng vào thống nhất cho Microservices
✦ Tóm tắt nhanh
Apache Kafka là nền tảng event streaming phân tán do LinkedIn tạo ra, giải quyết bài toán decoupling producer/consumer và replay event ở quy mô hàng triệu message/giây. Tìm hiểu kiến trúc Topic, Parti...
Bài này thế nào?

Apache Kafka là nền tảng distributed event streaming được LinkedIn sáng tạo năm 2011 và sau đó mã nguồn mở qua Apache Software Foundation. Từ một công cụ nội bộ xử lý hàng tỷ event mỗi ngày của LinkedIn, Kafka đã trở thành xương sống của kiến trúc data pipeline tại Uber, Airbnb, Netflix và hàng nghìn công ty trên thế giới.

Kafka là gì?

Apache Kafka là hệ thống distributed event streaming — một log phân tán bất biến (distributed immutable log) cho phép:

  • Publish (ghi) message từ nhiều Producer
  • Subscribe (đọc) message bởi nhiều Consumer độc lập
  • Store message lâu dài với retention policy linh hoạt
  • Process message theo thời gian thực hoặc replay lịch sử

Kafka được thiết kế cho throughput cực cao: một cluster Kafka điển hình xử lý hàng triệu message mỗi giây với độ trễ end-to-end dưới 10ms.

Điểm khác biệt cốt lõi: Không giống message queue truyền thống (xóa message sau khi đọc), Kafka giữ lại message trong một khoảng thời gian cấu hình (ví dụ: 7 ngày). Consumer có thể đọc lại (replay) toàn bộ lịch sử event bất kỳ lúc nào.

Vấn đề Kafka giải quyết

Hãy tưởng tượng hệ thống e-commerce: khi user đặt hàng, sự kiện đó cần được xử lý bởi:

  • Inventory service — trừ kho
  • Notification service — gửi email xác nhận
  • Analytics service — cập nhật dashboard
  • Fraud detection service — kiểm tra gian lận
  • Recommendation engine — cập nhật history

Nếu Order service gọi trực tiếp 5 service này:

Order Service → Inventory (HTTP)
             → Notification (HTTP)
             → Analytics (HTTP)
             → Fraud (HTTP)
             → Recommendation (HTTP)

Hệ thống trở nên tightly coupled: thêm service mới phải sửa Order service, một service chậm làm chậm cả pipeline, không có cơ chế retry khi downstream fail.

Kafka giải quyết bằng cách tạo ra một event bus trung gian:

Order Service → [order-placed Topic] → Inventory Service
                                     → Notification Service
                                     → Analytics Service
                                     → Fraud Service
                                     → Recommendation Service

Order service chỉ cần publish một event. Mỗi downstream service subscribe và xử lý theo tốc độ riêng, hoàn toàn độc lập. Thêm service mới không cần chạm vào Order service.

Kiến trúc Kafka

Kiến trúc Kafka gồm các thành phần chính:

Producer

Producer là bất kỳ ứng dụng nào ghi message vào Kafka. Producer chọn Topic để ghi và optionally chỉ định Partition key để kiểm soát message routing.

Topic và Partition

Topic là danh mục logic để nhóm message (ví dụ: order-placed, user-signup, payment-processed).

Mỗi Topic được chia thành N Partition — đây là đơn vị song song hóa:

  • Mỗi Partition là ordered, immutable log: message được append vào cuối, không bao giờ sửa.
  • Message trong cùng Partition được đảm bảo thứ tự (ordering guarantee).
  • Message có cùng Partition key luôn đi vào cùng Partition — đảm bảo ordering cho một entity cụ thể (ví dụ: mọi event của user_id=123 vào cùng Partition).
  • Tăng số Partition → tăng parallelism → tăng throughput.

Broker

Broker là Kafka server — node lưu trữ và phục vụ Partition. Một Kafka cluster thường có 3–5 Broker. Mỗi Partition có một Leader Broker (nhận đọc/ghi) và nhiều Follower (replica để HA).

ZooKeeper (hoặc KRaft từ Kafka 3.3+) quản lý cluster metadata và leader election.

Consumer và Consumer Group

Consumer là ứng dụng đọc message từ Topic.

Consumer Group là nhóm Consumer cùng nhau consume một Topic:

  • Kafka phân phối Partition cho Consumer trong Group: mỗi Partition → đúng một Consumer.
  • Số Consumer trong Group ≤ số Partition mới có hiệu quả (Consumer dư sẽ idle).
  • Nhiều Consumer Group khác nhau đọc cùng Topic hoàn toàn độc lập — mỗi Group có offset riêng.
Topic: order-placed (3 Partitions)
│
├─ Consumer Group "inventory-svc"   → Consumer A (P0), Consumer B (P1, P2)
└─ Consumer Group "analytics-svc"  → Consumer X (P0, P1, P2)

Retention, Offset và Consumer Lag

Offset

Mỗi message trong Partition có một offset — số nguyên tăng dần (0, 1, 2, …) xác định vị trí của message. Consumer tự quản lý offset: sau khi xử lý message, Consumer commit offset để báo với Kafka rằng "tôi đã xử lý đến đây".

Offset không được quản lý bởi Kafka server mà lưu trong internal topic __consumer_offsets.

Retention

Kafka giữ message trong một khoảng thời gian/kích thước cấu hình:

properties
# Giữ message 7 ngày
log.retention.hours=168

# Hoặc giới hạn kích thước
log.retention.bytes=10737418240  # 10 GB per Partition

Sau retention period, Kafka xóa message cũ nhất — bất kể Consumer có đọc chưa. Đây là pull model: Consumer tự quyết định đọc nhanh hay chậm.

Consumer Lag

Consumer Lag = Latest Offset − Committed Offset = số message Consumer đang "nợ" chưa xử lý.

Lag cao là dấu hiệu Consumer đang không theo kịp tốc độ Producer. Monitoring lag là một trong những metric quan trọng nhất trong Kafka production.

Code thực tế

Python với kafka-python

Python
 1from kafka import KafkaProducer, KafkaConsumer
 2import json
 3
 4# Producer: ghi message vào Topic
 5producer = KafkaProducer(
 6    bootstrap_servers=['localhost:9092'],
 7    value_serializer=lambda v: json.dumps(v).encode('utf-8'),
 8    # Đảm bảo không mất message: chờ tất cả in-sync replica xác nhận
 9    acks='all',
10    retries=3
11)
12
13# Gửi event đặt hàng
14order_event = {
15    "event": "order_placed",
16    "order_id": "ORD-2026-001",
17    "user_id": 42,
18    "total": 599000
19}
20
21# Key = user_id để đảm bảo event cùng user vào cùng Partition
22future = producer.send(
23    topic='order-placed',
24    key=str(order_event['user_id']).encode('utf-8'),
25    value=order_event
26)
27record_metadata = future.get(timeout=10)
28print(f"Đã gửi → partition={record_metadata.partition}, offset={record_metadata.offset}")
29
30producer.flush()
31producer.close()
32
33# Consumer Group: tiêu thụ message từ Topic
34consumer = KafkaConsumer(
35    'order-placed',
36    bootstrap_servers=['localhost:9092'],
37    group_id='inventory-service',  # Consumer Group ID
38    auto_offset_reset='earliest',  # Đọc từ đầu nếu chưa có offset
39    value_deserializer=lambda m: json.loads(m.decode('utf-8')),
40    enable_auto_commit=False  # Tắt auto commit để control manually
41)
42
43print("Inventory Service đang lắng nghe...")
44try:
45    for message in consumer:
46        event = message.value
47        print(f"Nhận: order_id={event['order_id']}, user={event['user_id']}")
48        
49        # Xử lý business logic ở đây (trừ kho, v.v.)
50        # ...
51        
52        # Commit offset sau khi xử lý thành công
53        consumer.commit()
54finally:
55    consumer.close()

Node.js với kafkajs

JavaScript
 1const { Kafka } = require('kafkajs');
 2
 3const kafka = new Kafka({
 4  clientId: 'my-app',
 5  brokers: ['localhost:9092'],
 6});
 7
 8// ── Producer ──────────────────────────────────────────────
 9async function runProducer() {
10  const producer = kafka.producer();
11  await producer.connect();
12
13  // Gửi batch message vào Topic
14  await producer.send({
15    topic: 'order-placed',
16    messages: [
17      {
18        key: '42',                               // Partition key = user_id
19        value: JSON.stringify({
20          event: 'order_placed',
21          orderId: 'ORD-2026-002',
22          userId: 42,
23          total: 899000,
24        }),
25      },
26      {
27        key: '99',
28        value: JSON.stringify({
29          event: 'order_placed',
30          orderId: 'ORD-2026-003',
31          userId: 99,
32          total: 149000,
33        }),
34      },
35    ],
36  });
37
38  console.log('Đã gửi 2 order event vào Kafka');
39  await producer.disconnect();
40}
41
42// ── Consumer Group ────────────────────────────────────────
43async function runConsumer() {
44  const consumer = kafka.consumer({ groupId: 'notification-service' });
45  await consumer.connect();
46
47  // Subscribe vào Topic
48  await consumer.subscribe({ topic: 'order-placed', fromBeginning: false });
49
50  await consumer.run({
51    // eachMessage được gọi cho từng message
52    eachMessage: async ({ topic, partition, message }) => {
53      const event = JSON.parse(message.value.toString());
54      console.log(`[P${partition}] orderId=${event.orderId}, userId=${event.userId}`);
55      
56      // Gửi email/push notification
57      // await notificationSvc.send(event);
58    },
59  });
60}
61
62runProducer().catch(console.error);
63runConsumer().catch(console.error);

Kafka vs RabbitMQ và Redis Pub/Sub

Tiêu chí Kafka RabbitMQ Redis Pub/Sub
Mô hình Distributed log Message broker (AMQP) In-memory pub/sub
Retention Giữ theo time/size config Xóa sau khi ACK Không persist
Replay Có (rewind offset) Không Không
Throughput Cực cao (triệu msg/s) Cao (trăm nghìn msg/s) Rất cao nhưng ephemeral
Ordering Trong Partition Trong Queue Không đảm bảo
Consumer Group Có, mạnh Competing consumers Tất cả nhận
Routing Đơn giản (key-based) Phức tạp (Exchange/Binding) Channel-based
Complexity Cao Trung bình Thấp

Khi nào dùng Kafka?

Kafka là lựa chọn đúng khi:

  • Event streaming với throughput cao: hàng triệu event/giây từ nhiều nguồn
  • Cần replay: audit log, reprocessing khi có bug, backfill data warehouse
  • Nhiều Consumer độc lập cùng consume một stream (fan-out không mất event)
  • Data pipeline: CDC (Change Data Capture) từ database, ETL real-time
  • Event sourcing: lưu toàn bộ lịch sử thay đổi trạng thái

Khi nào KHÔNG dùng Kafka?

  • Cần routing phức tạp (topic exchange, fanout exchange) → RabbitMQ
  • Task queue đơn giản, fire-and-forget → Redis List / BullMQ
  • Hệ thống nhỏ, team chưa có Kafka ops experience → overhead không xứng
  • Cần request-reply (RPC pattern) → RabbitMQ phù hợp hơn

Redis là gì? Cache, Pub/Sub và hàng đợi với in-memory database

Kafka Connect và Kafka Streams

Kafka Connect

Kafka Connect là framework tích hợp sẵn trong Kafka để kết nối với hệ thống bên ngoài không cần viết code:

  • Source Connector: MySQL Debezium (CDC), S3, MongoDB → Kafka
  • Sink Connector: Kafka → Elasticsearch, Snowflake, PostgreSQL, S3

Elasticsearch là gì? Full-text search và phân tích log theo thời gian thực

JSON
 1// Ví dụ: Debezium MySQL Source Connector config
 2{
 3  "name": "mysql-orders-connector",
 4  "config": {
 5    "connector.class": "io.debezium.connector.mysql.MySqlConnector",
 6    "database.hostname": "mysql-host",
 7    "database.port": "3306",
 8    "database.user": "debezium",
 9    "database.password": "secret",
10    "database.server.name": "mydb",
11    "table.include.list": "shop.orders"
12  }
13}

Kafka Streams

Kafka Streams là thư viện Java/Scala để xây dựng stateful stream processing trực tiếp từ Kafka:

  • Filter, map, aggregate, join trên Kafka Topic
  • KTable — materialized view được cập nhật liên tục từ stream
  • Windowed aggregation — tổng hợp trong cửa sổ thời gian (5 phút, 1 giờ)
  • Không cần cluster riêng (khác Spark, Flink) — chạy như library trong ứng dụng

Kafka Streams là lựa chọn nhẹ nhàng cho stream processing; dùng Apache Flink khi cần xử lý phức tạp hơn với stateful computation ở quy mô lớn hơn.

Use cases thực tế: LinkedIn, Uber, Airbnb

LinkedIn — nơi Kafka ra đời

LinkedIn tạo ra Kafka năm 2011 để xử lý activity stream của hàng trăm triệu user. Trước Kafka, LinkedIn dùng nhiều message queue riêng lẻ gây ra "data integration mess" với hàng chục point-to-point connections. Kafka thay thế tất cả bằng một central nervous system duy nhất, xử lý hơn 7 nghìn tỷ message mỗi ngày.

Uber — pricing và surge detection

Uber dùng Kafka làm backbone cho real-time pricing engine. Mỗi chuyến xe, vị trí tài xế, và yêu cầu đặt xe là một event stream. Kafka giúp Uber tính surge pricing theo thời gian thực dựa trên supply/demand ở từng khu vực, xử lý hàng triệu event mỗi phút.

Airbnb — data pipeline và ML feature store

Airbnb dùng Kafka cho SmartPricing — hệ thống gợi ý giá cho host. Mọi tương tác người dùng (view, search, book) đều được stream qua Kafka vào data warehouse và ML feature store theo thời gian thực, giúp model cập nhật feature mà không cần batch job qua đêm.

API Gateway là gì? Kiến trúc, chức năng và cách triển khai

Câu hỏi thường gặpQ&A
Kafka là gì một cách ngắn gọn?
Apache Kafka là nền tảng distributed event streaming mã nguồn mở, cho phép publish và subscribe message theo dạng log bất biến (immutable log). Producer ghi message vào Topic, Consumer đọc từ Topic theo tốc độ riêng. Kafka được thiết kế để xử lý hàng triệu message/giây với độ trễ thấp và khả năng replay lịch sử event.
Topic và Partition trong Kafka là gì?
Topic là danh mục logic để phân loại message, tương tự như một channel. Mỗi Topic được chia thành nhiều Partition — đây là đơn vị song song hóa của Kafka. Mỗi Partition là một ordered, immutable log. Message trong cùng Partition được đảm bảo thứ tự; message giữa các Partition thì không. Số Partition quyết định mức độ parallelism tối đa khi consume.
Consumer Group trong Kafka là gì?
Consumer Group là nhóm các Consumer cùng nhau tiêu thụ một Topic. Kafka phân phối các Partition cho Consumer trong Group sao cho mỗi Partition chỉ được đọc bởi một Consumer tại một thời điểm (load balancing). Nhiều Group khác nhau có thể đọc cùng một Topic độc lập — đây là điểm mạnh của Kafka so với message queue truyền thống.
Kafka khác RabbitMQ như thế nào?
Kafka là distributed log: message được giữ lại (retain) theo cấu hình thời gian/kích thước và Consumer tự quản lý offset, hỗ trợ replay. RabbitMQ là message broker truyền thống: message bị xóa sau khi Consumer acknowledge, hỗ trợ routing phức tạp qua Exchange. Kafka phù hợp cho event streaming, audit log, data pipeline; RabbitMQ phù hợp cho task queue, RPC, routing linh hoạt.
Kafka có mất message không nếu một Broker bị crash?
Không, nếu cấu hình đúng. Kafka dùng replication: mỗi Partition có một Leader và nhiều Follower replica trên các Broker khác nhau. Khi Leader crash, một Follower được tự động elect làm Leader mới. Với replication factor ≥ 3 và acks=all (producer chờ tất cả in-sync replica xác nhận), Kafka đảm bảo không mất message khi số Broker fail < replication factor.
Kafka Connect là gì?
Kafka Connect là framework tích hợp dữ liệu có sẵn trong Kafka, dùng để kết nối Kafka với các hệ thống bên ngoài mà không cần viết code. Source Connector đọc dữ liệu từ database, S3, Elasticsearch,… và đẩy vào Kafka Topic. Sink Connector làm ngược lại — tiêu thụ Kafka Topic và ghi ra hệ thống đích. Có hàng trăm connector sẵn có trên Confluent Hub.