08 kafka
1 Kafka概述
1.1 定义
● 基于发布/订阅模式的消息队列(Message Queue)—— 传统
● 分布式事件流平台(event streaming platform)—— 最新定位
1.2 消息队列
1.2.1 传统消息队列的应用场景
1)引用场景
2)使用消息队列的好处
解耦
● 允许独立的扩展、修改两边的处理过程。
可恢复性
● 部分组件失效,不影响整体系统。
缓冲
● 有助于控制和优化数据流经过系统的速度
● 解决生产消息和消费消息的处理速度不一致的情况
灵活性和峰值处理能力
● 使用消息队列能够使关键组件顶住突发的访问压力。
异步通信
● 用户把消息放入队列,并表示不想立即处理。
1.2.2 消息队列的两种模式
1)点对点模式(一对一)
● 消费者主动拉去数据,用后消除
● 一个消息只有一个消费者使用(Queue支持存在多个消费者)
2)发布/订阅模式(一对多)
● 优点:发布到topic的消息会被所有的订阅者消费
● 缺点:不断轮询,看看消息出来没(自助烧烤)
1.3 Kafka基础架构
Producer | 消息生产者 |
Consumer | 消息消费者 |
Consumer Group | 消费组 |
Broker | kafka服务器=broker, broker可以容纳多个topic |
Topic | 队列(先这样理解),生产者和消费者面向的都是一个topic |
Partition | 有序的队列 (一个topic可分布到多个broker上,一个topic可以分为多个parition) |
Replication | 副本 |
leader | ”主“,(读写) |
follower | ”从“,(同步数据),实时与leader副本保持同步 |
2 Kafka快速入门
2.1 安装部署
集群规划——Kafka下载
2.1.2 集群部署
解压——修改文件名——修改配置文件——配置环境变量——分发环境变量——分发安装包——修改brokerid——启动集群——关闭集群
配置文件修改内容
[atguigu@hadoop102 kafka]$ cd config/
[atguigu@hadoop102 config]$ vim server.properties
# broker的全局唯一编号,不能重复
broker.id=102
# 删除topic功能使能,当前版本此配置默认为true,已从配置文件移除
delete.topic.enable=true
# 处理网络请求的线程数量
num.network.threads=3
# 用来处理磁盘IO的线程数量
num.io.threads=8
# 发送套接字的缓冲区大小
socket.send.buffer.bytes=102400
# 接收套接字的缓冲区大小
socket.receive.buffer.bytes=102400
# 请求套接字的缓冲区大小(100M)
socket.request.max.bytes=104857600
# kafka运行日志(数据)存放的路径
log.dirs=/opt/module/kafka/datas
# topic在当前broker上的分区个数
num.partitions=1
# 启动时用于日志恢复和关闭时用于刷新的每个数据目录的线程数量
num.recovery.threads.per.data.dir=1
# segment文件保留的最长时间,超时将被删除
log.retention.hours=168
# 配置连接Zookeeper集群地址
zookeeper.connect=hadoop102:2181,hadoop103:2181,hadoop104:2181/kafka
启动kafka集群 | bin/kafka-server-start.sh -daemon config/server.properties |
关闭kafka集群 | bin/kafka-server-stop.sh |
-daemon | daemon又称为守护进程,后台运行。 |
2.1.4 群起脚本
1)脚本编写
查看代码
#! /bin/bash
if (($#==0)); then
echo -e "请输入参数:\n start 启动kafka集群;\n stop 停止kafka集群;\n" && exit
fi
case $1 in
"start")
for host in hadoop103 hadoop102 hadoop104
do
echo "---------- $1 $host 的kafka ----------"
ssh $host "/opt/module/kafka/bin/kafka-server-start.sh -daemon /opt/module/kafka/config/server.properties"
done
;;
"stop")
for host in hadoop103 hadoop102 hadoop104
do
echo "---------- $1 $host 的kafka ----------"
ssh $host "/opt/module/kafka/bin/kafka-server-stop.sh /opt/module/kafka/config/server.properties"
done
;;
*)
echo -e "---------- 请输入正确的参数 ----------\n"
echo -e "start 启动kafka集群;\n stop 停止kafka集群;\n" && exit
;;
esac
2)脚本文件添加权限
[atguigu@hadoop102 bin]$ chmod +x kafka.sh
2.2 Kafka命令行操作
2.2.1 Topic相关命令操作
查看所有topic | bin/kafka-topics.sh --bootstrap-server hadoop102:9092 --list |
创建topic | bin/kafka-topics.sh --bootstrap-server hadoop:9092 --create --replication-factor 2 --partitions 1 --topic first |
--bootstrap-server 指定broker节点(一个或多个) | |
--topic 定义topic名 | |
--replication-factor 定义副本数 | |
--partitions 定义分区数 | |
删除topic | bin/kafka-topics.sh --bootstrap-server hadoop102:9092 --delete --topic first |
查看topic详情 | bin/kafka-topics.sh --bootstrap-server hadoop102:9092 --describe --topic first |
修改分区数 | bin/kafka-topics.sh --bootstrap-server hadoop102:9092 --alter --topic first --partitions 3 |
注意:
● 副本数不可以修改
● 如果修改分区数,分区数只能增加,不能减少。
2.2.2 消息的生产和消费
生产消息 | bin/kafka-console-producer.sh --broker-list hadoop102:9092 --topic first |
--broker-list 指定集群地址 | |
消费消息 | bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic first |
bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --from-beginning --topic first | |
--from-beginning 会把主题中现有的所有的数据读取出来 (从offset为0开始消费) | |
指定消费组组 | bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --from-beginning --group t1 --topic first |
查看消费组记录 | ./kafka-consumer-groups.sh --all-groups --all-topics --describe --bootstrap-server hadoop102:9092 |
3 Kafka架构深入
3.1 Kafka工作流程及文件存储机制
① Kafka消息分类——topic
② topic下的每一个分区都单独维护一组offset,所以分发到不同分区中的数据都是有序的。
③ 消费者消费消息的同时,还维护着消息的offset:一个消费者一个主题的一个分区维护一个offset。
④ topic — 逻辑概念 partition — 物理概念
⑤ 每个partition逻辑上对应一个log文件(存储producer生产的数据,追加形式,每条数据都有自己的offset)。
⑥ 消费组中的每个消费组,都会实时记录自己消费到了哪个offset(当出错然后又恢复时,就可从上次的位置继续消费)。
注意:
如果新来的一个消费组,来拉取数据,就从原来的offser+1的位置开始
由于生产的消息会不断追加到 log 文件末尾,当log文件数量过大时,数据定位效率低下,怎么办?
Kafka采取了分片和索引机制:
● 将每个partition分为多个segment。
● 每个segment对应两个文件 —— ".index"文件和".log"文件
3.1 Kafka工作流程及文件存储机制
3.2 Kafka生产者
3.2.1 消息发送流程
Producer发送消息方式:异步发送
两线一变
● main线程:(发)将消息发送给RecordAccumulator。
● Sender线程:(拉)不断从RecordAccumulator中拉取消息发送到Kafka broker
● RecordAccumulator线程共享变量
相关参数:
batch.size:数据累计到batch.size时,sender才会发送数据
linger.ms:如数据迟迟未达到batch.size,sender等待liger.time之后就会发送数据
3.2.2 异步发送API
3.2.3 同步发送API
3.2.4 分区策略
1)分区的原因
① 方便在集群中扩展
② 可提高并发
2)分区的原则
我们需要将producer发送的数据封装成一个ProducerRecord对象
① ProducerRecord(topic,partition_num,……) 有partition
直接发往指定的分区
② ProducerRecord(topic,key,value) 无partition,有key
key的hash值 % topic的partition数 取余得到partition的值
③ ProducerRecord(topic,value) 无partition,无key
采用黏性分区器,会随机选择一个分区,并尽可能一直使用该分区
待该分区的batch已满或已完成
kafk再随机一个分区进行使用
3.2.5 分区器
3.2.6 数据可靠性保证
1)生产者发送数据到 topic partition 的可靠性保证
① producer发送数据 → topic中的partition
② topic中的partition发送ack → producer
③ producer收到ack,进行下一轮的发送,否则重新发送
2)Topic partition存储数据的可靠性保证
分区分配策略
测试一:
topic first有三个分区 first0 first1 first2
消费者组 group01 consumer01 — c1 consumer02 — c2 consumer03 — c3
① 只启动消费者c1
分区消费情况 c1 - first2、first1、first0 【一个消费者消费三个分区】
② c1已启动的情况下,再启动 c2
分区消费情况 c1 - first1、first0 c2 - first2
消费者端的分区分配是什么时候开始分的呢? 消费者组内有新的消费者加入,就会触发
③ c1、c2已启动的情况下,再启动c3
分区消费情况 c1 - first1 c2 - first2 c3 - first0
③ c1、c2、c3已启动的情况下,再启动c4
分区消费情况 c1 - first1 c2 - first2 c3 - first0 c4 - 无 【此时碰巧每分配到,一般情况下会打乱,重分配】
④ c1、c2、c3、c4已启动的情况下,退出c1
分区消费情况 c2 - first1 c3 - first0 c4 - first2
(改)消费者端的分区分配是什么时候开始分的呢? 消费者组内消费者发生变化(增加、减少),就会触发分区重分配
------------------------------------------------------------------------------------------------------------------------------------------------------
测试二: 分区策略使用Range
topic first有七个分区 first0 first1 first2 first3 irst4 first5 first6
消费者组 group02 consumer1 — c1 consumer2 — c2 consumer3 — c3
① 启动c1
分区消费情况 c1 - first0 first1 first2 first3 irst4 first5 first6
② 已启动c1,再启动c2
分区消费情况 c1 - first3 first2 first1 first0 c2 -first5 irst4 first6
③ 已启动c1、c2,再启动c3
分区消费情况 c1 - first2 first1 first0 c2 -first5 first6 c3 -first3 irst4
④ 已启动c1、c2、c3,关闭c1 【会重新分配】
分区消费情况 c2 -first5 irst4 first6 c3 - first3 first2 first1 first0
------------------------------------------------------------------------------------------------------------------------------------------------------
测试三: 分区策略使用RoundRobin(轮询)
topic first有七个分区 first0 first1 first2 first3 irst4 first5 first6
消费者组 group03 consumer1 — c1 consumer2 — c2 consumer3 — c3
① 启动c1
分区消费情况 c1 - first0 first1 first2 first3 irst4 first5 first6
② 已启动c1,再启动c2 【会重新分配】
分区消费情况 c1 - first2 first4 first6 first0 c2 -first3 irst5 first1
③ 已启动c1、c2,再启动c3 【会重新分配】
分区消费情况 c1 - first3 first6 first0 c2 -first4 first1 c3 -first2 irst5
④ 已启动c1、c2、c3,关闭c1 【会重新分配】
分区消费情况 c2 -first2 irst4 first6 first0 c3 - first3 first5 first1
------------------------------------------------------------------------------------------------------------------------------------------------------
测试三: 分区策略使用Sticky(黏性分区) 减少了消费者退出的时候,分区的切换
topic first有七个分区 first0 first1 first2 first3 irst4 first5 first6
消费者组 group03 consumer1 — c1 consumer2 — c2 consumer3 — c3
① 启动c1
分区消费情况 c1 - first0 first1 first2 first3 irst4 first5 first6
② 已启动c1,再启动c2
分区消费情况 c1 - first4 first6 first1 first0 c2 -first3 irst2 first5
③ 已启动c1、c2,再启动c3
分区消费情况 c1 - first6 first1 first0 c2 -first2 first5 c3 -first3 first4
④ 已启动c1、c2、c3,关闭c1 【会将牺牲的c1的消费分区,分给c2、c3,且c2、c3原来消费的分区不会变动】
分区消费情况 c2 -first2 irst5 first1 c3 - first3 first4 first6 first0
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南