Kafka之路

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值