Kafka
有broker重topic的高性能消息队列
💡在重topic的消息队列⾥必然需要topic的存在
消息队列的作用:解决通信问题
#环境准备
1.安装zk
官网下载,这里以3.4.14版本为例,由于是老版本,所以需要在链接中找到这句话:Older releases are available in the archive
.
💡有时候找老版本很麻烦,其实很多都能在下载页找到archive这个单词,并找到老版本
解压、进入解压目录、复制conf/zoo_sample.cfg为zoo.cfg、进入bin目录(存放了各种运行脚本)
./zkServer.sh start启动、status状态、stop停止 #启动需要借助conf/zoo.cfg文件
视频教程:B站千锋教育zookeeper教程的安装教程
zk操作
./zkCli.sh #客户端
ls /
ls /brokers
2.安装kafka
官网下载、解压、进入解压目录、进入bin目录(同样包含了各种运行脚本)
./kafka-server-start.sh -daemon ../config/server.properties #携带配置文件启动
视频教程:B站千锋教育kafka教程的安装教程
#主题Topic
1.查看主题
# 指定zk地址
./kafka-topics.sh --list --zookeeper localhost:2181
2.创建hello主题
./kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic hello
#消息的生产和消费
1.生产消息
#指定kafka地址和主题
./kafka-console-producer.sh --broker-list localhost:9092 --topic hello
2.消费消息:接收消息
# 从头开始消费
./kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic hello
# 从最后一条消息的偏移量+1开始消费
./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic hello
#消息持久化
broker将消息有序的保存到本地的日志文件,具体路径见config/server.properties下的log.dirs=../kafka-logs
配置
#消费类型
1.单播消息
一个生产者(更具体就是一个分区,后面集群有涉及),多个消费者,消费者指定相同组id,同组的消费者,消息只能消费一次
./kafka-console-consumer.sh --bootstrap-server localhost:9092 --consumer-property group.id=helloGroup --topic hello
2.多播消费
一个生产者(一个分区),多个消费者,消费者指定不同组id,那么各个组都会收到消息,当然每个组只能有一个消费者能消费到消息
查看消费组信息
# 查看当前主题下有哪些消费组
./kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list
# 查看消费组中的具体信息:比如当前消费者已消费的偏移量(current-offset)、最后一条消息的偏移量,即消息总量(Log-end-offset)、未消费的消息数量(Lag)
./kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group helloGroup
#基本概念
主题
Kafka的一个逻辑概念,使用topic能对消息进行分类,消费者可以根据需要订阅对应的主题
问题:主题消息过多,会导致日志文件过大,可以使用分区解决
分区
将消息分段存储,避免文件过大,同时能提高并发处理能力(提高读写吞吐量)
为主题创建分区–partitions num
./kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 2 --topic hi
通过log.dirs=../kafka-logs
可以看到有两个日志文件夹记录(hi-0 hi-1)
内建主题
kafka内部⾃⼰创建了包含50个分区的__consumer_offsets主题。这个主题⽤来存放消费者消费某个主题的偏移量。因为每个消费者都会维护着⾃⼰消费的主题的偏移量,也就是说每个消费者会把消费的主题的偏移量⾃主上报给kafka中的默认主题。其中,kafka为了提升这个主题的并发性,默认设置了50个分区(offsets.topic.num.partitons)。
至于具体提交到哪个分区:通过hash函数:hash(consumerGroupId) % __consumer_offsets计算。
提交到该主题中的内容是:key是消费组id+topic+分区号,value就是当前offset的值
⽂件中保存的消息,默认保存7天。七天到后消息会被删除。
#集群
部署
找个文件夹作为集群的练习
mkdir jinqun
配置多个broker,复制多个配置文件到该文件夹
cp ./config/server.properties ./jinqun/s1.properties #s1 s2 s3
修改配置文件中的三个配置
broker.id=1 # 不同节点 1 2 3
listeners=PLAINTEXT://localhost:9091 # 通过设置不同端口模拟 9091 9092 9093
log.dir=./kafka-logs-1 # 不同日志1 2 3
启动(进入bin目录)
./kafka-server-start.sh -daemon ./s1.properties #携带各个配置文件
副本
主题有多个分区,而集群有多个节点,每个节点需要订阅该主题,于是使用分区副本,存到自己的节点中(日志中)。其中作为读写的副本称为leder,其他副本称为follower,负责从leader中同步数据。(leader挂了,从isr集合中选取follower代替)
💡isr集合记录了可同步和已同步的节点
通过创建主题指定副本 --replication-factor num
./kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 3 --partitions 2 --topic jiqun
查看单个主题的具体信息(leader follower sir等信息)
../bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic jiqun
生产消息
多个broker用逗号隔开
../bin/kafka-console-producer.sh --broker-list localhost:9091,localhost:9092,localhost:9093 --topic jiqun
消费消息
../bin/kafka-console-consumer.sh --bootstrap-server localhost:9091,localhost:9092,localhost:9093 --topic jiqun
# -consumer-property group.id=jiqunGroup 可指定组id
同样遵循组内单播、组间广播
从集群上看,一个分区的消息只能被同组的一个消费者消费,但是一个消费者可消费多个分区,且组内消费者的数量不能多于主题的总分区数,否则存在消费者消费不到消息。其中,如果消费者挂了,会让其他消费者代替
问题:收不到消息则把zk和kafka重启(不行就把日志文件全删了)
java操作kafka
原生API
依赖
<!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.4.0</version>
</dependency>
生产者
/Users/zone/IdeaProjects/kafka/src/main/java/com/zone/producer
1.同步发送消息
- ack=0/1/-1
- 消息重试
2.异步发送消息
回调函数
3.缓冲区设置
消费者
/Users/zone/IdeaProjects/kafka/src/main/java/com/zone/consumer
1.提交offset问题
前提是消息已经消费完,此时消费者有⾃动提交和⼿动提交offset配置,手动提交有同步和异步
2.长轮询poll
消费者建⽴了与broker之间的⻓连接,开始poll消息
1s内不断的poll,直到达到设置的500条max.poll.records
,则结束poll去消费消息(遍历for循环),如果poll的总时间超过1s,也会结束poll去消费消息.
如果两次poll的间隔超过30s(例如for循环执行时间过久),集群会认为该消费者的消费能⼒过弱,将其被踢出消费组,并触发rebalance机制,rebalance机制会造成性能开销。可以通过设置这个参数max.poll.interval.ms
延长间隔,或者让⼀次poll的消息条数少⼀点.
3.心跳健康、定制化消费(主题、分区、偏移量、时间)
4.新消费组消费设置
SpringBoot集成
/Users/zone/IdeaProjects/boot-kafka/src/main/java/com/zone/bootkafka
依赖
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
配置
spring:
kafka:
bootstrap-servers: localhost:9091,localhost:9092,localhost:9093
producer: # ⽣产者
retries: 3 # 设置⼤于0的值,则客户端会将发送失败的记录重新发送
batch-size: 16384
buffer-memory: 33554432
acks: 1
# 指定消息key和消息体的编解码⽅式
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
consumer:
group-id: default-group
enable-auto-commit: false
auto-offset-reset: earliest
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
max-poll-records: 500
listener:
# 当每⼀批poll()的数据被消费者监听器(ListenerConsumer)处理之后, ⼿动调⽤Acknowledgment.acknowledge()后提交
# MANUAL
# ⼿动调⽤Acknowledgment.acknowledge()后⽴即提交,⼀般使⽤这种
# MANUAL_IMMEDIATE
ack-mode: MANUAL_IMMEDIATE
poll-timeout: 50000
生产者使用KafkaTemplate发消息,消费者使用@KafkaListener注解消费消息
集群三大概念
controller
每个broker启动时会向zk创建⼀个临时序号节点,获得的序号最⼩的那个broker将会作为集群中的controller
当集群中有⼀个副本的leader挂掉,controller会通过isr集合中选择最左边的副本作为新的leader
当集群中有broker新增或减少或分区新增或减少,controller会同步信息给其他broker或分区
rebalance机制
当消费组中的消费者没有指明分区来消费,分区的分配策略有range和轮询
此时,如果消费组中的消费者和分区的关系发⽣变化的时候,会触发rebalance,如果开启了sticky(粘合策略),会在之前已分配的基础上调整(局部range和轮询),不会改变之前的分配情况。否则,分区会全部进行重新分配(重新range和轮询)
range策略:通过公式,让分区均衡的分到各个消费者
以7分区,3个消费者为例:
7/3除不尽,向上取整,所以第一个消费者对应3个分区,剩余4
4/2除的尽,所以第二个消费者对应2个分区,剩余2
2/1除的尽,所以最后一个消费者对应2个分区,结束
轮询:分区轮流分给消费者
HW、LEO
IEO 每个副本最后一个offset(log-end-offset)
HW俗称⾼⽔位,取ISR集合中副本最⼩的LEO作为HW,HW之前的数据才能被消费者消费。
这样就保证了如果leader所在的broker失效,仍然可以从新选举的leader中继续消费。
优化问题总结
1.防止消息丢失
发送⽅: ack是1 或者-1/all 可以防⽌消息丢失,如果要做到99.9999%,ack设成all,把min.insync.replicas配置成分区备份数
消费⽅:把⾃动提交改为⼿动提交。
2.如何防⽌消息的重复消费
幂等性
3.消息积压
https://blog.csdn.net/weixin_42322206/article/details/121848854
4.延迟队列
Kafka-eagle监控平台
https://zhuanlan.zhihu.com/p/446774729