Nguồn tham khảo: Udemy — Developer to Architect Series

Mục tiêu bài viết

  • Hiểu Kafka là distributed log — khác RabbitMQ ở chỗ nào.
  • Nắm tại sao sequential write + partition giúp Kafka scale ngang.
  • Hiểu offset, pull model, event replay và 3 trade-off chính.
  • Biết khi nào dùng Kafka, khi nào dùng RabbitMQ.

1) Big Picture — Kafka khác RabbitMQ ở đâu?

RabbitMQ                         Kafka

Producer                        Producer
   │                               │
   ▼                               ▼
Exchange                       Append
   │                               │
   ▼                               ▼
Queue                          Log File
   │                               │
   ▼                               ▼
Consumer                       Consumer
  • RabbitMQ: tập trung vào message broker + routing + delivery.
  • Kafka: append data cực nhanh → lưu lại → consumer tự đọc theo offset.

2) Kafka = Distributed Log

Kafka đơn giản là một file log được append tuần tự:

┌──────────────────────────────────────────────┐
│                  Kafka Log                   │
├────┬────┬────┬────┬────┬────┬────┬─────────┤
│ M1 │ M2 │ M3 │ M4 │ M5 │ M6 │ M7 │   ...   │
└────┴────┴────┴────┴────┴────┴────┴─────────┘
  0    1    2    3    4    5    6
              ↑
           offset

Producer chỉ làm một việc — append vào cuối log:

Producer
   │
   ▼
Append M8
   │
   ▼
M1 M2 M3 M4 M5 M6 M7 M8

Sequential write cực nhanh → Kafka xử lý được rất nhiều producer cùng lúc.


3) Tại sao Sequential Write nhanh?

Random / complex write      Sequential append
        ↓                           ↓
     nhiều overhead              ít overhead
        ↓                           ↓
       chậm                       nhanh

Kafka chủ yếu append vào cuối log — không cần navigate hay update phức tạp như message broker truyền thống.


4) Consumer không “consume rồi xóa”

Khác biệt lớn nhất so với RabbitMQ:

RabbitMQ:

Queue → Consumer → ACK → DELETE MESSAGE

Kafka:

Consumer
    │ "Tôi đã đọc tới offset 5"
    ▼
Kafka Log vẫn giữ nguyên M1 → M8

Consumer có thể quay lại đọc từ bất kỳ offset nào:

M1 M2 M3 M4 M5 M6 M7 M8
         ↑
      đọc lại từ offset 3

Consumer tự track offset — Kafka core không quản lý consumer đang ở đâu.


5) Offset — trái tim của Kafka

Offset:  0    1    2    3    4    5    6
         M0   M1   M2   M3   M4   M5   M6

Nhiều consumer có thể đọc cùng một log ở vị trí khác nhau:

M0 M1 M2 M3 M4 M5 M6 M7 M8
         ↑          ↑
         │          │
      Consumer A  Consumer B
       offset 3    offset 5

→ Mạnh cho nhiều consumer và replay data.


6) Page Cache — tại sao đọc cũng nhanh

Consumer → Kafka Log → OS → Page Cache → Consumer

OS đọc log theo chunks và giữ trong memory:

┌──────────────────┐
│   Page Cache     │
│ M5 M6 M7 M8 ...  │
└──────────────────┘

Consumer tiếp theo muốn đọc gần đó → không cần đọc disk lại.


7) Kafka Performance Model

                 KAFKA PERFORMANCE
                       │
          ┌────────────┴────────────┐
          ▼                         ▼
       PRODUCER                  CONSUMER
          │                         │
          ▼                         ▼
 Sequential Write              Page Cache
          │                         │
          ▼                         ▼
       Very Fast                 Very Fast
          └────────────┬────────────┘
                       ▼
              VERY HIGH THROUGHPUT
                (millions msg/s)

8) Partition — chìa khóa Horizontal Scaling

Nếu chỉ có một log file → vẫn có bottleneck. Kafka giải quyết bằng Partition:

                   Kafka Topic
                       │
          ┌────────────┼────────────┐
          ▼            ▼            ▼
     Partition 0  Partition 1  Partition 2
     ┌─────────┐  ┌─────────┐  ┌─────────┐
     │ M1 M4   │  │ M2 M5   │  │ M3 M6   │
     │ M7 M10  │  │ M8 M11  │  │ M9 M12  │
     └─────────┘  └─────────┘  └─────────┘

Mỗi partition = một log riêng, có thể nằm trên machine riêng.


9) Partition giúp Producer và Consumer scale ngang

Producer 1 ─────► Partition 0  (Machine A)
Producer 2 ─────► Partition 1  (Machine B)
Producer 3 ─────► Partition 2  (Machine C)
Partition 0 ─────► Consumer A
Partition 1 ─────► Consumer B
Partition 2 ─────► Consumer C
100 partitions → 100 machines → parallel processing → horizontal scaling

10) Đây chính là khác biệt kiến trúc cốt lõi

RabbitMQ:

Master → Slave1, Slave2, Slave3
→ HA / Replication
→ KHÔNG scale workload

Kafka:

Partition 0 → Machine A
Partition 1 → Machine B
Partition 2 → Machine C
→ Parallel processing
→ HORIZONTAL SCALING thực sự

11) Trade-off #1 — Mất Global Ordering

Một log duy nhất:

M1 → M2 → M3 → M4 → M5 → M6  (global ordering)

Khi partition:

Partition 0: M1 → M3 → M5
Partition 1: M2 → M4 → M6

Global ordering bị mất. Nhưng ordering bên trong từng partition vẫn được giữ.

Giải pháp: Gom tất cả event của cùng một entity (vd: user) vào cùng partition:

User A: Event 1 → Event 2 → Event 3 → Event 4
                       │
                  Partition 0

→ Ordering của từng user vẫn được giữ.

Nếu cần global ordering → dùng 1 partition, nhưng mất horizontal scaling.


12) Trade-off #2 — Chỉ Pull, không Push

RabbitMQ: Queue ──PUSH──► Consumer

Kafka: Consumer ──PULL──► Kafka

Consumer tự kiểm soát tốc độ:

Consumer A: 100 msg/s
Consumer B: 500 msg/s
Consumer C: 1000 msg/s

Lợi thế: Consumer-controlled processing rate — rất phù hợp high-throughput workloads.

Hạn chế: Không phù hợp cho service integration vì service phải liên tục polling.


13) Trade-off #3 — Message không bị xóa ngay

Kafka giữ log trong một khoảng thời gian:

Consumer A đọc offset 3
Consumer B đọc offset 5
Consumer A replay lại từ offset 2

Replay event là khả năng cực mạnh của Kafka.


14) Replay Event → Rebuild Database

Kafka Events:
UserCreated → OrderCreated → PaymentCompleted → OrderShipped

Nếu database bị mất:
       ↓
Replay all events
       ↓
Rebuild Database

Đây là nền tảng của event-driven architectureevent sourcing.


15) Kafka phù hợp với Streaming

Users (hàng triệu)
 ├── Click / Page View / Search / Purchase
       │
       ▼
   ┌──────────┐
   │  Kafka   │
   │ P0 P1 P2 │
   └────┬─────┘
        │
        ├────► Analytics
        ├────► Monitoring
        ├────► Recommendation
        └────► Data Pipeline

16) RabbitMQ vs Kafka — Bảng so sánh đầy đủ

  RabbitMQ Kafka
Mô hình Message Broker Distributed Log
Main use case Service integration Streaming
Delivery Push + Pull Pull only
Storage Queue Log
Message sau ACK Delete Retain
Replay
Ordering Global queue ordering Ordering trong partition
Partition Không phải cơ chế scale chính Core scaling mechanism
Horizontal scaling Hạn chế Mạnh
Traffic Variable Very high throughput
Consumer rate Queue push Consumer control
Event replay Không phù hợp Rất phù hợp

17) Mental Model để nhớ

             KAFKA
               │
     ┌─────────┼─────────┐
     ▼         ▼         ▼
   LOG      PARTITION   OFFSET
     │         │         │
     ▼         ▼         ▼
 Append      Scale      Replay
     └─────────┼─────────┘
               ▼
          HIGH THROUGHPUT

3 trade-offs:

Kafka
 │
 ├── Partition  → Scale ↑ / Global ordering ↓
 │
 ├── Pull only  → Consumer control ↑ / Service integration ↓
 │
 └── Retain msg → Replay ↑ / Storage ↑

Tóm tắt — Câu trả lời interview

Kafka scales horizontally because it models data as an append-only distributed log. Sequential writes are very fast. More importantly, Kafka partitions the log — each partition can live on a different machine, allowing producers and consumers to work in parallel. Increasing partitions and machines increases throughput. The trade-off: global ordering is lost (only per-partition ordering is guaranteed), delivery is pull-only (not ideal for service integration), and messages are retained rather than deleted after consumption — enabling event replay.