Kafka 消息队列

消息队列

什么是消息队列?

消息队列,一般简称为MQ,消息(Message) + 队列(Queue) 的简写,而队列是一种先进先出的数据结构

在这里插入图片描述

Kakka

Kafka是一个消息队列,把消息放到队列里面的叫生产者,从队列里面消费的叫消费者

在这里插入图片描述

一个消息中间件,队列不单单只有一个,我们往往会有多个队列,而我们生产者和消费者就得知道:把数据丢到哪个队列,从哪个队列得到消息,我们就需要给队列取名字,叫做topic,与队列一一对应,相当于数据库里的概念

在这里插入图片描述

现在我们给队列去了名字后,生产者就知道往哪个队列丢数据了,消费者也知道往哪个队列拿数据了,我们可以有多个生产者往同一个队列(topic)丢数据,多个消费者往同一个队列(topic)中拿数据,但一个队列的吞吐量是固定的,这时为了提高一个队列的吞吐量,kafka会把topic进行分区(Partition)

在这里插入图片描述

所以,生产者实际上是往一个topic名为 z4 的分区(Partition) 丢数据,消费者实际上是往一个topic名为 z4 的分区(Partition) 取数据

一台kafaka服务器叫做Broker,kafka集群就是多台Kafka服务器:

在这里插入图片描述

生产者往一个topic里丢数据,实际上数据会在partition中,partition会分布在不同的broker(服务器)上。

现在我们已经知道了往topic里边丢数据,实际上这些数据会分到不同的partition上,这些partition存在不同的broker上,分布式肯定会带来问题,如果其中一台broker(kafka服务器)出现网络抖动或者挂了,怎么办?

Kafka是这样做的: 我们数据存在不同的partition上,那kafka就把这些partition做备份,比如,现在我们有3个partition,分别存在三台broker上,每个partition都会备份,这些备份散落在不同的broker上。

在这里插入图片描述

红色代表主分区,黄色代表备份分区

备份分区仅仅用作于备份,不做读写,如果某个Broker挂了,那就会选举其他Broker的partition来作为主分区,这就实现了高可用

  • 当生产者把数据丢进topic时,如果Broker中途挂了,那肯定会丢数据的,我们知道tpoic是写在partition上的,那partition是怎么将其持久化的呢?

  • kafka不是partion一有数据就立马将数据写到磁盘上,它会先缓存一部分,等到足够多数据量等待一定时间再批量写入(flush)磁盘,以消息日志方式存储,不过kafka只允许追加写入(顺序访问),避免缓慢的随机I/O操作。

从各个主分区取数据

生产者可以有多个,消费者也可以有多个,一个消费者消费三个分区的数据,多个消费者可以组成一个消费者组

在这里插入图片描述

消费者组

本来是一个消费者消费三个分区的,现在我们有消费者组,就可以每个消费者去消费一个分区(也是为了提高吞吐量)

在这里插入图片描述

消费者组的每个消费者回去对应partition拿数据

  • 如果消费者组中的某个消费者挂了,那么其中一个消费者可能就要消费两个partiton了
  • 如果只有三个partition,而消费者组有4个消费者,那么一个消费者会空闲
  • 如果多加入一个消费者组,无论是新增的消费者还是原本的消费者组,都能消费topic的全部数据。( 消费者组之间从逻辑上它们是独立的 )

如果一个消费者组中的某个消费者挂了,那挂掉的消费者所消费的分区可能就由存活的消费者消费。那存活的消费者是如何知道挂掉的消费者消费到哪了

这里就要引出offset了,kafka就是用offset来表示消费者的消费进度到哪了,每个消费者都会有自己的office,说白了offset就是表示消费者的消费进度

zookeeper对于kafka来说的作用:

  • 探测 broker消费者(consumer) 的添加或移除。
  • 负责维护所有partition的领导者/从属者关系(主分区和备份分区),如果主分区挂了,需要选举出备份分区作为主分区。
  • 维护topic、partition等元配置信息

场景一

  • 如果zookeeper发现消费者组中一个消费者A挂掉,让消费者B顶替消费,这时消费者A重连,消费者A和消费者B可能会同时消费同一条数据吗?

    答: 会的,但如何避免同时消费,这时候需要在消费端做业务处理(如果已经消费过了,就不消费了)

关注博客爵士,欢迎各位大大光临(大数据,python,java,操作系统) http://www.yazz.top/