一、概述
Apache Kafka 是一款开源分布式流处理平台。可以用来发布和订阅数据以及对数据进行实时或者离线处理。
1、主要特点
- 高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒,每个topic可以分多个partition, consumer group 对partition进行consume操作;
- 扩展性强:支持分布式集群部署,且kafka集群支持热扩展;
- 持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失;
- 容错性强:允许集群中节点失败。(最多允许n-1个节点失败);
- 高并发:支持多个客户端同时读写;
- 支持实时在线处理和离线处理:可以使用storm实时流处理系统对消息进行实时处理,同时还支持hadoop这种批处理系统进行离线处理;
- 多客户端支持:比如java、golang等;
2、主要应用场景:
- 消息系统:常规的消息队列中间件,实现异步解耦、削峰等功能
- 日志收集:Kafka可以收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer,例如Hadoop、Hbase、Solr等;
- 数据监控:Kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告;
- 流式处理:比如spark streaming和storm;
- Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到Hadoop、数据仓库中做离线分析和挖掘;
二、基本概念
1、Broker
每个Broker即一个kafka服务实例,多个broker构成一个kafka集群。生产者发布的消息保存在broker中,消费者从broker获取消息进行消费。
在集群中,根据每个kafka实例担任的角色可分为leader(controller)和broker。
2、Topic
kafka中将消息分类,每一类消息称为一个Topic,生产者通过指定Topic将消息发送到broker中,消费者通过指定Topic可以针对不同的Topic采取不同的消费逻辑。Topic有点类似于数据库的表。
3、Partition
一个Topic可以分为多个Partition,每个Partition是一个有序队列,在Partition中每条消息都存在一个有序的偏移量offset代表这条消息在paitition中的位置。在一个Topic的多个partition中,分为leader和follower,只有leader进行读写操作,follower仅进行复制,客户端无法感知。
在一个集群中,同一个topic的不同partition可分布在不同的broker中,以保证数据安全可用。 图片来源:blog.csdn.net/m0_46109609...
4、Replica
为了保证数据安全,partition有多个副本,至少会有一个leader副本和多个follower副本。leader负责处理客户端的读写请求,follower副本只复制leader副本的数据。当leader宕机时,follower会自动接替leader副本的工作,从而保证数据的可用性。
5、Producer
生产者,负责生产消息,并发送到broker。
6、Consumer
消费者,负责消费broker中topic消息,每个consumer归属于一个consumer group。
7、各组成部分关系图
三、关键性版本变更
在kafka版本2.8以前,kafka集群通过zookeeper进行集群管理,从2.8.0版本开始,kafka提供了另一种管理模式:KRaft。
1、KRaft模式简介
KRaft 是 "Kafka" 和 "Raft" 的组合词,其中 Raft 是一个用于管理复制日志的分布式一致性算法。在 KRaft 模式中,Kafka 使用 Raft 协议来实现集群的元数据管理,包括主题配置、分区副本分配、访问控制列表等。
在 KRaft 模式下,Kafka 集群中的一个或多个 broker 将被指定为 controller,它们负责管理集群的元数据。当一个 controller 出现故障时,其他的 broker 可以通过 Raft 协议的领导者选举机制来选举出一个新的 controller。
它使得 Kafka 能够在没有 Apache ZooKeeper 的情况下运行。KRaft 模式的主要目标是简化 Kafka 的架构,提高其性能和稳定性。
2、两种模式对比
2.1 架构复杂度及性能
zookeeper模式:部署kafka集群时,必然要部署对应的zookeeper集群,既增加了系统的复杂性,同时也需要对zookeeper进行维护。kafka的性能不仅受到本身资源的限制,也受到zookeeper本身的限制以及kafka与zookeeper通信之间的限制。
KRaft模式:KRaft模式消除了kafka集群对zookeeper的依赖,降低了kafka部署及维护的难度;同时也消除了因zookeeper本身限制、通信方面的瓶颈以及由于引入zookeeper带来的系统风险,提高了kafka集群的性能和稳定性。
2.2 leader选举
在 Kafka 集群中,Controller 是一个非常重要的角色。Kafka 集群会选举出一个 Broker 作为 Controller,这个 Controller 主要负责管理和协调整个 Kafka 集群中的分区和副本。
- 分区 Leader 的选举:当某个分区的 Leader 副本发生故障时,Controller 负责从该分区的 Follower 副本中选举出一个新的 Leader。
- 副本状态的管理:Controller 负责跟踪所有副本的状态,并在副本状态发生变化时进行相应的处理。例如,当一个新的副本加入到集群时,Controller 会将其状态设置为 "ReplicaOnline"。
- Topic 和分区的管理:当创建或删除 Topic 时,Controller 负责在各个 Broker 上创建或删除相应的分区。
- Broker 状态的监控:Controller 会持续监控集群中所有 Broker 的状态。当某个 Broker 发生故障时,Controller 会将其上的所有 Leader 分区迁移到其他健康的 Broker 上。
- 集群元数据的维护:Controller 负责维护 Kafka 集群的元数据,包括 Topic 配置、分区副本分配、访问控制列表等。
zookeeper模式:在zookeeper模式中,kafka的leader由zookeeper自行选举,用户无法指定。
KRaft模式: 在KRaft模式中,可以通过配置文件直接指定broker节点的角色(controller、broker),也可以由集群自己完成。
四、docker-compose部署Kraft模式集群
1、版本对齐
docker版本
:24.0.4
docker-compose版本
: 2.20.2
kafka镜像版本
:bitnami/kafka:3.6
2、创建kafka集群网络并取kafka镜像
shell
docker network create kafka-net
docker pull bitnami/kafka:3.6
3、docker-compsoe.yaml文件
本文主要目的是为了学习,所以是把配置项都写到了docker-compose文件中。个人觉得在实际的环境中,还是通过为挂载数据卷的方式,将配置项写在配置文件中。
yaml
version: "3"
services:
kafka1:
image: docker.io/bitnami/kafka:3.6
container_name: kafka1
restart: always
ports:
- 19092:9092
- 19093:9093
volumes:
- "/home/xxx/workspace/kafka-docker/kafka1/data:/bitnami/data"
privileged: true
environment:
#是否使用KRaft模式
KAFKA_ENABLE_KRAFT: yes
KAFKA_CFG_PROCESS_ROLES: broker,controller
KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_CFG_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_KRAFT_CLUSTER_ID: VaW86rUCTMmoxIcDiER_lA
KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
ALLOW_PLAINTEXT_LISTENER: yes
KAFKA_HEAP_OPTS: -Xmx512M -Xms256M
KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: true
#broker单独配置
KAFKA_CFG_NODE_ID: 1
KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://192.168.94.128:19092
kafka2:
image: docker.io/bitnami/kafka:3.6
container_name: kafka2
restart: always
ports:
- 29092:9092
- 29093:9093
volumes:
- "/home/xxx/workspace/kafka-docker/kafka2/data:/bitnami/data"
privileged: true
environment:
KAFKA_ENABLE_KRAFT: yes
KAFKA_CFG_PROCESS_ROLES: broker,controller
KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_CFG_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_KRAFT_CLUSTER_ID: VaW86rUCTMmoxIcDiER_lA
KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
ALLOW_PLAINTEXT_LISTENER: yes
KAFKA_HEAP_OPTS: -Xmx512M -Xms256M
KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: true
#broker单独配置
KAFKA_CFG_NODE_ID: 2
KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://192.168.94.128:29092
kafka3:
image: docker.io/bitnami/kafka:3.6
container_name: kafka3
restart: always
ports:
- 39092:9092
- 39093:9093
volumes:
- "/home/xxx/workspace/kafka-docker/kafka3/data:/bitnami/data"
privileged: true
environment:
KAFKA_ENABLE_KRAFT: yes
KAFKA_CFG_PROCESS_ROLES: broker,controller
KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_CFG_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_KRAFT_CLUSTER_ID: VaW86rUCTMmoxIcDiER_lA
KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
ALLOW_PLAINTEXT_LISTENER: yes
KAFKA_HEAP_OPTS: -Xmx512M -Xms256M
KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: true
#broker单独配置
KAFKA_CFG_NODE_ID: 3
KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://192.168.94.128:39092
networks:
default:
external: true
name: kafka-net
4、参数解析
KAFKA_ENABLE_KRAFT
: 使用Kraft模式KAFKA_CFG_PROCESS_ROLES
:指定服务器在KRaft模式下的角色。broker(处理客户端请求及管理分区副本)、controller(只管理集群及协调选举)。两个角色可以同时兼任;KAFKA_CFG_CONTROLLER_QUORUM_VOTERS
:在raft模式下,参与选举和和决策的控制器节点<brockerID>@<hostname>:<port>
格式,多个以,
分割;KAFKA_CFG_LISTENERS
:指定了 Kafka 绑定的监听器列表和主机/IP和端口。监听器是 Kafka 用来和客户端或其他 broker 通信的网络接口。KAFKA_CFG_LISTENERS 的格式是一个由逗号分隔的<name>://<host>:<port>
对,其中<name>
是一个任意的标识符,<host>
是主机名或 IP 地址,<port>
是端口号。<name>
常用协议名称;KAFKA_CFG_ADVERTISED_LISTENERS
:它指定了 Kafka 代理向客户端或其他代理公开的监听器列表,包括它们的主机/IP和端口。这些监听器是客户端或其他代理用来连接到 Kafka 代理的地址;KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP
:定义了每个监听器名称要使用的安全协议的键/值对。监听器是 Kafka 用来和客户端或其他 broker 通信的网络接口,每个监听器由主机/IP、端口和协议组成。安全协议是指通信时使用的加密方式,如 PLAINTEXT、SSL、SASL_PLAINTEXT 等;KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP
的格式是一个由逗号分隔的<name>:<protocol>
对,其中<name>
是一个任意的标识符,<protocol>
是一个支持的安全协议;KAFKA_KRAFT_CLUSTER_ID
:集群唯一uuid,可以通过bin/kafka-storage.sh random-uuid
工具命令生成;KAFKA_CFG_CONTROLLER_QUORUM_VOTERS
:kafka参与选举的broker名称及地址;KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE
:是否自动创建topic;KAFKA_CFG_NODE_ID
:kraft模式下节点id,从1开始,不重复;ALLOW_PLAINTEXT_LISTENER
:控制 Kafka 是否允许使用 PLAINTEXT 侦听器。PLAINTEXT 侦听器是指没有加密和认证的通信方式,这在生产环境中是不安全的,所以默认情况下是不允许的。如果你想在开发或测试环境中使用 PLAINTEXT 侦听器。KAFKA_HEAP_OPTS
:用来设置 Kafka 的堆内存大小。堆内存是 JVM 用来存储对象的内存区域,它影响着 Kafka 的性能和稳定性。KAFKA_HEAP_OPTS
的格式是-Xmx<size> -Xms<size>
.
5、kafka自带工具命令行操作
在docker容器中,kafka相关工具的可执行文件bin目录在/opt/bitnami/kafka/bin
目录 以下展示两个简单操作,因为更多的时候我们还是通过对应语言客户端进行对kafka的操作,此处仅作示例,更多操作可查询操作文档。地址:kafka.apachecn.org/documentati...
进入容器,切到kafka的bin目录下
创建topic
shell
kafka-topics.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --create --topic my_topic_name --partitions 20 --replication-factor 3 --config x=y
查看所有的topic
shell
kafka-topics.sh --list --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092
6、kafka-ui 一款kafka web管理界面工具(可选)
docker-compose.yaml文件
yaml
version: "3"
services:
kafka-ui:
image: provectuslabs/kafka-ui:latest
network_mode: kafka-net
container_name: kafka-ui
restart: always
ports:
- 19091:8080
volumes:
- /home/xxx/workspace/kafka-docker/kafka-ui:/etc/localtime
environment:
# 集群名称
- KAFKA_CLUSTERS_0_NAME=local
# 集群地址
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka1:9092,kafka2:9092,kafka3:9092
运行容器,进入页面单击Brokers,可看到当前集群信息
至此,docker-compose部署kafka集群已完成。
五、参考资料
官方文档:
kafka.apachecn.org/documentati...
巨人的肩膀:
blog.csdn.net/u014609111/...
www.cnblogs.com/snow-man/p/...
cloud.tencent.com/developer/a...
新手入门,记录收藏,如有错误,敬请指正