kafka 消息队列初识

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kafka 消息队列初识相关的知识,希望对你有一定的参考价值。

参考技术A 添加消息的依赖

<dependency>

<groupId>org.springframework.kafka</groupId>

<artifactId>spring-kafka</artifactId>

</dependency>

<dependency>

<groupId>io.projectreactor.kafka</groupId>

<artifactId>reactor-kafka</artifactId>

<version>1.1.0.RELEASE</version>

</dependency>

信息队列通信的模式---信息中间件

1》点对点模式

   点对点模式通常是基于拉取或者轮询的消息传送模式,(pull)主动的

特点:发送到队列的消息被一个且只有一个消费者进行处理。生产者将消息放入消息队列后,由消费者主动的去拉去消息进行消费。

优点:消费者拉取消息的频率可以由自己控制,消费者端需要额外的线程去监控消息是否消费。

2》发布订阅模式

发布订阅模式是一个基于消息送的消息传送模式,该模式可以由多种不同的订阅者,(push)被动接受

特点:生产者将消息放入消息队列后,队列会将消息推送给订阅过该类消息的消费者,消息队列无法感知消费者消费的速度,消息的处理速度不同,会出现自己的浪费问题

Kafka 消息:

概念:高吞吐量的分布式发布订阅消息系统,

特点:处理消费者规模的网站中的所有动作流数据,具有高性能,持久化,多副本备份,横向扩展能力,,,等

Producer :生产者,消息的入口,

kafka cluster (kafka 群):

Broker:kafka的实例,每个服务器上有一个或多个kafka 实例,多个broker 在kafka集群中是不重复存在的,会被定义不同不得编号并使用。

Topic:消息的主题,对消息进行分类,kafka数据保存在Topic中,而且,Broker 可以创建多个Topic

Partition:Topic的分区。其作用:处理负载,提高kafka 的吞吐量,同一个Topic 的不同分区数据不重复。Partition相当于一个个的文件夹。

Replication:分区有多个副本,其作用是为了做备胎。当主分区(Leader)c出现故障时,会选择一个备胎(Follower)上位,,成为Leader,在Kafka中默认最大的副本量为10个,且副本的数量不能大于Broker 的数量,follower和Leader 绝对不能在同一个机器中,同一机器对同一分区只能存放一个副本(包括自己)

Message:发送的消息主体

Consumer:消费者,消息的出口,消费方。

Consumer Group:多个消费者组成一个消费组,同一分区的数据,被消费组中一个消费者消费,这样提高了kafka的吞吐量

Zookeeper:kafka集群依赖zookeeper,用来保存集群的元信息,确保系统的可用性。

重点来啦:

工作流程分析:

注意:消息写入leader后,follower 是主动的去 leader进行同步操作的,Producer采用push的方式将数据发布到broker 中,并对每条消息追加到分区中,依次顺序写入磁盘中,以此保证统一分区内的数据是有序的,

如上图:数据在不同的分区中,可能会问没为什么要分区,目的又是什么,

分区的主要目的:1》方便扩展,topic和partition是一对多的关系,可以使用扩展机器,轻松扩展数据量。

                           2》提高并发,以partition 为基本的读写单位,多个消费者可以同时消费数据,提高消费的处理效率。

同时也会有疑问:一个topic 有多个partition,producer 如何确认数据发向哪个partition ?

z在此提下kafka的几大原则:

1:partition 在写入的时候可以选择需要写入的partition,有指定,则写入指定的partition。

2:若没有指定,但是呢,设置可数据的key 值,则会根据key值hash 出一个partition,

3:若没有partition ,也没有key ,则会根据轮询选出一个partition 。

保证信息不丢失是一个消息队列中间件的基本保证,但如何确保呢?-----通过ACK应答机制,

在生产者向队列写入数据的时候,可以设置参数来确定是否确认kafka接收到数据,这个参数可以设置的值为0,1,all。

0:producer 往集群发送数据不需要等到集群的返回,不确保消息的发送成功。其安全性最低,但效率最高。

1:producer往集群发送数据只要leader应答就可以发送一条,只确保leader发送成功。

all:producer 往集群发送数据所有的follower 都完成从leader 的同步发送下一条,确保leader 发送成功何所有副本都完成备份,安全性高,但效率最低。

kafka的应用场景:

主要解决应用解耦,一步消息,流量消费等,实现高性能,高可用,可伸缩和最终一致性架构。存储转发

目前使用较多的消息队列,有Active MQ。BabbitMQ,ZeroMQ,kafka ,MetaMQ,rocket MQ

应用场景:

1:网站活动追踪,对消息进行实时处理,实时监测,离线处理数据仓库,或加载到Hadoop上

2:指标 用于监测数据,分布式应用程序生成的统计数据集中聚合

3:日志聚合:使用kafka代替一个日志聚合的解决方案

4:流处理:基于单个topic主题的实时数据流,

5:实践采集:是一种应用程序的设计风格,kafka支持非常大的存储日志数据的场景

6:提交日志:kafka可以作为一种分布式的外部提交日志,日志帮助节点之间复制数据。并作为失败的节点来恢复实践重新同步,kafka的日志压缩功能能制止这个用法。

k

Kafka 初识

1.Kafka 是什么?

用一句话概括一下:Apache Kafka 是一款开源的消息引擎系统。

 


倘若“消息引擎系统“这个词对你来说有点陌生的话,那么“消息队列“、“消息中间件”的提法想必你一定是有所耳闻的。不过说实话我更愿意使用消息引擎系统这个称谓,因为消息队列给出了一个很不明确的暗示,仿佛 Kafka 是利用队列的方式构建的;而消息中间件的提法有过度夸张“中间件”之嫌,让人搞不清楚这个中间件到底是做什么的。

像 Kafka 这一类的系统国外有专属的名字叫 Messaging System,国内很多文献将其简单翻译成消息系统。我个人认为并不是很恰当,因为它片面强调了消息主体的作用,而忽视了这类系统引以为豪的消息传递属性,就像引擎一样,具备某种能量转换传输的能力,所以我觉得翻译成消息引擎反倒更加贴切。


2.这类系统是做什么用的?

  先来个官方严肃版本的答案。

  根据维基百科的定义:消息引擎系统是一组规范。企业利用这组规范在不同系统之间传递语义准确的消息,实现松耦合的异步式数据传递。
果然是官方定义,有板有眼。

  如果觉得难于理解,那么可以试试我下面这个民间版:
       系统 A 发送消息给消息引擎系统,系统 B 从消息引擎系统中读取 A 发送的消息。
  最基础的消息引擎就是做这点事的!

  不论是上面哪个版本,它们都提到了两个重要的事实:

  • 消息引擎传输的对象是消息;
  • 如何传输消息属于消息引擎设计机制的一部分。

 

3.它如何设计消息(消息的格式)?

  既然消息引擎是用于在不同系统之间传输消息的,那么如何设计待传输消息的格式从来都是一等一的大事。

  试问一条消息如何做到信息表达业务语义而无歧义,同时它还要能最大限度地提供可重用性以及通用性?

  一个比较容易想到的是使用已有的一些成熟解决方案,比如使用 CSV、XML 亦或是 JSON;又或者你可能熟知国外大厂开源的一些序列化框架,比如 Google 的 Protocol Buffer 或 Facebook 的 Thrift。这些都是很酷的办法。那么现在我告诉你 Kafka 的选择:它使用的是纯二进制的字节序列。当然消息还是结构化的,只是在使用之前都要将其转换成二进制的字节序列。

 

4.传输消息的方式?
  消息设计出来之后还不够,消息引擎系统还要设定具体的传输协议,即我用什么方法把消息传输出去。常见的有两种方法:

  • 点对点模型:也叫消息队列模型。如果拿上面那个“民间版“的定义来说,那么系统 A 发送的消息只能被系统 B 接收,其他任何系统都不能读取 A 发送的消息。日常生活的例子比如电话客服就属于这种模型:同一个客户呼入电话只能被一位客服人员处理,第二个客服人员不能为该客户服务。

 

  • 发布 / 订阅模型:与上面不同的是,它有一个主题(Topic)的概念,你可以理解成逻辑语义相近的消息容器。该模型也有发送方和接收方,只不过提法不同。发送方也称为发布者(Publisher),接收方称为订阅者(Subscriber)。和点对点模型不同的是,这个模型可能存在多个发布者向相同的主题发送消息,而订阅者也可能存在多个,它们都能接收到相同主题的消息。生活中的报纸订阅就是一种典型的发布 / 订阅模型。比较酷的是 Kafka 同时支持这两种消息引擎模型。

  提到消息引擎系统,你可能会问 JMS 和它是什么关系。JMS 是 Java Message Service,它也是支持上面这两种消息引擎模型的。严格来说它并非传输协议而仅仅是一组 API 罢了。不过可能是 JMS 太有名气以至于很多主流消息引擎系统都支持 JMS 规范,比如 ActiveMQ、RabbitMQ、IBM 的 WebSphere MQ 和 Apache Kafka。当然 Kafka 并未完全遵照 JMS 规范,相反,它另辟蹊径,探索出了一条特有的道路。

 

5.为什么要用用它?
  好了,目前我们仅仅是了解了消息引擎系统是做什么的以及怎么做的,但还有个重要的问题是为什么要使用它。
依旧拿上面“民间版“举例,我们不禁要问,为什么系统 A 不能直接发送消息给系统 B,中间还要隔一个消息引擎呢?
答案就是“削峰填谷”。这四个字简直比消息引擎本身还要有名气。

  所谓的“削峰填谷”就是指缓冲上下游瞬时突发流量,使其更平滑。特别是对于那种发送能力很强的上游系统,如果没有消息引擎的保护,“脆弱”的下游系统可能会直接被压垮导致全链路服务“雪崩”。但是,一旦有了消息引擎,它能够有效地对抗上游的流量冲击,真正做到将上游的“峰”填满到“谷”中,避免了流量的震荡。消息引擎系统的另一大好处在于发送方和接收方的松耦合,这也在一定程度上简化了应用的开发,减少了系统间不必要的交互。

  说了这么多,可能你对“削峰填谷”并没有太多直观的感受。举个例子来说明一下 Kafka 在这中间是怎么去”抗“峰值流量的吧。比如购买课程,每门课程都有一个专门的订阅按钮,点击之后进入到付费页面。这个简单的流程中就可能包含多个子服务,比如点击订阅按钮会调用订单系统生成对应的订单,而处理该订单会依次调用下游的多个子系统服务 ,比如调用支付宝和微信支付的接口、查询你的登录信息、验证课程信息等。显然上游的订单操作比较简单,它的 TPS 要远高于处理订单的下游服务,因此如果上下游系统直接对接,势必会出现下游服务无法及时处理上游订单从而造成订单堆积的情形。特别是当出现类似于秒杀这样的业务时,上游订单流量会瞬时增加,可能出现的结果就是直接压跨下游子系统服务。
解决此问题的一个常见做法是我们对上游系统进行限速,但这种做法对上游系统而言显然是不合理的,毕竟问题并不出现在它那里。所以更常见的办法是引入像 Kafka 这样的消息引擎系统来对抗这种上下游系统 TPS 的错配以及瞬时峰值流量。

  还是这个例子,当引入了 Kafka 之后。上游订单服务不再直接与下游子服务进行交互。当新订单生成后它仅仅是向 Kafka Broker 发送一条订单消息即可。类似地,下游的各个子服务订阅 Kafka 中的对应主题,并实时从该主题的各自分区(Partition)中获取到订单消息进行处理,从而实现了上游订单服务与下游订单处理服务的解耦。这样当出现秒杀业务时,Kafka 能够将瞬时增加的订单流量全部以消息形式保存在对应的主题中,既不影响上游服务的 TPS,同时也给下游子服务留出了充足的时间去消费它们。这就是 Kafka 这类消息引擎系统的最大意义所在。

 

  对Kafka的初识就到这里。谢谢阅读。

 

以上是关于kafka 消息队列初识的主要内容,如果未能解决你的问题,请参考以下文章

初识中间件之消息队列

Kafka 初识

云图说丨初识分布式消息服务Kafka版

初识消息队列处理机框架KClient

01-初识消息队列MQ&&Rabbit相关概念介绍

Kafka 入门篇