Luyện Phỏng Vấn IT — 2000+ Câu Hỏi Phỏng Vấn IT Có Đáp Án 2026

Kafka là distributed event streaming platform cho phép xử lý dữ liệu real-time với throughput cao, latency thấp và khả năng replay message — lý do chính khiến nó phổ biến trong hệ thống phân tán.

  • Apache Kafka được LinkedIn phát triển và open-source năm 2011.
  • Kafka được thiết kế để xử lý luồng dữ liệu thời gian thực với thông lượng cực cao, độ trễ thấp và khả năng mở rộng theo chiều ngang.
  • Điểm mạnh của Kafka so với các message broker truyền thống là khả năng lưu trữ message lâu dài trên disk (không xóa sau khi consumer đọc), cho phép nhiều consumer đọc lại cùng một message.
  • Kafka thường được dùng trong các use case như event sourcing, log aggregation, real-time analytics, data pipeline giữa các microservices, và change data capture (CDC) từ database.

Kafka cluster gồm nhiều Broker lưu Topic, mỗi Topic chia thành Partition để song song hoá, và Consumer Group để scale đọc. Broker là một server Kafka chạy độc lập; một Kafka cluster thường có nhiều broker để đảm bảo high availability. Topic là kênh logic để phân loại message (ví dụ: topic 'orders', topic 'payments'). Mỗi topic được chia thành nhiều Partition — đây là đơn vị song song hóa của Kafka; các message trong một partition được sắp xếp theo thứ tự và mỗi message có một offset duy nhất. Consumer Group là nhóm các consumer cùng nhau đọc một topic; mỗi partition chỉ được đọc bởi đúng một consumer trong group tại một thời điểm, cho phép scale out việc tiêu thụ message.

Ví dụ: nếu topic có 6 partition và group có 3 consumer, mỗi consumer xử lý 2 partition.

Producer gửi message đến một topic và Kafka tự động phân phối message vào các partition (theo key hash, round-robin, hoặc custom partitioner).

  • Cấu hình quan trọng của producer: acks (0=fire-and-forget, 1=leader ack, all=tất cả ISR ack), retries, batch.sizelinger.ms để tối ưu throughput.
  • Consumer đọc message từ partition theo offset và có thể commit offset tự động (enable.auto.commit=true) hoặc thủ công.
  • Cấu hình quan trọng của consumer: auto.offset.reset (earliest/latest), max.poll.records, session.timeout.ms.
  • Trong thực tế, nên dùng manual commit để tránh mất message khi consumer crash trước khi xử lý xong.

Kafka Connect là framework tích hợp sẵn trong Kafka ecosystem để kết nối Kafka với các external system (database, file system, cloud storage, search engine) mà không cần viết code.

  • Kafka Connect có hai loại connector: Source Connector (đọc data từ external system vào Kafka, ví dụ: Debezium CDC từ PostgreSQL) và Sink Connector (ghi data từ Kafka ra external system, ví dụ: Elasticsearch Sink).
  • Connect chạy ở chế độ distributed với worker pool, tự động handle fault tolerance và load balancing.

Ví dụ thực tế: dùng Debezium Source Connector để capture mọi thay đổi trong MySQL database, publish vào Kafka topic, sau đó Elasticsearch Sink Connector index data để search — toàn bộ pipeline không cần viết một dòng code custom nào.

Kafka được dùng rộng rãi cho log aggregation, event sourcing, CDC, và microservices communication nhờ khả năng lưu trữ và replay message.

Các use case phổ biến của Kafka trong production:

  • Log aggregation: tập hợp log từ nhiều service vào một nơi, sau đó forward sang Elasticsearch hoặc S3 để phân tích.
  • Event sourcing: lưu tất cả sự kiện (thay vì chỉ state hiện tại) để rebuild state bất kỳ lúc nào.
  • Real-time analytics: stream data từ user activity vào Kafka, xử lý với Kafka Streams hoặc Flink để cập nhật dashboard real-time.
  • Microservices communication: thay vì gọi API trực tiếp (tight coupling), các service publish event và service khác subscribe — giảm coupling và tăng resilience.
  • Change Data Capture (CDC): dùng Debezium để capture mọi thay đổi từ database, sync sang data warehouse hoặc invalidate cache.
  • Fraud detection: stream giao dịch tài chính qua Kafka, dùng ML model để detect bất thường trong real-time.

Offset là số thứ tự của message trong một partition, bắt đầu từ 0.

  • Kafka lưu offset của consumer vào một internal topic tên __consumer_offsets.
  • Auto commit (enable.auto.commit=true) sẽ tự động commit offset theo chu kỳ auto.commit.interval.ms (mặc định 5000ms), nhưng có thể dẫn đến mất message nếu consumer crash SAU khi auto-commit nhưng TRƯỚC khi xử lý xong message đó, hoặc xử lý trùng nếu consumer crash sau khi xử lý nhưng trước khi auto commit.
  • Manual commit (commitSync() hoặc commitAsync()) cho phép kiểm soát chính xác: chỉ commit sau khi xử lý thành công. commitSync() block cho đến khi commit thành công, commitAsync() không block nhưng cần callback để xử lý lỗi.
  • Trong production, nên dùng manual commit kết hợp với idempotent processing để đảm bảo at-least-once hoặc exactly-once semantics.

Kafka đảm bảo thứ tự message trong phạm vi một partition — các message được ghi và đọc theo đúng thứ tự FIFO.

  • Tuy nhiên, không có đảm bảo thứ tự giữa các partition khác nhau.
  • Để đảm bảo ordering cho một nhóm message liên quan (ví dụ: tất cả sự kiện của một user), cần gán cùng một message key — Kafka sẽ hash key và luôn route message có cùng key vào cùng partition.
  • Ordering có thể bị phá vỡ khi: producer bật retries > 0max.in.flight.requests.per.connection > 1 (message sau có thể arrive trước message trước bị retry) — giải pháp là bật enable.idempotence=true.
  • Ngoài ra, rebalancing consumer group không ảnh hưởng đến thứ tự trong partition vì offset được duy trì.

Mỗi partition có một leader và nhiều follower replica trên các broker khác nhau.

  • Leader xử lý tất cả read/write, follower chủ động pull data từ leader để sync.
  • ISR (In-Sync Replicas) là tập hợp các replica đang sync kịp với leader (không bị lag quá replica.lag.time.max.ms).
  • Khi leader broker bị lỗi, một replica trong ISR sẽ được bầu làm leader mới.
  • Cấu hình replication.factor=3min.insync.replicas=2 kết hợp với acks=all đảm bảo message chỉ được acknowledge khi ít nhất 2 replica đã ghi — bảo vệ khỏi mất data kể cả khi 1 broker bị lỗi.
  • Trong production nên dùng replication.factor >= 3 để chịu được lỗi của 2 broker đồng thời.

Kafka Streams là thư viện Java/Scala để xây dựng ứng dụng stream processing trực tiếp trên Kafka, không cần external cluster như Spark hay Flink. Kafka Streams cung cấp các operation high-level như filter, map, groupBy, aggregate, join giữa các stream. Điểm khác biệt: consumer thông thường chỉ đọc và xử lý message, còn Kafka Streams có khái niệm KStream (unbounded stream of events) và KTable (changelog stream, represents current state), cho phép stateful processing với local state store (RocksDB). Kafka Streams tự động handle partitioning, scaling, và fault recovery — khi thêm instance, Kafka tự rebalance partition.

Ví dụ: tính tổng doanh thu mỗi 5 phút từ stream order events, join stream clicks với stream purchases để tính conversion rate.

Idempotent producer đảm bảo rằng dù producer retry gửi message bao nhiêu lần (do network error, timeout), mỗi message chỉ được ghi đúng một lần vào partition. Cách hoạt động: Kafka assign cho mỗi producer một Producer ID (PID) duy nhất và mỗi message có sequence number tăng dần per-partition. Broker reject nếu thấy message có sequence number đã nhận hoặc không liên tiếp. Bật bằng cách set enable.idempotence=true — tự động set acks=all, max.in.flight.requests.per.connection=5, retries=Integer.MAX_VALUE. Idempotence chỉ trong một producer session — nếu producer restart, PID mới và sequence reset. Để exactly-once across sessions và multiple partitions, cần Kafka Transactions.

Ví dụ:

props.put("enable.idempotence", "true");
props.put("transactional.id", "my-tx-id"); // cho transactions

Mặc định Kafka producer gửi message ngay lập tức (linger.ms=0), nhưng cách này kém hiệu quả khi throughput cao vì mỗi request chứa ít record. batch.size (default 16384 bytes = 16KB) là kích thước tối đa của một batch per-partition — khi batch đầy, gửi ngay. linger.ms (default 0ms) là thời gian producer chờ thêm message trước khi gửi dù batch chưa đầy — tương tự Nagle's algorithm của TCP. Tuning throughput: tăng batch.size lên 128KB–1MB, thêm linger.ms=10–50ms để gom nhiều message hơn, bật compression.type=lz4 hoặc snappy. Kết quả: throughput tăng 3-5x, latency tăng nhẹ (chấp nhận được cho non-realtime). Với low-latency use case (trading, alerting) thì giữ linger.ms=0.

Trade-off: linger.ms cao → throughput tốt, latency cao; linger.ms=0 → latency thấp nhất, throughput thấp hơn.

At-most-once (fire-and-forget): producer acks=0, consumer commit offset trước khi xử lý — message có thể mất, không bao giờ duplicate.

  • Dùng cho metrics/log không cần chính xác tuyệt đối. At-least-once: producer acks=all + retries, consumer commit sau khi xử lý thành công — không mất message nhưng có thể xử lý trùng (duplicate) khi consumer crash sau xử lý nhưng trước commit.
  • Yêu cầu consumer logic phải idempotent. Exactly-once: khó nhất, cần cả producer và consumer phối hợp.
  • Producer: bật enable.idempotence=true + Kafka Transactions (transactional.id).
  • Consumer: isolation.level=read_committed + đặt offset commit trong cùng transaction với business logic (nếu write ra DB phải là transactional outbox).
  • Kafka Streams với processing.guarantee=exactly_once_v2 tự handle toàn bộ.
  • Exactly-once có overhead ~20-30% latency — chỉ dùng cho billing, financial transactions.

Kafka Group Coordinator (broker) quản lý consumer group lifecycle và partition assignment.

  • Khi consumer join group, Group Coordinator trigger rebalance và chọn một consumer làm Group Leader — Leader thực hiện partition assignment theo strategy đã cấu hình và gửi kết quả về Coordinator. RangeAssignor (default): assign partition liên tiếp theo topic — consumer 0 nhận partition 0,1; consumer 1 nhận 2,3.
  • Nếu partition không chia đều, consumer đầu tiên nhận nhiều hơn (uneven distribution across topics). RoundRobinAssignor: phân phối đều hơn bằng cách xen kẽ — mỗi consumer nhận partition luân phiên. StickyAssignor: cố gắng minimize sự thay đổi so với assignment trước. CooperativeStickyAssignor: như Sticky nhưng dùng cooperative protocol (không stop-the-world) — khuyến nghị cho ứng dụng mới theo KIP-429.
  • Thực tế: số consumer không nên vượt số partition — consumer thừa sẽ idle.
  • Khi scale out, thêm partition TRƯỚC khi thêm consumer để tránh idle consumers.

Partition key quyết định message vào partition nào (hash(key) % numPartitions).

  • Chọn key sai dẫn đến: hotspot (một partition bị overload), hoặc mất ordering (message liên quan vào partition khác nhau). Nguyên tắc chọn key: chọn field có cardinality cao và phân phối đều — user_id, order_id, device_id tốt hơn country_code hay status.
  • Key phải là field mà ordering quan trọng trong context của nó: tất cả event của cùng order_id phải theo thứ tự → dùng order_id làm key. Tránh hotspot: nếu key phân phối không đều (một số user_id hoạt động cực nhiều), thêm random suffix: user_id + '-' + random(0, N) — nhưng sẽ mất ordering global per user.
  • Kỹ thuật khác: key salting key + timestamp_bucket — partition thay đổi theo thời gian.
  • Tăng số partition cũng giúp giảm hotspot nhưng không giải quyết root cause nếu key quá skewed.