1. Kafka 简介
- Apache Kafka 是一个分布式流处理平台,由 LinkedIn 开发并于 2011 年开源,后成为 Apache 软件基金会的顶级项目。
- 核心概念
- Topic:主题,是消息分类的逻辑概念,生产者将消息发送到特定的 Topic,消费者从 Topic 中订阅消息。
- Partition:分区,每个 Topic 可以被划分为多个 Partition,每个 Partition 是一个有序的队列。
- Broker:Kafka 集群中的服务器节点,负责接收和存储消息。
- Producer:生产者,负责向 Kafka 发送消息。
- Consumer:消费者,负责从 Kafka 订阅并消费消息。
- Consumer Group:消费者组,同一组内的消费者互斥地消费消息,不同组的消费者可以同时消费同一消息。
- Offset:偏移量,每个消息都有一个唯一的偏移量,消费者通过该偏移量来消费消息。
- Controller:Kafka 集群中的一个特殊 Broker,负责管理协调集群状态,如分区的 Leader 选举、副本管理等。
- 主要功能:
- 消息传递:支持高吞吐量的消息发布和订阅。
- 存储:能够持久化存储大量的消息数据。
- 处理:支持实时数据流的处理。
- 特点:
- 高吞吐量:能够每秒处理数百万条消息。
- 可扩展性:支持水平扩展,通过增加更多的节点来提升性能。
- 容错性:设计为分布式系统,具有良好的容错机制。
2. 工作原理
2.1. Controller选举
- 作用:确保 Kafka 集群中有一个活跃的 Controller 节点,负责管理和协调集群中的各种操作,如分区的 Leader 选举、副本管理等。
- 实现方式:
- ZooKeeper 协调:Kafka 使用 ZooKeeper 来协调 Controller 的选举过程。
- 选举过程:
- 初始化:当 Kafka 集群启动时,所有 Broker 会尝试在 ZooKeeper 的 /controller 路径下创建一个临时节点。
- 竞争:由于 ZooKeeper 的特性,只能有一个 Broker 成功创建该临时节点,这个 Broker 就被选为 Controller。
- 通知:当选出 Controller 后,ZooKeeper 会通知其他 Broker,它们会更新内部状态,识别新的 Controller。
- 故障转移:如果当前的 Controller 节点失败,其他 Broker 会再次尝试创建 /controller 节点,从而选出新的 Controller。
2.2. Partition Leader 的选举
- 作用:确保每个 Partition 有一个活跃的 Leader,负责处理所有对该 Partition 的读写请求。
- 实现方式:
- Controller 负责:Controller 负责管理和执行 Partition Leader 的选举过程。
- 选举过程:
- AR (Assigned Replicas):所有分配给某个 Partition 的副本集合。
- ISR (In-Sync Replicas):与 Leader 保持同步的副本集合。
- OSR (Out-of-Sync Replicas):未能与 Leader 保持同步的副本集合。
- 选举条件:
- 正常情况:如果 Leader 正常运行,ISR 中的副本会继续同步数据。
- Leader 失败:如果 Leader 失败,Controller 会从 ISR 中选择一个新的 Leader。
- 选举算法:
- 选择新的 Leader:Controller 会选择 ISR 中 LEO(Log End Offset,即下一条待写入消息的偏移量)最高的副本作为新的 Leader。
- 更新 ISR:新的 Leader 选举后,Controller 会更新 ISR,移除无法同步的副本。
- 通知 Broker:Controller 会通知所有相关的 Broker 关于新的 Leader 信息,以便它们更新内部状态。
2.3. 消费者组中领导者的选举
- 作用:确保每个消费者组有一个领导者,负责协调组内成员的分区分配。
- 实现方式:
- Group Coordinator:每个消费者组都有一个 Group Coordinator,通常是 Kafka 集群中的一个 Broker。
- 选举过程:
- 心跳检测:消费者定期向 Group Coordinator 发送心跳,表明其活跃状态。
- 领导者选举:当 Group Coordinator 收到所有成员的心跳后,会选举一个消费者作为领导者。
- 分区分配:领导者负责将分区分配给组内的消费者,并将分配结果通知给 Group Coordinator。
- 通知成员:Group Coordinator 将分区分配结果通知给所有组成员。
3. 分区详解
分区(Partition)的主要作用:
- 逻辑划分:
- Topic 分区:每个 Topic 可以被划分为多个 Partition,每个 Partition 是一个有序的队列。
- 并行处理:通过将消息分散到多个 Partition 中,可以实现并行处理,提高系统的吞吐量。
- 顺序保证:
- 单个 Partition 内的顺序:在一个 Partition 内,消息是按顺序存储的,每个消息都有一个唯一的偏移量(Offset)。
- 全局顺序:如果需要全局顺序,可以通过将所有消息发送到同一个 Partition 来实现,但这会牺牲并行处理的能力。
- 负载均衡:
- 生产者负载均衡:生产者可以将消息均匀地分布到不同的 Partition 中,避免单个 Partition 过载。
- 消费者负载均衡:消费者可以并行地从不同的 Partition 中消费消息,提高消费速度。
- 数据冗余和容错:
- 副本机制:每个 Partition 可以有多个副本,分布在不同的 Broker 上,提高数据的可靠性和容错性。
- Leader 和 Follower:每个 Partition 有一个 Leader 和多个 Follower,生产者和消费者只与 Leader 交互,Follower 同步 Leader 的数据。
4. 副本复制过程
Kafka 的副本复制机制是为了确保数据的高可用性和可靠性。以下是 Kafka 副本复制的详细过程:
- 副本角色
- Leader 副本:每个 Partition 有一个 Leader 副本,负责处理所有读写请求。
- Follower 副本:每个 Partition 可以有多个 Follower 副本,从 Leader 副本同步数据。
- 副本同步过程
- 初始化
- 选举 Leader:当一个 Partition 被创建或 Leader 副本发生故障时,Kafka 的 Controller 会从 ISR(In-Sync Replicas)列表中选择一个新的 Leader。
- 通知 Broker:Controller 会通知所有相关的 Broker 关于新的 Leader 信息,以便它们更新内部状态。
- 数据同步
- Follower 发送 Fetch 请求:Follower 副本定期向 Leader 副本发送 Fetch 请求,请求最新的数据。
- Leader 返回数据:Leader 副本接收到 Fetch 请求后,返回最新的数据给 Follower 副本。
- Follower 存储数据:Follower 副本将接收到的数据存储到本地日志中。
- 同步确认
- Follower 发送 ACK:Follower 副本将数据成功写入本地日志后,向 Leader 副本发送 ACK 确认。
- Leader 更新 ISR:Leader 副本接收到 ACK 后,更新 ISR 列表,确保 Follower 副本与 Leader 副本保持同步。
- ISR 管理
- ISR 列表:ISR(In-Sync Replicas)列表包含与 Leader 副本保持同步的所有副本。
- 同步检查:Kafka 定期检查 Follower 副本的同步状态,如果某个 Follower 副本落后太多(超过 replica.lag.time.max.ms 配置的时间),则将其从 ISR 列表中移除。
- 重新加入 ISR:当 Follower 副本追赶上 Leader 副本后,可以重新加入 ISR 列表。
- 异常处理
- Leader 故障:如果 Leader 副本所在的 Broker 发生故障,Controller 会从 ISR 列表中选择一个新的 Leader。
- Follower 故障:如果 Follower 副本所在的 Broker 发生故障,Kafka 会等待其恢复或从其他 Follower 副本中选择新的副本进行同步。
- 初始化
5. 常见配置
- broker.id:Broker 的唯一标识符,用于在 ZooKeeper 中识别 Broker。
- num.network.threads
- 默认值:3
- 作用:指定 Kafka Broker 用于处理网络请求的线程数。这些线程负责与客户端进行通信,接收和发送消息。
- 配置建议::在高负载环境中,可以适当增加 num.network.threads 的值,以提高 Broker 的处理能力。
- num.io.threads
- 默认值:8
- 作用:指定 Kafka Broker 用于处理磁盘 I/O 操作的线程数。这些线程负责将消息从内存缓冲区写入磁盘。
- 配置建议:在高负载环境中,可以适当增加 num.io.threads 的值,以提高磁盘 I/O 的处理能力。
- socket.request.max.bytes
- 默认值:104857600(100 MB)
- 作用:指定单个网络请求的最大字节数。这个参数可以防止过大的请求导致 Broker 崩溃或性能下降。
- 配置建议:根据实际的业务需求和网络带宽,适当调整这个参数的值。
- message.max.bytes
- 默认值:1048588(1 MB)
- 作用:指定单个消息的最大字节数。这个参数可以防止过大的消息导致 Broker 崩溃或性能下降。
- 配置建议:根据实际的业务需求,适当调整这个参数的值。
- log.flush.interval.messages
- 默认值:10000
- 作用:指定在将消息从内存缓冲区刷入磁盘之前,累积的消息数。这个参数可以影响消息的持久性和性能。
- 配置建议:在高吞吐量环境中,可以适当增加这个值以提高性能,但会增加数据丢失的风险。
- log.flush.interval.ms
- 默认值:1000(1 秒)
- 作用:指定在将消息从内存缓冲区刷入磁盘之前,累积的时间间隔。这个参数可以影响消息的持久性和性能。
- 配置建议:在高吞吐量环境中,可以适当增加这个值以提高性能,但会增加数据丢失的风险。
- log.retention.hours
- 默认值:168(7 天)
- 作用:指定消息在日志中保留的时间。超过这个时间的消息会被删除。
- 配置建议:根据实际的业务需求和存储资源,适当调整这个参数的值。
- log.segment.bytes
- 默认值:1073741824(1 GB)
- 作用:指定日志段的大小。每个日志段是一个单独的文件,当达到这个大小时,会创建新的日志段。
- 配置建议:根据实际的业务需求和存储资源,适当调整这个参数的值。
- replica.fetcher.max.bytes
- 默认值:1048576(1 MB)
- 作用:设置从 Leader 副本获取数据的最大字节数。这个参数决定了 Follower 副本每次从 Leader 副本拉取数据的最大量。
- replica.fetch.response.max.bytes
- 默认值:10485760(10 MB)
- 作用:设置从 Leader 副本获取响应的最大字节数。这个参数决定了 Leader 副本返回给 Follower 副本的响应数据的最大量。
- fetch.purgatory.purge.interval.requests
- 默认值:10000
- 作用:设置清理 fetch 请求的间隔。这个参数决定了 Kafka Broker 清理未完成的 fetch 请求的频率。
6. 常用命令
6.1. 启动
./kafka-server-start.sh -daemon ./config/server.properties
6.2. 创建主题
–create: 指定创建新主题。
–topic : 指定要创建的主题名称。
–bootstrap-server : 指定 Kafka 集群的地址,例如 localhost:9092。
–partitions : 指定主题的分区数量。
–replication-factor : 指定主题的副本因子,即每个分区的副本数量(副本因子应小于或等于集群中的 broker 数量,否则会创建失败)
./kafka-topics.sh --create --topic --bootstrap-server --partitions --replication-factor
./kafka-topics.sh --create --topic quickstart-events --bootstrap-server localhost:9092
6.3. 查看主题信息
./kafka-topics.sh --describe --topic quickstart-events --bootstrap-server localhost:9092
6.4. 发布消息
./kafka-console-producer.sh --topic quickstart-events --bootstrap-server localhost:9092
6.5. 消费消息
#指定消费索引(从开始):–from-beginning
./kafka-console-consumer.sh --topic quickstart-events --from-beginning --bootstrap-server localhost:9092
6.6. 单播消费
#一条消息只能被某一个消费者消费的模式,类似queue模式,只需让所有的消费者在同一个消费组内即可:–consumer-property group.id=XXX
kafka-console-consumer.sh --topic quickstart-events --consumer-property group.id=testGroup --bootstrap-server localhost:9092
6.7. 多播消费
#通过将消费者放在不同的消费者组中,确保每个消息可以被多个消费者消费。这种方式适用于需要将消息广播给多个系统的场景