Kafka学习日记

34 阅读3分钟

介绍

能做什么? 1.消息队列 2.构建实时流式应用程序,对这些流数据进行转换或者影响。

kafka:

  1. client:
    1. producer:可以把数据发布到选择的topic的那一个partition,具体哪一个看具体策略(比如可以通过循环的方式)
    2. consumer group:一个partition只能对应组内的一个消费者
      1. consumer:保存消费分区的offset
  2. server:
    1. 多个broker: 每个broker下都有订阅的topic
    2. topic:
      1. 多个partition:每个partition都有一个offset,允许扩展partition,也就是增加分区数量; 每个分区都有个server作为leader,若干个followers

约定

  • 生产者发送到特定topic partition 的消息将按照发送的顺序处理。 也就是说,如果记录M1和记录M2由相同的生产者发送,并先发送M1记录,那么M1的偏移比M2小,并在日志中较早出现
  • 一个消费者实例按照日志中的顺序查看记录.
  • 对于具有N个副本的主题,我们最多容忍N-1个服务器故障,从而保证不会丢失任何提交到日志中的记录.

使用

用docker管理Kraft版本的kafka

配置

docker-compose.yaml 配置过程中出现了些bug

  1. ❌ 监听器配置错误:缺少 KAFKA_CONTROLLER_LISTENER_NAMES 环境变量
  1. ❌ 广播地址配置不当:使用了宿主机IP而不是容器名

下面是正确的配置

version: '3'
services:
  kafka1:
    image: apache/kafka:4.0.0
    container_name: kafka-node1
    environment:
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT"
      KAFKA_NODE_ID: 1
      CLUSTER_ID: "kafka-cluster"               # 集群所有节点必须相同
      KAFKA_PROCESS_ROLES: broker,controller    # 同时承担Broker和Controller角色
      KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-node1:9092  # 使用容器名而不是宿主机IP
      KAFKA_CONTROLLER_QUORUM_VOTERS: "1@kafka-node1:9093,2@kafka-node2:9093,3@kafka-node3:9093"  # 所有Controller节点
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
    ports:
      - "19092:9092"  # Broker端口
      - "19093:9093"  # Controller选举端口
    volumes:
      - ./node1/data:/var/lib/kafka/data        # 节点数据独立存储

  kafka2:
    image: apache/kafka:4.0.0
    container_name: kafka-node2
    environment:
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT"
      KAFKA_NODE_ID: 2
      CLUSTER_ID: "kafka-cluster"
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-node2:9092  # 使用容器名而不是宿主机IP
      KAFKA_CONTROLLER_QUORUM_VOTERS: "1@kafka-node1:9093,2@kafka-node2:9093,3@kafka-node3:9093"
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
    ports:
      - "29092:9092"
      - "29093:9093"
    volumes:
      - ./node2/data:/var/lib/kafka/data

  kafka3:
    image: apache/kafka:4.0.0
    container_name: kafka-node3
    environment:
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT"
      KAFKA_NODE_ID: 3
      CLUSTER_ID: "kafka-cluster"
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-node3:9092  # 使用容器名而不是宿主机IP
      KAFKA_CONTROLLER_QUORUM_VOTERS: "1@kafka-node1:9093,2@kafka-node2:9093,3@kafka-node3:9093"
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
    ports:
      - "39092:9092"
      - "39093:9093"
    volumes:
      - ./node3/data:/var/lib/kafka/data

networks:
  default:
    name: kafka-net  # 自定义网络确保容器互通

生产者和消费者

生产者

docker exec -it kafka-node1 /opt/kafka/bin/kafka-console-producer.sh \
  --bootstrap-server kafka-node1:9092 \
  --topic test-topic

消费者

docker exec -it kafka-node1 /opt/kafka/bin/kafka-console-consumer.sh \
  --bootstrap-server kafka-node1:9092 \
  --topic test-topic --from-beginning

生产者吞吐量测试

docker exec -it kafka-node1 /opt/kafka/bin/kafka-producer-perf-test.sh \
  --topic test-topic \
  --num-records 1000000 \
  --record-size 1000 \
  --throughput 50000 \
  --producer-props bootstrap.servers=kafka-node1:9092

消费者吞吐量测试

docker exec -it kafka-node3 /opt/kafka/bin/kafka-consumer-perf-test.sh \
  --bootstrap-server kafka-node3:9092 \
  --topic test-topic \
  --messages 1000000