目录
什么是Kafka?
kafka是一个分布式消息队列
这个定义意味深长,记住容易,理解不易。首先我们得先知道什么是消息系统,他的原理是什么
根据kafka官网最新的定义,其将自身定义为:分布式事件流平台。但是他多数使用者还是用他做分布式消息队列,所以这里讨论消息队列的内容
消息队列原理:
消息队列原理如下:
关于分布式,我在下面的这篇文章中有所探讨:
消息队列原理如下:
这里客户端A负责生产数据,也被称作是生产者,生产完数据之后,放入到消息队列中,然后客户端B作为消费者去消费数据,之类消费者和生产者之间并不是直接通信的。这里的消息队列有两种模式:
🅰️ 点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除)
🅱️ 发布/订阅模式(一对多)
使用消息对列通信直接通信和之后的优点如下:
1️⃣ 解耦:消息队列将生产和消费,和数据的存储,分解开来,这样消费者和生产者没有直接关联,耦合性低,扩展性就越好,可以随时增减消费者或者是生产者;
2️⃣ 峰值处理:比如kafka设计的是客户取数据,这样消费者可以根据自己的速率来进行调整,而不是消息队列推送,这样还可以避免数据的丢失,同时并发量巨大的时候,直接增加服务器就OK;
3️⃣ 异步通信:生产生产了数据,可以存放在消息队列汇中,然后自己继续生产,消费者消费与否,并不影响生产
发一条消息,需要等待结果,发一条消息需要等待结果这就是同步,不需要等待返回结果,就可以干别的事情,就是异步。打电话的时候,就是同步通信,发短信的时候,就是异步通信
其实这些好处都是解耦之后带来的好处
kafka的核心概念
1️⃣ Producer:向 kafka broker 发消息的客户端就是 producer
2️⃣ Broker:kafka 管理消息的节点
3️⃣ Consumer:从kafka broker 取消息的客户端就是 Consumer
4️⃣ 分区:一个 Topic数据以分区的方式散列各个 Broker。每个partition是一个有序的队列,单个消费者去消费分区中的队列,以此保证有序
一个分区不能同一个消费者组中的,2个消费者消费,Kafka能够保证一个Partition中的消息是顺序的
kafka是依赖Zookeeper 的,Kafka在启动时候会写入Broker的 id的信息,分区的信息,主题等信息到zookeeper。Consumer会将消费的偏移量offset
记录在Zookeeper中,记录当前消费者消费到第几条数据了,下次消费的时候,从消费记录开始
kafka工作流程详解:
以上图(kafka原理及工作原理)的为例:多台机器构成kafka消息队列的集群,主要是为了负载,每一台服务器叫做broker,多个服务broker在一起,就形成了一个集群,为什么这么设计?
1️⃣ 分区提高吞吐 :
生产者生产数据的时候,理论上说一台机器来接收数据就OK了,但是如果生产者的产能很大,大量的数据涌向一台机器,这台,能干嘛?只能崩溃,就像情绪,太大了会让我们emo。所以我们这样做:增加多台机器,然后将大量的数据分区,将数据按照分区放到不同的机器上去,这样单台机器承担的数据压力就小了。如上图,生产者A生产的消息(订单主题),一部分分到了1分区,另外一部分分到了 0分区,如此一来,信息没有放在一块,数据量就少了,性能就会提升
2️⃣ 当数据到达broker之后 ,谁在关心发过来的数据呢?因为消费者不可能消费所有的消息,所以我们将消息划分逻辑主Topic,对不同的消息做一些分类,(就像我们将类似的文件放在一个folder一样),定义了主题之后,将相关的消息放进来就OK了,这样消费者消费的时候,就可以只是消费他关心的数据
3️⃣ 副本保证数据安全
将数据按照分区发送到不同的分区是没有任何的问题的,但是如果某一台机器宕机了,可见数据是不安全的,所以在这种情况下,我们应该给分区做一个备份,所以这里有一个replication的操作,将数据做一个副本,为了安全,这个副本应该被放置在不同的机器上,这样就有了leader和follower的概念,这里的副本仅仅是为了备份,读写都只有leader才能够进行.表现在图中,就是生产者的箭头,仅仅指向了leader,同理消费者只取leader中消费数据
分布式系统的副本,有的对外提供服务(MySQL主从中的从会提供读服务,HDFS的副本也提供读服务),有的不提供,Kafka的 follower 副本,MySQL中的主备从的备不提供读服务
4️⃣ 消费者组提高吞吐
消费数据都是按照组为单位来消费的,这就意味着,Topic 订单中的所有数据都是组拿到的,组内的单个成员去消费不同的分区,如果有3个消费者,2个分区,那么将有一个空闲消费者?一般地,消费者组中的消费者和分区数是保持一致,所以如何来增加消费能力呢?最基本的条件是增加分区
5️⃣ 这里有分区0 和分区1,对于消费者组来说,他无法保证他是先读取到分区0中的数据,还是先读到分区1中的数据,这里影响的主要因素是网络的原因,但能够保证的是:同一个分区中数据是有序的,因为消息的内部的实现方式是队列,这也是kafka叫消息队列的原因
推荐阅读:
分布式架构下的消息队列:服务端分布式架构、客户端分布式架构、分布式系统的区别与联系_客户端服务端模式是分布模式吗-CSDN博客