Kafka学习文章目录Kafka学习1. Kafka简介1.1 Kafka消费模式1.2 Kafka的基础架构1.3 Kafka的安装和使用2. Kafka高级2.1 工作流程2.2 文件存储2.3 生产者分区策略2.4 生产者ISR2.4.1 副本数据同步策略2.4.2 ISR(同步副本集)2.5 生产者ack机制2.6 数据一致性问题2.7 ExactlyOnce3. 消费者分区分配策略3.1 分区分配策略3.2 消费者offset的存储3.3 消费者组案例4. 高效读写&Zookeeper作用4.1 Kafka的高效读写4.2 Kafka中zookeeper的作用5. 事务5.1 Producer事务5.2 Consumer事务6. API生产者流程6.1 异步发送普通生产者6.2 异步发送带回调函数的生产者6.3 生产者分区策略测试7. API消费者7.1 简单消费者7.2 消费者重置offset7.3 消费者保存offset读取问题7.4 消费者手动提交offset7.5 数据漏消费和重复消费分析7.6 自定义存储offset8. 自定义拦截器9. Kafka监控Eagle10. 常见面试题11. 小结
之前学过一点点不过不是系统的学习,这次学习还是参照视频来的,主要是学习Kafka的使用以及整体的知识,以及面试的相关知识点,主要针对春招的备战,同时也是为了让自己学会越来越多的知识,继续加油!
1. Kafka简介Kafka是一种消息队列,主要用来处理大量数据状态下的消息队列,一般用来做日志的处理。既然是消息队列,那么Kafka也就拥有消息队列的相应的特性了。
消息队列的好处
解耦合
耦合的状态表示当你实现某个功能的时候,是直接接入当前接口,而利用消息队列,可以将相应的消息发送到消息队列,这样的话,如果接口出了问题,将不会影响到当前的功能。
异步处理
异步处理替代了之前的同步处理,异步处理不需要让流程走完就返回结果,可以将消息发送到消息队列中,然后返回结果,剩下让其他业务处理接口从消息队列中拉取消费处理即可。流量削峰
高流量的时候,使用消息队列作为中间件可以将流量的高峰保存在消息队列中,从而防止了系统的高请求,减轻服务器的请求处理压力。
1.1 Kafka消费模式
Kafka的消费模式主要有两种:一种是一对一的消费,也即点对点的通信,即一个发送一个接收。第二种为一对多的消费,即一个消息发送到消息队列,消费者根据消息队列的订阅拉取消息消费。
一对一
消息生产者发布消息到Queue队列中,通知消费者从队列中拉取消息进行消费。消息被消费之后则删除,Queue支持多个消费者,但对于一条消息而言,只有一个消费者可以消费,即一条消息只能被一个消费者消费。
一对多
![](https://i-blog.csdnimg.cn/blog_migrate/b6752219db316d1c1f19b2182f346dee.png)
这种模式也称为发布/订阅模式,即利用Topic存储消息,消息生产者将消息发布到Topic中,同时有多个消费者订阅此topic,消费者可以从中消费消息,注意发布到Topic中的消息会被多个消费者消费,消费者消费数据之后,数据不会被清除,Kafka会默认保留一段时间,然后再删除。
1.2 Kafka的基础架构
![](https://i-blog.csdnimg.cn/blog_migrate/7a31217dcaca5c0ded4094d2746e2dca.png)
Kafka像其他Mq一样,也有自己的基础架构,主要存在生产者Producer、Kafka集群Broker、消费者Consumer、注册消息Zookeeper.
- Producer:消息生产者,向Kafka中发布消息的角色。
- Consumer:消息消费者,即从Kafka中拉取消息消费的客户端。
- Consumer Group:消费者组,消费者组则是一组中存在多个消费者,消费者消费Broker中当前Topic的不同分区中的消息,消费者组之间互不影响,所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。某一个分区中的消息只能够一个消费者组中的一个消费者所消费
- Broker:经纪人,一台Kafka服务器就是一个Broker,一个集群由多个Broker组成,一个Broker可以容纳多个Topic。
- Topic:主题,可以理解为一个队列,生产者和消费者都是面向一个Topic
- Partition:分区,为了实现扩展性,一个非常大的Topic可以分布到多个Broker上,一个Topic可以分为多个Partition,每个Partition是一个有序的队列(分区有序,不能保证全局有序)
- Replica:副本Replication,为保证集群中某个节点发生故障,节点上的Partition数据不丢失,Kafka可以正常的工作,Kafka提供了副本机制,一个Topic的每个分区有若干个副本,一个Leader和多个Follower
- Leader:每个分区多个副本的主角色,生产者发送数据的对象,以及消费者消费数据的对象都是Leader。
- Follower:每个分区多个副本的从角色,实时的从Leader中同步数据,保持和Leader数据的同步,Leader发生故障的时候,某个Follower会成为新的Leader。
上述一个Topic会产生多个分区Partition,分区中分为Leader和Follower,消息一般发送到Leader,Follower通过数据的同步与Leader保持同步,消费的话也是在Leader中发生消费,如果多个消费者,则分别消费Leader和各个Follower中的消息,当Leader发生故障的时候,某个Follower会成为主节点,此时会对齐消息的偏移量。
1.3 Kafka的集群部署
基于zookeeper的三台机器操作:
cd /opt/
tar zxvf kafka_2.13-2.7.1.tgz
mv kafka_2.13-2.7.1 /usr/local/kafka
#kafka安装包上传到/opt解压并移动到/usr/local中改名为kafka
#下载地址wget https://mirrors.tuna.tsinghua.edu.cn/apache/kafka/2.7.1/kafka_2.13-2.7.1.tgz
cd /usr/local/kafka/config/
cp server.properties server.properties.bak
vim server.properties
#kafka主配置文件备份并编辑,内容如下
broker.id=0
#21行,broker的全局唯一编号,每个broker不能重复,因此要在其他机器上配置 broker.id=1、broker.id=2
listeners=PLAINTEXT://192.168.10.17:9092
#31行,指定监听的IP和端口,如果修改每个broker的IP需区分开来,也可保持默认配置不用修改
num.network.threads=3
#42行,broker 处理网络请求的线程数量,一般情况下不需要去修改
num.io.threads=8
#45行,用来处理磁盘IO的线程数量,数值应该大于硬盘数
socket.send.buffer.bytes=102400
#48行,发送套接字的缓冲区大小
socket.receive.buffer.bytes=102400
#51行,接收套接字的缓冲区大小
socket.request.max.bytes=104857600
#54行,请求套接字的缓冲区大小
log.dirs=/usr/local/kafka/logs
#60行,kafka运行日志存放的路径,也是数据存放的路径
num.partitions=1
#65行,topic在当前broker上的默认分区个数,会被topic创建时的指定参数覆盖
num.recovery.threads.per.data.dir=1
#69行,用来恢复和清理data下数据的线程数量
log.retention.hours=168
#103行,segment文件(数据文件)保留的最长时间,单位为小时,默认为7天,超时将被删除
log.segment.bytes=1073741824
#110行,一个segment文件最大的大小,默认为 1G,超出将新建一个新的segment文件
zookeeper.connect=192.168.30.18:2181,192.168.30.19:2181,192.168.30.20:2181
#123行,配置连接Zookeeper集群地址,保存后退出
vim /etc/profile
#编辑全局变量文件,添加kafka全局环境变量,内容如下
export KAFKA_HOME=/usr/local/kafka
export PATH=$PATH:$KAFKA_HOME/bin
#export全局生效,修改完后保存退出
source /etc/profile
#刷新全局配置变量文件
#编写管理kafka服务的脚本
vim /etc/init.d/kafka
#!/bin/bash
#chkconfig:2345 22 88
#description:Kafka Service Control Script
KAFKA_HOME='/usr/local/kafka'
case $1 in
start)
echo "---------- Kafka 启动 ------------"
${KAFKA_HOME}/bin/kafka-server-start.sh -daemon ${KAFKA_HOME}/config/server.properties
;;
stop)
echo "---------- Kafka 停止 ------------"
${KAFKA_HOME}/bin/kafka-server-stop.sh
;;
restart)
$0 stop
$0 start
;;
status)
echo "---------- Kafka 状态 ------------"
count=$(ps -ef | grep kafka | egrep -cv "grep|$$")
if [ "$count" -eq 0 ];then
echo "kafka is not running"
else
echo "kafka is running"
fi
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
esac
脚本内容为当执行脚本位置变量1为star,stop,restart,status,*时执行对应的服务管理脚本(安装时自带管理服务的脚本)
chkconfig --add kafka
#设置开机自启并使用service管理服务
service kafka start
service kafka status
#开启并查看服务状态
###随便一台机器执行:
kafka-topics.sh --create --zookeeper 192.168.30.18:2181,192.168.30.19:2181,192.168.30.20:2181 --replication-factor 2 --partitions 3 --topic test
#kafka创建topic即主题test
#--zookeeper:定义 zookeeper 集群服务器地址,如果有多个 IP 地址使用逗号分割,一般使用一个 IP 即可
#--replication-factor:定义分区副本数,1 代表单副本,建议为 2
#--partitions:定义分区数
#--topic:定义 topic 名称
kafka-topics.sh --list --zookeeper 192.168.30.18:2181,192.168.30.19:2181,192.168.30.20:2181
#查看当前服务器中的所有 topic
kafka-topics.sh --describe --zookeeper
192.168.30.18:2181,192.168.30.19:2181,192.168.30.20:2181
#查看某个 topic 的详情
kafka-console-producer.sh --broker-list 192.168.30.18:9092,192.168.30.19:9092,192.168.30.20:9092 --topic test
#进入test的topic主机发布消息,输入完命令后输入123456
kafka-console-consumer.sh --bootstrap-server 192.168.30.18:9092,192.168.30.19:9092,192.168.30.20:9092 --topic test --from-beginning
#在另外一台主机输入消费信息的命令,查看是否可以收到发布的消息
#--from-beginning:会把主题中以往所有的数据都读取出来,即从最开始读取
kafka-topics.sh --zookeeper 192.168.30.18:2181,192.168.30.19:2181,192.168.30.20:2181 --alter --topic test --partitions 6
#修改名为test的topic主题的分区数
kafka-topics.sh --delete --zookeeper 192.168.30.18:2181,192.168.30.19:2181,192.168.30.20:2181 --topic test
#删除名为test的topic
![](https://i-blog.csdnimg.cn/blog_migrate/47f7c94e56442d9f428f269bdd7bcbcf.png)
8、kafka报错分析
[2023-04-10 20:01:57,373] WARN [Producer clientId=console-producer] Bootstrap broker 192.168.217.150:2181 (id: -1 rack: null) disconnected (org.apache.kafka.clients.NetworkClient)
[2023-04-10 20:01:57,475] WARN [Producer clientId=console-producer] Bootstrap broker 192.168.217.101:2181 (id: -2 rack: null) disconnected (org.apache.kafka.clients.NetworkClient)
[2023-04-10 20:01:57,577] WARN [Producer clientId=console-producer] Bootstrap broker 192.168.217.102:2181 (id: -3 rack: null) disconnected (org.apache.kafka.clients.NetworkClient)
[2023-04-10 20:01:57,679] WARN [Producer clientId=console-producer] Bootstrap broker 192.168.217.101:2181 (id: -1 rack: null) disconnected (org.apache.kafka.clients.NetworkClient)
[2023-04-10 20:01:57,782] WARN [Producer clientId=console-producer] Bootstrap broker 192.168.217.102:2181 (id: -2 rack: null) disconnected (org.apache.kafka.clients.NetworkClient)
###报错信息
ERROR org.apache.kafka.common.errors.InvalidReplicationFactorException: Replication factor: 2 larger than available brokers: 1(kafka.admin.TopicCommand$)
##三台kafka只起来一台,查看是否配置文件中的broker.id相同了,或者其他俩台防火墙启动错误