Triển khai Kafka KRaft mode và KafkaUI bằng docker compose có thể áp dụng cho môi trường production
🧠 Giới Thiệu Kafka KRaft + Docker Compose
✅ Yêu Cầu Trước Khi Bắt Đầu
- Đã cài đặt Docker và Docker Compose
- Có kiến thức cơ bản về Docker và Docker Compose
1. Tổng Quan Về Kafka
Kafka là một distributed streaming platform được sử dụng để xây dựng các ứng dụng real-time data pipeline và stream processing.
Kafka có thể xử lý khối lượng lớn dữ liệu nhờ:
- Partitioning dữ liệu trên nhiều broker
- Đảm bảo High Availability (HA) và Fault Tolerance
🔍 Các Thành Phần Chính Trong Kiến Trúc Kafka
| Thành phần | Vai trò | 
|---|---|
| Producer | Gửi dữ liệu đến topic | 
| Broker | Lưu trữ và quản lý dữ liệu | 
| Consumer | Đọc dữ liệu từ topic | 
| Topic | Tập hợp các message theo danh mục | 
2. Zookeeper Là Gì và Tại Sao Kafka Cần Nó?
🧩 Zookeeper Là Gì?
Zookeeper là một distributed coordination service, giúp Kafka:
- Quản lý metadata (topics, partitions, broker)
- Điều phối election
- Đồng bộ hóa dữ liệu giữa các node
📌 Vai Trò Của Zookeeper Trong Kafka
- 
Quản lý metadata: - Topic, partition, leader election, ACLs
 
- 
Theo dõi trạng thái broker 
- 
Leader election cho partition 
- 
Lưu trữ cấu hình & hạn ngạch (quotas) 
❗Nhược Điểm Khi Sử Dụng Zookeeper
- Cần vận hành một cụm riêng
- Độ trễ và chi phí khi coordination
- Khó mở rộng với high write-throughput
3. KRaft Mode – Kafka Không Cần Zookeeper
Từ Kafka 2.8+ (preview) và 3.3+ (production), Kafka hỗ trợ KRaft Mode:
- Sử dụng Raft consensus algorithm để thay thế Zookeeper
- Metadata lưu trong topic nội bộ: _cluster_metadata
- Tự xử lý broker registration, controller election
🔥 Ưu điểm khi dùng KRaft
- Không cần Zookeeper
- Kiến trúc đơn giản hơn
- Quản lý metadata hiệu quả và ổn định
4. Triển Khai Kafka KRaft Với Docker Compose
📦 Kiến Trúc Docker Compose
- 3 Kafka brokers (KRaft mode)
- 1 Kafka UI để theo dõi hệ thống
🌐 Các Port
| Broker | Host Port | Container Port | 
|---|---|---|
| kafka-1 | 19092 | 9092 | 
| kafka-2 | 29092 | 9092 | 
| kafka-3 | 39092 | 9092 | 
| Kafka UI | 8080 | 8080 | 
🧾 Cấu Hình docker-compose.yml
🔧 Kafka Broker - kafka-1
kafka-1:
  image: apache/kafka:latest
  hostname: kafka-1
  container_name: kafka-kraft-1
  ports:
    - "19092:9092"
  environment:
    KAFKA_NODE_ID: 1
    KAFKA_PROCESS_ROLES: broker,controller
    KAFKA_LISTENERS: PLAINTEXT://kafka-1:9092,CONTROLLER://kafka-1:9093,INTERNAL://kafka-1:9094
    KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-1:9092,INTERNAL://kafka-1:9094
    KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
    KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,INTERNAL:PLAINTEXT
    KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka-1:9093
    KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
    KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
    KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
    KAFKA_NUM_PARTITIONS: 1
    KAFKA_LOG_RETENTION_HOURS: 24
  networks:
    - kafka-net
  volumes:
    - kafka-data-1:/var/lib/kafka/data
🔧 Kafka UI
kafka-ui:
  image: provectuslabs/kafka-ui
  ports:
    - "8080:8080"
  restart: always
  environment:
    KAFKA_CLUSTERS_0_NAME: "kraft-cluster"
    KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka-1:9094,kafka-2:9094,kafka-3:9094
  depends_on:
    - kafka-1
    - kafka-2
    - kafka-3
  networks:
    - kafka-net
📦 Các brokers kafka-2, kafka-3 có cấu hình tương tự kafka-1, chỉ khác KAFKA_NODE_ID, hostname, container_name, ports.
Sau khi hoàn thành mình sẽ được 1 file docker compose hoàn chỉnh sau
version: '3.5'
services:
  kafka-1:
    image: apache/kafka
    hostname: kafka-1
    container_name: kafka-kraft-1
    ports:
      - "19092:9092"
    environment:
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_LISTENERS: PLAINTEXT://kafka-1:9092,CONTROLLER://kafka-1:9093,INTERNAL://kafka-1:9094
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:19092,INTERNAL://kafka-1:9094
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,INTERNAL:PLAINTEXT
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka-1:9093,2@kafka-2:9093,3@kafka-3:9093
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      KAFKA_NUM_PARTITIONS: 1
      KAFKA_LOG_RETENTION_HOURS: 24
    networks:
      - kafka-net
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "./opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092 > /dev/null 2>&1",
        ]
      interval: 10s
      timeout: 10s
      retries: 5
    volumes:
      - kafka-data-1:/var/lib/kafka/data
  kafka-2:
    image: apache/kafka
    hostname: kafka-2
    container_name: kafka-kraft-2
    ports:
      - "29092:9092"
    environment:
      KAFKA_NODE_ID: 2
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_LISTENERS: PLAINTEXT://kafka-2:9092,CONTROLLER://kafka-2:9093,INTERNAL://kafka-2:9094
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:29092,INTERNAL://kafka-2:9094
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,INTERNAL:PLAINTEXT
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka-1:9093,2@kafka-2:9093,3@kafka-3:9093
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      KAFKA_NUM_PARTITIONS: 1
      KAFKA_LOG_RETENTION_HOURS: 24
    networks:
      - kafka-net
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "./opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092 > /dev/null 2>&1",
        ]
      interval: 10s
      timeout: 10s
      retries: 5
    volumes:
      - kafka-data-2:/var/lib/kafka/data
  kafka-3:
    image: apache/kafka
    hostname: kafka-3
    container_name: kafka-kraft-3
    ports:
      - "39092:9092"
    environment:
      KAFKA_NODE_ID: 3
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_LISTENERS: PLAINTEXT://kafka-3:9092,CONTROLLER://kafka-3:9093,INTERNAL://kafka-3:9094
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:39092,INTERNAL://kafka-3:9094
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,INTERNAL:PLAINTEXT
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka-1:9093,2@kafka-2:9093,3@kafka-3:9093
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      KAFKA_NUM_PARTITIONS: 1
      KAFKA_LOG_RETENTION_HOURS: 24
    networks:
      - kafka-net
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "./opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092 > /dev/null 2>&1",
        ]
      interval: 10s
      timeout: 10s
      retries: 5
    volumes:
      - kafka-data-3:/var/lib/kafka/data
  kafka-ui:
    image: provectuslabs/kafka-ui
    ports:
      - "8080:8080"
    restart: always
    environment:
      KAFKA_CLUSTERS_0_NAME: "kraft-cluster"
      KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka-1:9094,kafka-2:9094,kafka-3:9094
    depends_on:
      - kafka-1
      - kafka-2
      - kafka-3
    networks:
      - kafka-net
volumes:
  kafka-data-1:
  kafka-data-2:
  kafka-data-3:
networks:
  kafka-net:
    driver: bridge
💾 Mount Volumes
volumes:
  kafka-data-1:
  kafka-data-2:
  kafka-data-3:
🌐 Mạng dùng chung
networks:
  kafka-net:
    driver: bridge
5. Khởi Chạy Hệ Thống
docker-compose up -d
✅ Sau khi chạy, bạn có thể truy cập Kafka UI tại: http://localhost:8080
6. Tạo Topic Mới Trong Kafka
Khi tạo topic, chú ý đến:
| Thông số | Mô tả | 
|---|---|
| Topic name | Tên topic | 
| Number of partitions | Phân vùng (nhiều partition giúp parallelism tốt hơn) | 
| Replication factor | Số bản sao cho mỗi partition | 
| Min In Sync Replicas | Số replicas tối thiểu đang online khi ghi | 
| Cleanup policy | Xóa (delete), ghi đè (compact), hoặc kết hợp | 
| Retention.ms | Kafka sẽ xóa dữ liệu sau thời gian này | 
| Retention.bytes | Dung lượng tối đa được giữ | 
| Max message bytes | Kích thước tối đa của message | 
🧪 Ví dụ:
Tạo topic payment.response.dev để nhận kết quả trả về từ event thanh toán.
7. Gửi Message Test
Bắn một message vào topic payment.response.dev sử dụng broker-1 (localhost:19092), sau đó kiểm tra trên Kafka UI.
📸 Hình Ảnh Minh Họa
| Mô tả | Hình ảnh | 
|---|---|
| Container đã chạy |  | 
| Kafka UI |  | 
| Danh sách brokers |  | 
| Topic list |  | 
| Tạo topic mới |  | 
| Topic sau khi tạo |  | 
| Message trong topic |  | 
🔗 Tham Khảo
Sau khi hoàn thành mình đã bỏ vào chatgpt để gen markdown cho đẹp, anh em xem thì vui vẻ nhé  ))
))
All rights reserved
 
  
 