Triển khai Kafka bằng Docker

Kafka là một hệ thống nhắn tin phân tán mạnh mẽ, thường được sử dụng cho các ứng dụng truyền dữ liệu thời gian thực. Việc triển khai Kafka có thể trở nên phức tạp, nhưng Docker cung cấp một giải pháp hiệu quả để đơn giản hóa quá trình này.

Các Khái Niệm Cơ Bản Của Kafka

  • Producer (Nhà sản xuất): Ứng dụng gửi dữ liệu (tin nhắn) đến Kafka.
  • Consumer (Người tiêu dùng): Ứng dụng đọc dữ liệu từ Kafka. Mỗi consumer thuộc về một consumer group. Trong một topic, một tin nhắn chỉ được tiêu thụ bởi một consumer duy nhất trong cùng một consumer group, nhưng nhiều consumer group khác nhau có thể cùng đọc một tin nhắn.
  • Cluster (Cụm): Một tập hợp các máy chủ Kafka (Broker) hoạt động cùng nhau.
  • Broker: Một máy chủ Kafka trong cụm, chịu trách nhiệm lưu trữ các tin nhắn đã được publish.
  • Topic: Một danh mục hoặc tên luồng mà các tin nhắn được gửi và đọc. Topic giúp phân loại dữ liệu, ví dụ, tất cả log liên quan đến dịch vụ A có thể được định nghĩa trong topic 'service-a'. Về mặt vật lý, dữ liệu của các topic khác nhau được lưu trữ riêng biệt trên các Broker, nhưng về mặt logic, người dùng chỉ cần quan tâm đến tên topic để gửi hoặc nhận dữ liệu.
  • Partition (Phân vùng): Mỗi topic được chia thành một hoặc nhiều phân vùng. Đây là đơn vị lưu trữ cơ bản của Kafka. Mỗi phân vùng tương ứng với một thư mục trên Broker, chứa tất cả tin nhắn và chỉ mục của nó. Kafka sử dụng một thuật toán để xác định phân vùng nào sẽ lưu trữ một tin nhắn cụ thể, giúp việc đọc dữ liệu có độ phức tạp O(1). Mỗi tin nhắn trong một phân vùng có một số thứ tự liên tục gọi là offset, giúp định danh duy nhất tin nhắn đó trong phân vùng.
  • Segment: Một phân vùng bao gồm nhiều segment. Mỗi segment là một tệp tin trong thư mục của phân vùng. Kích thước của segment được giới hạn bởi cấu hình log.segment.bytes.

Triển Khai Bằng Docker

Sử dụng Docker Compose là cách tiếp cận phổ biến để thiết lập môi trường Kafka.

Tệp Docker Compose (docker-compose.yml)

version: '2'
services:
  zookeeper:
    image: wurstmeister/zookeeper
    ports:
      - "2181:2181"
  kafka:
    image: wurstmeister/kafka
    depends_on:
      - zookeeper
    ports:
      - "9092"
    environment:
      KAFKA_ADVERTISED_HOST_NAME: 192.168.1.100 # Thay thế bằng IP thực tế của máy host
      KAFKA_CREATE_TOPICS: "app-logs:1:1" # Tự động tạo topic 'app-logs' với 1 partition và 1 replica
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "false" # Vô hiệu hóa tự động tạo topic
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
  kafka-ui: # Một công cụ quản lý giao diện web cho Kafka
    image: provectuslabs/kafka-ui
    depends_on:
      - zookeeper
      - kafka
    ports:
      - "8080:8080"
    environment:
      SERVER_PORT: 8080
      KAFKA_CLUSTERS_0_NAME: local
      KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:9092
      KAFKA_CLUSTERS_0_ZOOKEEPERCONNECT: zookeeper:2181

Lưu ý: Thay thế 192.168.1.100 bằng địa chỉ IP thực tế của máy host mà các container Docker có thể truy cập được. Cấu hình KAFKA_ADVERTISED_HOST_NAME là rất quan trọng để các client kết nối đúng.

Các Lệnh Docker Compose

# Khởi chạy các dịch vụ theo cấu hình docker-compose.yml
docker-compose up -d

# Mở rộng số lượng Kafka broker (ví dụ: lên 3)
docker-compose scale kafka=3

# Dừng tất cả các container
docker-compose stop

# Khởi động lại tất cả các container đã dừng
docker-compose start

# Xóa tất cả các container, network và volume được tạo bởi compose
docker-compose down -v

Các Lệnh Kafka CLI

Các công cụ dòng lệnh này thường có sẵn trong các image Kafka.

kafka-console-consumer.sh

Sử dụng để đọc tin nhắn từ một topic.

kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic app-logs

kafka-console-producer.sh

Sử dụng để gửi tin nhắn thủ công đến một topic.

kafka-console-producer.sh --broker-list localhost:9092 --topic app-logs
# Sau đó nhập tin nhắn và nhấn Enter

kafka-consumer-groups.sh

Quản lý và xem thông tin về các consumer group.

# Liệt kê tất cả các consumer group
kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list

# Mô tả chi tiết một consumer group cụ thể
kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group my-consumer-group

kafka-producer-perf-test.sh

Công cụ kiểm tra hiệu năng cho producer.

kafka-producer-perf-test.sh --topic app-logs --num-records 10000 --record-size 1024 --throughput 1000 --producer-props bootstrap.servers=localhost:9092

kafka-topics.sh

Quản lý các topic trong Kafka.

# Liệt kê tất cả các topic
# Lưu ý: Cần kết nối tới Zookeeper để liệt kê topic khi dùng Zookeeper
kafka-topics.sh --bootstrap-server localhost:9092 --list

# Mô tả chi tiết một topic
kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic app-logs

Xử Lý Sự Cố

  • Lỗi "UNKNOWN_TOPIC_OR_PARTITION" khi producer/consumer khởi động trong container: Thường do cấu hình KAFKA_ADVERTISED_HOST_NAME trong docker-compose.yml không chính xác, khiến các client không thể kết nối đến Broker. Hãy đảm bảo IP được cung cấp là IP mà các client có thể tiếp cận được từ bên ngoài container.

Thẻ: kafka docker docker-compose message-queue distributed-systems

Đăng vào ngày 3 tháng 7 lúc 13:23