介绍
能做什么? 1.消息队列 2.构建实时流式应用程序,对这些流数据进行转换或者影响。
kafka:
- client:
- producer:可以把数据发布到选择的topic的那一个partition,具体哪一个看具体策略(比如可以通过循环的方式)
- consumer group:一个partition只能对应组内的一个消费者
- consumer:保存消费分区的offset
- server:
- 多个broker: 每个broker下都有订阅的topic
- topic:
-
多个partition:每个partition都有一个offset,允许扩展partition,也就是增加分区数量; 每个分区都有个server作为leader,若干个followers
-
约定
- 生产者发送到特定topic partition 的消息将按照发送的顺序处理。 也就是说,如果记录M1和记录M2由相同的生产者发送,并先发送M1记录,那么M1的偏移比M2小,并在日志中较早出现
- 一个消费者实例按照日志中的顺序查看记录.
- 对于具有N个副本的主题,我们最多容忍N-1个服务器故障,从而保证不会丢失任何提交到日志中的记录.
使用
用docker管理Kraft版本的kafka
配置
docker-compose.yaml 配置过程中出现了些bug
- ❌ 监听器配置错误:缺少 KAFKA_CONTROLLER_LISTENER_NAMES 环境变量
- ❌ 广播地址配置不当:使用了宿主机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