2. 消息队列选型与部署:Kafka核心概念与高可用实战
大家好,我是老张。今天咱们聊聊Kafka。
做实时数据管道,消息队列是绕不开的坎。市面上选择很多,RabbitMQ、Pulsar、RocketMQ……但我个人习惯,只要吞吐量要求高、日志类数据多,首选就是Kafka。为什么?说白了,它天生就是为海量数据设计的。
我记得刚入行那会儿,公司选型时争论了很久。后来压测一跑,Kafka的吞吐量是RabbitMQ的十几倍。嗯,从那以后,我就再也没换过。
2.1 Kafka核心概念:Topic、Partition、Consumer Group
这三个概念,你搞懂了,Kafka就入门了一半。
2.1.1 Topic(主题)
Topic就是数据的分类。好比一个快递站,不同区域的包裹放在不同的货架上。你发一条订单数据,就往“订单Topic”里扔;发一条日志,就往“日志Topic”里扔。
每个Topic可以有多个生产者往里写数据,也可以有多个消费者读数据。互不干扰。
2.1.2 Partition(分区)
这是Kafka实现高吞吐的关键。一个Topic会被拆成多个Partition,每个Partition是一个有序的、不可变的日志文件。
为什么要分区?你想想看,如果只有一个文件,所有数据都往里面写,那速度肯定慢。分区之后,多个生产者可以同时往不同分区写,消费者也可以并行读。吞吐量自然就上去了。
2.1.3 Consumer Group(消费者组)
这是Kafka最巧妙的设计之一。一个Consumer Group里的消费者,共同消费一个Topic的数据。每个Partition只能被组内的一个消费者消费。
举个例子:你有一个Topic有4个Partition,Consumer Group里有3个消费者。那就会有一个消费者消费2个Partition,另外两个各消费1个。如果消费者增加到4个,那就一人一个Partition。如果增加到5个,那就有一个人闲着。
session.timeout.ms 调大到30秒,配合 max.poll.interval.ms 控制,才稳定下来。
2.2 Kafka集群部署与配置
单机Kafka玩玩可以,生产环境必须上集群。我建议至少3台Broker起步。
2.2.1 基础架构
一个Kafka集群由多个Broker组成。每个Broker就是一台服务器。ZooKeeper(或KRaft模式)负责协调。
数据写入时,生产者指定Topic和Partition。Broker收到后,写入本地磁盘,并同步到副本。
2.2.2 关键配置参数
| 参数名 | 推荐值 | 说明 |
|---|---|---|
num.partitions |
3-10(根据吞吐量调整) | Topic默认分区数。我一般设6个起步 |
default.replication.factor |
3 | 副本数。3副本可以容忍1台Broker宕机 |
log.retention.hours |
168(7天) | 数据保留时间。根据磁盘容量调整 |
message.max.bytes |
10485760(10MB) | 单条消息最大大小。别设太大,否则网络压力大 |
log.retention.bytes 设得太小,结果数据频繁被删除,消费者追不上。后来我改成按时间保留,配合监控告警,才解决问题。
2.2.3 部署步骤(简化版)
# 1. 下载解压
wget https://downloads.apache.org/kafka/3.5.0/kafka_2.13-3.5.0.tgz
tar -xzf kafka_2.13-3.5.0.tgz
# 2. 修改配置 server.properties
# broker.id=1(每台机器不同)
# listeners=PLAINTEXT://0.0.0.0:9092
# advertised.listeners=PLAINTEXT://你的IP:9092
# log.dirs=/data/kafka/logs
# zookeeper.connect=zk1:2181,zk2:2181,zk3:2181
# 3. 启动
bin/kafka-server-start.sh config/server.properties &
嗯,这里要注意:advertised.listeners 一定要配成客户端能访问的IP。我见过有人配了localhost,结果远程客户端连不上,排查了半天。
2.3 Kafka高可用机制
Kafka的高可用,靠的是副本机制和ISR(In-Sync Replicas)。
2.3.1 副本机制
每个Partition可以有多个副本。其中一个叫Leader,负责读写。其他叫Follower,负责同步。
Leader挂了怎么办?Controller会从ISR里选一个新的Leader。ISR就是所有与Leader保持同步的副本列表。
acks 参数:
acks=0:不等待确认,最快但可能丢数据acks=1:Leader确认即可,中等可靠性acks=all:所有ISR副本都确认,最安全但最慢
acks=all,配合 min.insync.replicas=2,保证至少2个副本同步。
2.3.2 故障恢复流程
假设一个Partition有3个副本,Leader在Broker1上。Broker1突然宕机了。
- Controller检测到Broker1心跳超时
- Controller从ISR中选出一个新的Leader(比如Broker2上的副本)
- 生产者、消费者更新元数据,开始读写新Leader
- Broker1恢复后,作为Follower重新加入ISR
整个过程通常在几秒内完成。你想想看,如果业务能接受秒级中断,那Kafka的高可用完全够用。
unclean.leader.election.enable 设为true。这个参数允许非ISR副本成为Leader,虽然能快速恢复,但可能丢数据。除非你明确知道自己在做什么,否则别碰。
2.3.3 生产环境高可用 checklist
- Broker数量至少3台,分散在不同机架或可用区
- 副本因子设为3,
min.insync.replicas设为2 - 生产者设置
acks=all,重试次数适当(我一般设3次) - 消费者设置
enable.auto.commit=false,手动提交offset - 监控Broker的磁盘、网络、GC情况
我记得有一次,集群里一台Broker的磁盘快满了,导致写入性能急剧下降。还好监控告警及时,我赶紧扩容了磁盘。从那以后,我养成了每周检查磁盘使用率的习惯。
好了,Kafka的核心概念、部署和高可用机制就聊到这儿。下一章咱们讲讲Kafka的监控和调优,到时候我会分享一些压测数据,看看不同配置下性能到底差多少。
公众号:蓝海资料掘金营,微信deep3321