飞道的博客

消息队列——Kafka

309人阅读  评论(0)

敖丙大佬:《浅入浅出》-Kafka

0.消息队列,考虑以下的问题:

1.使用消息队列不可能是单机的(必然是分布式or集群)

Kafka天然是分布式的,往一个topic丢数据,实际上就是往多个broker的partition存储数据

2.数据写到消息队列,可能会存在消息丢失的问题,所以,数据在消息队列需要持久化(磁盘?数据库?Redis?分布式文件系统?)

Kafka会将partition以消息日志的方式(落磁盘)存储起来,通过 顺序访问IO和缓存(等到一定的量或时间)才真正把数据写到磁盘上,来提高速度。

3.想要保证消息是有序的?怎么做?

Kafka会将数据写到partition,单个partition的写入是有顺序的。如果要保证全局有序,那只写入一个partition中。如果要消费也有序消费者只有一个

4.为什么在消息队列中重复消费了?

凡是分布式就无法避免网络抖动/机器宕机等问题的发生,很有可能消费者A读取了数据,还没来得及消费,就挂掉了。Zookeeper发现消费者A挂了,让消费者B去消费原本消费者A的分区,等消费者A重连的时候,发现已经重复消费同一条数据了。

解决:

如果业务上不允许重复消费的问题,最好消费者那端做业务上的校验(如果已经消费过了,就不消费了)

1.什么是Kafka?

1.1.Kafka入门

众所周知,Kafka是一个消息队列,把消息放到队列里的是生产者,从队列里边消费的是消费者。

1.什么是topic?

一个消息中间件,队列肯定不只有一个,我们往往会有多个队列,而我们生产者和消费者就得知道:

  • 把数据丢给哪个队列?
  • 应该从哪个队列取消息?
    我们需要给队列取名字,叫做topic(相当于数据库里面的

    在给队列取名字后,生产者就知道该给那个队列丢数据了,消费者也知道去哪个队列拿数据了。我们可以有:
  • 多个生产者往同一队列(topic)丢数据。
  • 多个消费者向同一队列(topic)拿数据。

2.什么是partition?

为了提升队列的吞吐量,Kafka会把topic进行分区(partition

所以,生产者实际上就是往一个topic名为Java3y的分区(partition)丢数据;
消费者实际上就是往1个topic名为Java3y的分区(partition)取数据。

3.什么是Broker?Kafka集群就是多台Kafka服务器(考虑负载均衡)


一个topic会分为多个partition,实际上partition会分布在不同的broker中,举个例子:

  • 生产者往1个topic里边丢数据,实际上数据会在parition中,partition会分布在不同的broker(服务器)上。
    由此可知:
  • Kafka是天然分布式的。

2.分布式带来的问题

生产者往topic里边丢数据,实际上这些数据会被分到不同的partition上,这些partition存在于不同的broker上。分布式肯定会带来问题。

2.1.生产者写入数据

1.万一某台broker出现网络抖动或者挂掉怎么办?

1.partition的备份机制

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

  • partition0为主分区的broker,partition1、partition2就是备份分区;
  • partition1为主分区的broker,partition0、partition2就是备份分区;
  • partition2为主分区的broker,partition0、partition1就是备份分区;

红色区域partition是主分区,紫色区域partition是备份分区。

  • 生产者往topic丢数据,是与主分区交互;
  • 消费者向topic取数据,也是与主分区交互。
实现:高可用

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

  • broker0挂掉了,选举broker1的partition0作为主分区,那么broker1的主分区有2个partition0、partition1;

2.partition的持久化

Kafka将partition的数据写在磁盘的(消息日志),不过Kafka只允许追加写入(顺序访问),避免缓慢的随机I/O操作。

  • Kafka不是partiton一有数据就写入磁盘,而是先缓存一部分,等到足够多数量或者等待一定的时间再批量写入(flush)。

2.2.消费者消费数据

生产者可以有多个,消费者也可以有多个,下图所示:

  • 一个消费者消费3个分区的数据。
  • 多个消费者可以组成1个消费者组。


1.提升吞吐量

  • 当消费者组中,每个消费者消费1个分区的数据(也是为了提高吞吐量)

总结:消费者

  • 1.如果消费者组中的某个消费者挂了,那么其中1个消费者可能要消费2个partition
  • 2.如果有3个partition,消费者组有4个消费者,那么剩余1个消费者处于空闲
  • 3.如果多加入1个消费者组,那各组之间从逻辑上独立,所以2个组都能消费topic所有数据。

2.3.消费者、生产者的数据处理

生产者往topic里丢数据是存在partition上的,而partition持久化到磁盘是IO顺序访问的,并且是先写缓存,隔一段时间或者数据量足够大的时候才批量写入磁盘的。

消费者在读的时候也很有讲究:正常的读磁盘数据是需要将内核态数据拷贝到用户态的,而Kafka 通过调用sendfile()直接从内核空间(DMA的)到内核空间(Socket的),少做了一步拷贝的操作。

2.4.offset——消费进度

消费者是怎么知道自己消费到哪里的呀?
Kafka不是支持回溯吗?那是怎么做的呀?

  • 比如:如果一个消费者组中的某个消费者挂了,那挂掉的消费者所消费的分区可能就由存活的消费者消费。那存活的消费者是需要知道挂掉的消费者消费到哪了,不然怎么玩。

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



转载:https://blog.csdn.net/m0_38057941/article/details/116072354
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场