← Tất cả bài viết

Kafka Internals #1: Kafka thực sự là gì, và khi nào không nên dùng

Kafka không phải hàng đợi. Bài đầu tiên lần theo một record từ partition đến replication, chỉ ra điểm mạnh thật sự, chi phí vận hành và khi nào nên chọn công cụ khác.

17 phút đọcTuyên

Kafka Internals — phần 1/3. Series đi theo một record từ producer đến commit. Phần 2 đi vào producer; phần 3 đi vào consumer và offset.

Phiên bản: bài viết đối chiếu Apache Kafka 4.3.x tại tháng 10/2026. Với Kafka 3.x, một số mặc định và protocol đã khác; những chỗ đáng chú ý sẽ được ghi rõ.

Để đọc bài này: người đọc cần nắm các khái niệm cơ bản về Kafka: topic, partition, producer, consumer và offset. Hệ thống ví dụ có 3 broker, replication factor 3, 12 partitions, min.insync.replicas=2; consumer xử lý đồng bộ trong poll loop. Các con số trong bài là minh hoạ, không phải kết quả đo production.

Một đơn hàng bị chặn 30 giây

Topic orders có 12 partitions. Consumer group có 4 instance. Instance A đang giữ partition 3; instance B giữ partition 7. Một đơn hàng trên partition 3 gọi payment service và bị timeout 30 giây.

Trong 30 giây đó, mọi record đến sau trên partition 3 phải chờ. Nếu A còn giữ partition 4, partition 4 cũng chờ, vì consumer xử lý tuần tự trong một thread. Partition 7 vẫn chạy bình thường vì B không bị chặn.

Đây là ví dụ giả định, nhưng cơ chế thì có thật. Nó giải thích luôn ba giới hạn thường gặp:

  • Thứ tự chỉ được đảm bảo trong một partition, không phải toàn topic.
  • Một partition chỉ thuộc một consumer trong một group tại một thời điểm.
  • Số partition là trần parallelism của group. Scale lên 20 consumer mà topic vẫn 12 partitions thì 8 instance sẽ không nhận được partition nào.

Nếu giảm còn 1 partition để "đảm bảo thứ tự", mọi record đi qua một consumer. Throughput giảm, khả năng chịu lỗi giảm, và một record chậm chặn toàn bộ consumption của topic.

Đây không phải bug. Đó là hệ quả của một mô hình dữ liệu: Kafka là một tập các log có thứ tự, không phải một hàng đợi công việc. Hiểu mô hình này sẽ trả lời được câu hỏi quan trọng hơn: khi nào nên dùng Kafka, và khi nào nên chọn công cụ khác.

Kafka là một replicated log, không phải hàng đợi

Ở tầng thấp, Kafka lưu một chuỗi record trong các partition. Mỗi partition là một log append-only, được replicate sang các broker khác. Producer ghi vào cuối log; consumer đọc từ một offset. Không có khái niệm "message tiếp theo" ngoài offset tiếp theo trong một partition.

Record, partition, offset

Một record gồm key, value, headers và timestamp. Với default partitioner, key được hash để chọn partition. Cùng một key đi vào cùng một partition, nên các record của cùng một đơn hàng nằm cạnh nhau và giữ được thứ tự. Nếu key là null, producer dùng sticky partitioner: record được dồn vào một partition cho đến khi batch đầy, nhưng không có ordering theo key.

Partition là một log append-only. Mỗi record nhận một offset tăng đơn điệu trong partition đó. Offset không phải ID toàn cục: partition 3 và partition 7 đều có offset 0, và offset 0 của chúng là hai vị trí khác nhau. Record không bị sửa tại chỗ; compaction chỉ xóa bản cũ.

Consumer group chia các partition cho các instance. Một partition chỉ thuộc một consumer trong group tại một thời điểm, nhưng nhiều group có thể đọc cùng một partition độc lập. Offset đã commit của mỗi group nằm trong topic nội bộ __consumer_offsets; vì vậy hai group có thể đọc cùng dữ liệu ở hai tốc độ khác nhau mà không ảnh hưởng nhau.

Hai chi tiết dễ bị bỏ qua. Thứ nhất, thứ tự của Kafka là thứ tự append vào partition, không phải thứ tự nghiệp vụ: nếu hai producer ghi cùng một key đồng thời, broker quyết định thứ tự cuối cùng. Thứ hai, tăng số partition có thể đổi mapping key → partition, làm record cũ và mới của cùng một key rơi vào hai partition khác nhau. Số partition không giảm được, nên đây là quyết định phải làm trước khi có traffic thật.

Hai consumer group đọc cùng một partition với offset riêng
Hình 1. Offset là vị trí trong một partition; mỗi consumer group có con trỏ riêng.
Mở ảnh lớn

Retention và compaction quyết định vòng đời dữ liệu

Kafka không xóa record khi consumer đã đọc. Record tồn tại theo retention hoặc theo chính sách compaction của topic.

Với cleanup.policy=delete — mặc định — Kafka xóa segment cũ khi vượt retention.ms hoặc retention.bytes. Mặc định topic giữ 7 ngày (retention.ms=604800000); đặt -1 là không giới hạn thời gian, còn retention.bytes=-1 là không giới hạn theo kích thước. Vì xóa theo segment, dung lượng thực tế có thể lớn hơn mức bạn hình dung.

Với cleanup.policy=compact, Kafka giữ bản ghi cuối cùng cho mỗi key. Record cũ cùng key bị dọn dần; tombstone (value null) đánh dấu key bị xóa và được giữ thêm một thời gian (delete.retention.ms, mặc định 1 ngày) để consumer kịp đọc. Compaction chạy nền, không tức thời.

Hệ quả: replay chỉ có thể trong cửa sổ retention. Nếu topic giữ 7 ngày, consumer mới chỉ đọc lại được 7 ngày gần nhất. Retention không phải backup, và replication cũng không phải backup: replication bảo vệ trước lỗi broker, không bảo vệ trước lỗi logic xóa dữ liệu hoặc một sự kiện xóa topic.

Offset cũng có thể có khoảng trống. Compaction xóa record, aborted transaction không trả record cho consumer read_committed, và offset vẫn tiếp tục tăng. Đừng giả định offset liên tục hay dùng offset như số thứ tự nghiệp vụ.

Replication: acks=all mạnh đến đâu?

Mỗi partition có một leader và các follower. Follower fetch từ leader để sao chép log. Tập replica bắt kịp leader là ISR (in-sync replicas). High watermark là offset mà mọi replica trong ISR đã replicate; consumer chỉ đọc được đến vùng đó.

acks=all — mặc định từ Kafka 3.0 — khiến leader đợi toàn bộ ISR ack trước khi báo thành công. Cần nhấn mạnh: "toàn bộ ISR", không phải "toàn bộ replica". Nếu ISR co lại còn 2 trong 3 replica, acks=all chỉ đợi 2 replica đó.

min.insync.replicas đặt ngưỡng ISR tối thiểu để nhận ghi. Mặc định là 1, nên acks=all với RF=3 vẫn có thể chỉ đợi leader nếu ISR co lại. Với RF=3 và min.insync.replicas=2, nếu hai broker chết và ISR chỉ còn 1, producer nhận lỗi thay vì ghi vào một replica duy nhất. Đây là availability đổi lấy durability: từ chối ghi thay vì nhận rủi ro mất dữ liệu.

unclean.leader.election.enable là lựa chọn ngược lại. Mặc định là false. Nếu bật, một replica ngoài ISR có thể thành leader khi các replica khác không sẵn sàng. Điều này tăng availability nhưng có thể làm mất record chưa kịp replicate. Vì vậy câu "acks=all không mất dữ liệu" chỉ đúng khi đi kèm min.insync.replicas và election policy phù hợp.

Trong Kafka 4.x, metadata do KRaft controller quorum quản lý; ZooKeeper đã bị loại bỏ từ 4.0. Controller quorum nằm ngoài data path: nó giữ metadata và bầu leader, nhưng không replicate record. Đừng nhầm replication của partition với replication của metadata.

Cấu hình

Điều được đảm bảo

Khi nào có thể mất

acks=1, RF=3

Leader đã ghi; chưa chắc follower đã có

Leader chết trước khi follower replicate

acks=all, minISR=2, RF=3

Ít nhất 2 ISR đã có record

ISR tụt dưới 2 thì producer lỗi; nếu bật unclean election, vẫn có thể mất

acks=all, minISR=3, RF=3

Cả 3 replica đã có record

Một replica chết là không ghi được; availability giảm

Leader và follower trong ISR; acks=all đợi toàn bộ ISR
Hình 2. acks=all chỉ đợi các replica trong ISR; khi ISR co lại, durability thay đổi.
Mở ảnh lớn

Consumer thường đọc từ leader. KIP-392 cho phép đọc từ follower gần nhất nếu cấu hình rack-aware fetching, nhưng mặc định vẫn là leader.

Vì sao log lại nhanh — và vì sao nhanh không đủ

Kafka nhanh vì nó làm một việc đơn giản rất tốt: ghi tuần tự vào cuối log. Ghi tuần tự thân thiện với disk hơn nhiều so với cập nhật ngẫu nhiên nhiều dòng. Kafka cũng dựa vào page cache của OS, không đặt toàn bộ dữ liệu trong JVM heap. Producer gom record thành batch, nén batch, rồi gửi ít request hơn. Consumer fetch theo batch. Follower replicate theo pipeline.

Zero-copy là một mảnh khác: với plaintext, Kafka có thể dùng sendfile để chuyển dữ liệu từ page cache ra socket mà không copy qua user space. Nhưng zero-copy không miễn phí trong mọi cấu hình: TLS/SSL cần mã hoá trong user space, nên lợi ích này có thể mất khi bật encryption.

Có một chi tiết quan trọng thường bị bỏ qua: Kafka không fsync từng record theo mặc định. flush.messages mặc định là Long.MAX_VALUE; Kafka dựa vào OS flush và replication để bảo vệ dữ liệu. acks=all đảm bảo record đã nằm trong log của các ISR, nhưng không đảm bảo nó đã được fsync xuống đĩa vật lý. Nếu toàn bộ replica mất điện cùng lúc, record gần nhất vẫn có thể mất. Đây là lý do durability của Kafka là "replication + OS flush", không phải một cam kết tuyệt đối.

Và throughput cao không có nghĩa latency thấp. Một record phải đi qua nhiều chặng:

  • linger.ms ở producer: mặc định 5ms từ Kafka 4.0, tăng lên để gom batch.
  • Broker append và replication: acks=all đợi ISR.
  • Consumer fetch: fetch.min.bytes và fetch.max.wait.ms quyết định consumer chờ bao lâu.
  • Xử lý của ứng dụng: một payment call 30 giây sẽ chặn consumer thread.

Tail latency còn đến từ page cache miss, disk chậm, GC, rebalance và hot partition. Giả sử một hệ thống có throughput 100 MB/s; nó vẫn có thể có p99 latency rất xấu nếu một partition bị chặn.

Mục tiêu

Knob chính

Cái giá

Throughput

batch.size, linger.ms, compression

Latency tăng, memory tăng

Latency thấp

linger.ms=0, batch nhỏ, fetch.min.bytes=1

Nhiều request hơn, CPU cao hơn

Durability

acks=all, minISR=2, RF=3

Availability giảm khi thiếu replica, cost tăng

Cost thấp

retention ngắn, RF thấp, tiered storage

Replay window ngắn, durability giảm

Kafka được tối ưu cho throughput và sequential access. Latency thấp là một cấu hình riêng, không phải thuộc tính mặc định.

Điểm mạnh thật sự — và điều kiện để có chúng

Kafka không mạnh vì có nhiều tính năng. Nó mạnh vì một cơ chế duy nhất: một log replicated cho phép nhiều consumer đọc độc lập và replay. Hầu hết điểm mạnh khác là hệ quả của cơ chế đó.

Nhu cầu

Cơ chế đáp ứng

Điều kiện để đúng

Bài toán điển hình

Replay/backfill

Retention + reset offset

Retention đủ dài; schema ổn định

Consumer mới, sửa bug, audit

Fan-out

Nhiều consumer group

Partition/consumer đủ; group độc lập

Event backbone, notification

Ordering theo key

Key → partition

Key cardinality tốt; không hot key

Trạng thái đơn hàng, tài khoản

Buffer burst

Log trên disk

Disk/lag capacity; có monitoring

Giải mã tải, decoupling

Durability

Replication + acks=all

RF≥3, minISR≥2, election hợp lý

Payment, audit, CDC

Hệ sinh thái

Connect/Streams/Schema Registry

Có người vận hành

CDC, stream processing

Replay là điểm mạnh khó thay thế nhất. Queue thông thường xóa message sau khi ack; Kafka giữ lại theo retention. Một consumer mới có thể đọc lại từ đầu, một consumer bị lỗi có thể tua lại để sửa dữ liệu, một pipeline mới có thể backfill mà không cần producer gửi lại. Điều kiện là retention đủ dài và schema không thay đổi theo cách phá vỡ consumer cũ.

Fan-out thật sự độc lập vì mỗi consumer group có offset riêng. Một group có thể đọc chậm mà không ảnh hưởng group khác. Điều kiện là đủ partition cho parallelism và đủ dung lượng cho từng group.

Ordering theo key đủ cho nhiều bài toán nghiệp vụ: mọi event của một đơn hàng, một tài khoản, một thiết bị nằm cùng partition. Nó không cho global ordering, và nó chỉ đúng nếu key có cardinality tốt. Một key quá phổ biến tạo hot partition; thêm partition không chia được một key.

Buffer cho phép producer và consumer chạy ở hai tốc độ khác nhau. Nhưng backlog không miễn phí: nó là disk, là lag, là thời gian recovery. Giả sử một topic có 1 tỷ record tồn đọng; nó vẫn "hoạt động", nhưng consumer có thể mất hàng giờ để đuổi kịp.

Durability là kết quả của cấu hình, không phải mặc định của sản phẩm. RF=3, minISR=2, acks=all và election policy hợp lý mới tạo ra mức bảo vệ mong muốn. Và durability không thay thế backup.

Bài toán nào phù hợp

Bài toán

Mức phù hợp

Lý do

Event backbone/domain events

Mạnh

Nhiều consumer, replay, ordering theo key

CDC/outbox

Mạnh

Log là đích tự nhiên của thay đổi dữ liệu

Audit/event sourcing

Mạnh

Giữ lịch sử, replay được

Activity tracking/metrics/logs

Mạnh

Throughput cao, nhiều consumer

Stream processing

Mạnh

Kafka Streams/Flink đọc trực tiếp

Task queue đơn giản

Có điều kiện

Làm được, nhưng retry/DLQ/priority phải tự xây

Notification/fan-out

Có điều kiện

Phụ thuộc volume và yêu cầu delay

Request/reply

Yếu

Không phải mô hình của Kafka

Delay/priority/TTL

Yếu

Không có primitive per-message

Payload lớn

Yếu

Cần claim check/external storage

Global ordering

Yếu

Chỉ có per-partition ordering

CRUD volume thấp

Yếu

Vận hành đắt so với nhu cầu

Điểm chung: Kafka phù hợp khi dữ liệu là một dòng sự kiện cần được giữ lại, chia sẻ cho nhiều consumer và đọc lại. Nếu dữ liệu chỉ là một task cần chuyển từ A sang B, Kafka thường là quá mức cần thiết.

Điểm yếu cố hữu — cái giá của log

Phần lớn điểm yếu của Kafka không phải lỗi cấu hình. Chúng là hệ quả trực tiếp của mô hình partition và log.

Ordering chỉ theo partition

Một record chậm chặn các record sau trong cùng partition. Nếu consumer xử lý đồng bộ, nó còn chặn mọi partition khác trên cùng consumer thread. Đây là head-of-line blocking, và nó là lý do một đơn hàng lỗi có thể làm chậm cả một nhóm đơn hàng.

Hot key là mặt còn lại. Giả sử key là tenantId và một tenant chiếm 40% traffic; partition chứa tenant đó chịu tải cao hơn hẳn. Thêm partition không chia được một key; muốn giảm hot key phải đổi key hoặc tách topic.

Global ordering đòi hỏi một partition. Một partition chỉ cho một consumer trong group, nên throughput bị giới hạn bởi consumer đó. Với nhiều producer, thứ tự vẫn là thứ tự broker nhận request, không phải thứ tự nghiệp vụ.

Số partition không giảm được. Tăng partition có thể đổi mapping key → partition và làm lệch ordering giữa record cũ và mới. Đây là quyết định không thể đảo ngược, cần làm trước khi có traffic thật.

Kafka không phải queue đa dụng

Kafka không có per-message delay, priority, TTL hay visibility timeout. Retention là cấp topic, không phải cấp message. Muốn "nhắc thanh toán sau 15 phút", "ưu tiên job VIP" hoặc "task hết hạn sau 1 giờ", cần một scheduler hoặc queue khác.

Retry topic, DLQ, delay topic là những pattern của ứng dụng, không phải primitive của Kafka. Chúng hoạt động, nhưng bạn phải tự xây, tự vận hành và tự đảm bảo ordering.

KIP-932 share group (production-ready từ Kafka 4.2) bổ sung một phần semantics kiểu queue: record được acquire và acknowledge, có delivery count. Nhưng nó không thay thế đầy đủ một queue đa dụng: không có offset commit kiểu consumer group, semantics khác, và không có sẵn mọi thứ như delay/priority. Cần đọc kỹ trước khi dùng share group thay cho SQS/RabbitMQ.

Vận hành và chi phí dữ liệu

Kafka là một hệ phân tán phải vận hành: broker, disk, replication, controller quorum, upgrade, quota, multi-tenancy, security. Một team nhỏ, volume thấp thường trả giá vận hành cao hơn giá trị nhận được.

Dữ liệu cũng không rẻ. RF=3 nghĩa là mỗi byte được lưu ba lần; cross-AZ replication thêm chi phí network; retention dài làm storage tăng tuyến tính. Backlog không miễn phí: lag lớn là disk, là thời gian recovery, là incident.

Monitoring tối thiểu gồm lag, ISR, disk, controller health và request latency. Nếu không có người trực và dashboard, Kafka sẽ trở thành một điểm mù.

Những giới hạn còn lại

Exactly-once của Kafka chỉ đúng trong biên read-process-write bên trong Kafka. Nếu consumer ghi DB hoặc gọi HTTP, Kafka không làm side effect đó trở nên exactly-once; cần idempotency key, outbox hoặc một thiết kế riêng. Bài 2 sẽ đi sâu vào điểm này.

Payload lớn nên dùng claim check: gửi metadata vào Kafka, nội dung thật nằm ở object storage; max.message.bytes và max.request.size là giới hạn cần biết.

Schema là một chi phí khác. Không có Schema Registry, producer và consumer dễ coupling theo JSON tự phát; thay đổi field có thể phá consumer cũ.

Kafka không phải database: không có query, không có secondary index. Nó cũng không phải request/response: muốn có kết quả trả về, cần correlation ID và response topic, hoặc dùng HTTP/gRPC.

Điểm yếu

Cơ chế

Failure mode

Giảm thiểu/alternative

Head-of-line

1 partition → 1 consumer

Record chậm chặn key

Async processing, tách topic, partition hợp lý

Hot key

Hash lệch

Một partition quá tải

Key salting, tách topic

Không delay/priority/TTL

Log semantics

Không schedule được

SQS/Rabbit/Redis, scheduler ngoài

Ops cost

Broker/disk/controller

Burnout, incident

Managed service, owner rõ

Storage cost

RF=3 + retention

Cost tăng

Tiered storage, compaction, retention

Payload lớn

Batch/record limit

Broker pressure

Claim check

EOS hẹp

Transaction chỉ trong Kafka

Duplicate side effect

Idempotency/outbox

Không request/reply

Async log

Correlation phức tạp

HTTP/gRPC

Khi nào nên dùng Kafka

Không có câu trả lời đúng cho mọi hệ thống. Có năm câu hỏi giúp loại Kafka sớm nếu không phù hợp.

1. Dữ liệu có phải event log/stream cần replay, hay chỉ là task cần chuyển? Nếu cần đọc lại, backfill hoặc nhiều consumer cùng đọc một dòng sự kiện, Kafka có lợi thế. Nếu chỉ cần chuyển job từ A sang B, queue đơn giản hơn.

2. Có nhiều consumer độc lập/fan-out không? Nếu chỉ có một consumer, lợi thế fan-out không tồn tại; bạn đang trả giá cho một log nhưng chỉ dùng như queue.

3. Có cần ordering theo key không? Key có cardinality tốt không? Nếu cần ordering theo orderId, Kafka làm tốt. Nếu cần global ordering, Kafka không phù hợp. Nếu key là một vài tenant lớn, hot partition sẽ xuất hiện.

4. Có cần hấp thụ burst/decouple producer-consumer không? Kafka làm tốt, nhưng phải tính disk, lag và thời gian recovery. Backlog không miễn phí.

5. Có owner vận hành và ngân sách cho broker/disk/retention không? Nếu không, managed service hoặc một queue nhẹ hơn là lựa chọn hợp lý hơn.

Không nên dùng Kafka khi

  • Chỉ cần chuyển task từ A sang B, không cần replay/fan-out.
  • Cần per-message delay, priority, TTL hoặc visibility timeout.
  • Cần request/response đồng bộ.
  • Payload rất lớn và không muốn claim check.
  • Cần global ordering tuyệt đối.
  • Không có người/ngân sách vận hành broker.

So sánh nhanh với các lựa chọn khác

Lựa chọn

Delivery/ordering

Replay

Delay/priority

Ops

Phù hợp

Kafka

At-least-once/EOS; order per partition

Có, theo retention

Không native

Cao

Event log, fan-out, stream

RabbitMQ

Ack per message; queue ordering

Hạn chế

Có plugin/priority

Trung bình

Task queue, routing

SQS/SNS

At-least-once; FIFO tùy chọn

Không (SQS)

Delay queue, DLQ

Thấp

AWS-native decoupling

Pulsar

Queue/stream; subscription

Có

Tùy

Cao

Multi-tenant streaming

NATS JetStream

At-least-once; persistence

Có

Hạn chế

Thấp–trung bình

Low-latency messaging

Postgres outbox + queue

Transactional với DB

Có giới hạn

Tự xây

Thấp

Side effect exactly-once-ish

Bảng này so sánh hành vi công bố, không phải benchmark. Không lựa chọn nào thắng mọi tiêu chí: RabbitMQ mạnh routing và per-message ack; SQS nhẹ vận hành; Pulsar mạnh multi-tenancy; NATS JetStream nhẹ và nhanh; Postgres outbox mạnh khi cần transactional với DB.

Phương án hybrid

Kafka thường là một phần của kiến trúc, không phải toàn bộ.

  • Kafka làm event log; SQS/RabbitMQ làm task queue. Hai công cụ giải hai bài toán khác nhau.
  • Kafka + Postgres outbox cho side effect transactional. Ghi outbox trong cùng transaction DB, rồi relay sang Kafka.
  • Kafka + Kafka Streams/Flink cho stateful processing.
  • Tránh dual-write: đừng ghi Kafka và DB trong hai transaction rời. Dùng outbox/CDC để biến hai lần ghi thành một luồng có thể phục hồi.
Cây quyết định chọn Kafka dựa trên replay, fan-out, queue semantics và ops
Hình 3. Cây quyết định: trả lời “không” ở câu đầu tiên thường loại Kafka sớm.
Mở ảnh lớn

Checklist trước khi chọn Kafka

Trước khi tạo topic, trả lời bảy câu hỏi:

  • Retention: cần replay bao lâu? retention.ms/retention.bytes đủ chưa?
  • Key: đơn vị ordering là gì? Cardinality có tốt không? Có hot tenant/key?
  • Partitions: parallelism tối đa cần bao nhiêu? Tăng partition sau này ảnh hưởng key/order thế nào? Số partition không giảm được.
  • Consumer groups: có bao nhiêu group? Mỗi group có đủ consumer theo partition không?
  • Ops: ai trực? ai upgrade? có monitoring lag/ISR/disk/controller không?
  • Cost: RF=3 + retention + cross-AZ; so với managed service/queue chưa?
  • Correctness: at-least-once hay EOS? Side effect có idempotent không? DLQ/retry ra sao?

Ví dụ tối thiểu cho topic orders:

kafka-topics.sh --bootstrap-server localhost:9092 \
  --create --topic orders \
  --partitions 12 \
  --replication-factor 3 \
  --config min.insync.replicas=2 \
  --config retention.ms=604800000 \
  --config cleanup.policy=delete

Số partition và replication factor là quyết định một chiều; đổi sau sẽ tốn kém.

Tín hiệu phải thiết kế lại:

  • Lag tăng dù traffic không tăng.
  • Rebalance storm hoặc consumer liên tục bị thu hồi partition.
  • Một partition hot bất thường.
  • Storage cost tăng nhanh hơn giá trị dữ liệu, hoặc không có owner vận hành.

Ba điều không nên làm:

  • Dùng Kafka như database/query store.
  • Dùng Kafka cho request/response đồng bộ.
  • Giả định "acks=all = không mất dữ liệu" mà không kiểm tra minISR và election policy.

Kết: chọn mô hình, không chọn API

Kafka không phải lựa chọn mặc định cho mọi async. Nó là lựa chọn cho event log có replay, fan-out và ordering theo key. Cái mua được là mô hình log; cái trả là partition planning, vận hành và một tập guarantee hẹp.

Nếu bài toán chỉ là chuyển task, queue hoặc DB phù hợp hơn và rẻ hơn. Nếu cần nhiều consumer đọc lại cùng một dòng sự kiện, Kafka thường là lựa chọn mạnh — miễn là đội ngũ hiểu rằng thứ tự chỉ đúng trong partition, và durability phụ thuộc vào cấu hình chứ không phải tên sản phẩm.

Chọn Kafka vì cần log, không vì cần một message broker. Bài tiếp theo đi vào con đường từ send() đến broker, nơi batch, retry và exactly-once bắt đầu.

Bài tiếp theo: Kafka Internals #2 — Producer: từ send() đến broker, và giới hạn của exactly-once.

Nguồn tham khảo

Tuyên
NGƯỜI VIẾTTuyên

Một lập trình viên tò mò và cố gắng trở nên tốt hơn mỗi ngày.