消息中间件 Kafka

2024-06-23 15:48
文章标签 kafka 消息中间件

本文主要是介绍消息中间件 Kafka,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

假设一种case,一个任务耗时高达数十秒,使用同步方式调用,一言不合便是超时,这可如何是好呢?

首相想到的,当然是异步化。耗时巨大的任务,使用同步调用方式,比如HTTP或者RPC,超时是很难避免的了。一个更好的做法便是将任务放入一个队列,同时给这个任务赋予一个唯一标识符,根据这个唯一标识符去获取任务的结果。队列有许多种,比如著名的Kafka,Nsq,RabbitMq等等。不同的队列有着不一样的适用场景。

笔者今天来谈谈对Kafka这一消息中间件的理解。

Kafka可以说是当前最为完善,使用最广泛的消息中间件。Kafka底层使用Scala语言编写,运行时需要JVM环境支撑。Kafka通常需要与Zookeeper一同使用,Kafka集群信息存储于Zookeeper中,每当有新的实例加入或者旧的实例退出时,都会在Zookeeper中进行实例信息的更改。Kafka 0.9之前的版本还会将offset存储于Zookeeper中,0.9版本及之后,offset不再存储于Zookeeper中,而改成存储在broker实例中。关于Kafka的offset将会在下文中阐述,这也是Kafka最为重要的一个概念。

说说Kafka最基本的几个概念。

Producer(生产者)

消息队列的生产者端,也就是发消息的。生产者发送消息的时候,会指定发送到哪个topic。

Consumer(消费者)

消息队列的消费者端。消费者会订阅某个topic,它会接收到来自这个topic的消息。

Consumer Group(消费者组)

字面意思,消费者的组。对于同一个消费者组,组内会有多个消费者进程,一个消费者对应一个消费者进程。对于归属于同一组的消费者,此消费者组订阅了一个topic,那么,来自这个topic的消息只会被消费者组中的一个消费者进程消费,如图Figure1所示。

消息中间件 Kafka

Figure1

对于两个不同的消费者组,这两个消费者组订阅了同一个topic,那么,来自这个topic的消息对于这两个消费者组是广播的,如图Figure1所示。

Topic(主题)

上文中已提到。不同的topic之间是相互独立开的,不同的topic里面存放着不同的消息。通常一个Kafka队列会有多个不同的业务方接入,不同的业务方使用不同的topic相互之间完全隔离。

Partition(分区)

对于一个topic,里面有一个或者多个分区。生产者发送的消息进入到topic里面之后,会均匀的分布在不同的分区之中,如图Figure2所示。

消息中间件 Kafka

Figure2

对于同一个分区内部,消息是保持有序的,但是在有多个分区的情况下,topic整体上消息无序。因此,如果有什么业务场景要求消息保持绝对有序,一定要将分区数量设置为1。对于同一个消费者组内部,一个消费者进程可以消费一个或者多个分区的消息。如果消费者进程数量小于分区数量,那么一个进程消费多个分区;如果消费者进程数量大于分区数量,那么就会有进程被闲置,因为一个分区只能被一个消费者消费。因此,通常设置同一个消费者组内,消费者数量等于分区数量,此时能够达到最高吞吐量。

Broker(实例,也就是机器)

Kafka通常由集群构成,集群中的一台机器,也就是一台实例,就是一个broker。

Offset(偏移量,用于记录当前消费位置)

笔者认为,这是kafka中最为关键的一个概念。Kafka队列的原理是,生产者写入的消息会保存到本地磁盘文件,也就是说,生产者发送的所有的消息都会被保存下来。消费者消费消息时,消息不是真的被消费了,而是,消费一条消息之后,offset向后偏移一位,指向下一条消息的index,如图Figure3所示。

消息中间件 Kafka

Figure3

在Figure3中,生产者从左侧写入消息,消费者的offset从右侧开始消费偏移。图中所示的是一个partition内部的情况,对于一个完整的topic,每个partition都会为每一个消费者组维持着一个offset值。什么意思呢?对于一个消费者组,它订阅了一个topic,也就是说,它正在消费这个topic中的所有partition,每个partition中都为这个消费者组,维护着一份offset,来表明该消费者组在这个partition中消费到了什么位置。当这个topic有多个消费者组订阅时,partition就会为每一个消费者组维护一份offset,因为不同的消费者组消费到的位置不一样。Offset不是永远只会往后移动的,他是可以自定义调整位置的。只要生产者成功写入了消息,消息就会被Kafka保存下来。如果消费者因为一些原因没能消费成功,那么可以通过修改偏移量offset来重新进行一次消费。在一些精确度要求很高的场景,这种特性十分适用,比如计费,点钞票的时候因为一些原因点漏了可就不好了,Kafka存储了所有消息,就算出现了异常,通过修改offset重来一次就好了。

那么,有个问题,对于同一个消费者组内部,每个消费者进程,是怎样被分配给topic里面的partition的呢?

分配策略有很多,笔者在这里说说Kafka本身自带的默认的两种策略,他们是RangeRoundRobin

Range策略

该策略十分简单。假设现在有1~10合计10个分区,有1~3合计三个消费者进程。此时我们用 10 除以 3,得到3余1。对于三个消费者进程,我们先分别给3个消费者进程分配3个分区。此时还有一个分区,我们将其分配给第一个消费者。于是乎,分区分配情况就是【(1, 2, 3, 4), (5, 6, 7), (8, 9, 10)】。第一个消费者进程分陪了1~4号分区,第二个消费者进程分配了5~7号分区,第三个消费者进程分配了8~10号分区。

再举一个例子,假设现在有1~11合计11个分区,有1~3合计三个消费者进程。那么11除以3等于3余2。先平均分配,此时剩余2个分区,我们再将这两个分区分配给前面的两个消费者进程,也就是【(1,2,3,4),(5,6,7,8),(9,10,11)】。

RoundRobin策略

该策略会无视Kafka的topic,它会将topic+partition视为一个整体,随后计算其hashcode,根据计算出来的hashcode值,对所有的topic-partition进行排序。随后,按照RoundRobin原则,将这些topic-partition均分给所有的消费者进程,如图Figure4所示。

消息中间件 Kafka

Figure4

在只订阅一个topic的情况下,上述两种策略其实没有特别大的区别。然而在订阅了多个topic的情况下,RoundRobin策略将会优于Range策略。Figure5所示为Range策略的一个bad case。

消息中间件 Kafka

Figure5

我们按照Range策略进行了分区分配之后,我们发现,consumer1消费了6个分区,consumer2消费了5个分区,consumer3只消费了三个分区。那么,这种分配就严重不均衡了。但如果是使用了RoundRobin策略,情况就会好的多,因为它将topic-partition视为了一个整体,不会因为topic的缘故导致分配不均匀,如图Figure6所示。

消息中间件 Kafka

Figure6

在RoundRobin策略下,consumer1和consumer2各消费了4个partition,consumer3消费了3个partition,分配情况优于Range策略。

那么当有消费者进程退出或者启动的时候,会发生什么呢?这种情况下,原先的分配就被打乱了吧?

是的,确实被打乱了,此时就会发生重平衡(rebalance)。重平衡发生于消费者进程数量发生变化的时候,为了保持分区分配的合理性,需重新进行一次分区分配。重平衡进行的时候,消费者暂停消费,不过时间不会太长,有可能导致短暂的服务不可用。如果监测到一个消费者服务频繁地发生重平衡,应当检查服务是否存在存在进程退出的case。

这篇关于消息中间件 Kafka的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1087597

相关文章

搭建Kafka+zookeeper集群调度

前言 硬件环境 172.18.0.5        kafkazk1        Kafka+zookeeper                Kafka Broker集群 172.18.0.6        kafkazk2        Kafka+zookeeper                Kafka Broker集群 172.18.0.7        kafkazk3

Java消息队列:RabbitMQ与Kafka的集成与应用

Java消息队列:RabbitMQ与Kafka的集成与应用 大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿! 在现代的分布式系统中,消息队列是实现系统间通信、解耦和提高可扩展性的重要组件。RabbitMQ和Kafka是两个广泛使用的消息队列系统,它们各有特点和优势。本文将介绍如何在Java应用中集成RabbitMQ和Kafka,并展示它们的应用场景。 消息队

Kafka (快速)安装部署

文章目录 1、软件下载&配置环境1_JDK安装2_Zookeeper安装3_Kafka安装 2、单机安装1_配置主机名和IP映射2_单机Kafka配置 3、集群安装1_配置主机名和IP的映射关系2_时钟同步3_Zookeeper配置信息4_集群Kafka配置 4、kafka的其他脚本命令 1、软件下载&配置环境 下面的操作无论是单机部署还是分布式集群环境下都是通用的。 准

Kafka 分布式消息系统详细介绍

Kafka 分布式消息系统 一、Kafka 概述1.1 Kafka 定义1.2 Kafka 设计目标1.3 Kafka 特点 二、Kafka 架构设计2.1 基本架构2.2 Topic 和 Partition2.3 消费者和消费者组2.4 Replica 副本 三、Kafka 分布式集群搭建3.1 下载解压3.1.1 上传解压 3.2 修改 Kafka 配置文件3.2.1 修改zookeep

Kafka 实战演练:创建、配置与测试 Kafka全面教程

文章目录 1.配置文件2.消费者1.注解方式2.KafkaConsumer 3.依赖1.注解依赖2.KafkaConsumer依赖 本文档只是为了留档方便以后工作运维,或者给同事分享文档内容比较简陋命令也不是特别全,不适合小白观看,如有不懂可以私信,上班期间都是在得 1.配置文件 Yml配置 spring:kafka:bootstrap-servers: cons

Kafka【十二】消费者拉取主题分区的分配策略

【1】消费者组、leader和follower 消费者想要拉取主题分区的数据,首先必须要加入到一个组中。 但是一个组中有多个消费者的话,那么每一个消费者该如何消费呢,是不是像图中一样的消费策略呢?如果是的话,那假设消费者组中只有2个消费者或有4个消费者,和分区的数量不匹配,怎么办? 所以这里,我们需要学习Kafka中基本的消费者组中的消费者和分区之间的分配规则: 同一个消费者组的消费者都订

Kafka【十三】消费者消费消息的偏移量

偏移量offset是消费者消费数据的一个非常重要的属性。默认情况下,消费者如果不指定消费主题数据的偏移量,那么消费者启动消费时,无论当前主题之前存储了多少历史数据,消费者只能从连接成功后当前主题最新的数据偏移位置读取,而无法读取之前的任何数据。如果想要获取之前的数据,就需要设定配置参数或指定数据偏移量。 【1】起始偏移量 在消费者的配置中,我们可以增加偏移量相关参数auto.offset.re

Kafka的三高设计原理

1.生产者缓存机制--高性能 生产者缓存机制的主要目的是将消息打包,减少网络IO频率 kafka生产者端存在消息累加器RecordAccumulator,它会对每个Partition维护一个双端队列,队列中消息到达一定数量后 或者 到达一定时间后,通过sender线程批量的将消息发送给kafka服务端。(批量发送) 2.发送应答机制--高可用 发送应发机制保证了消息可以安全到达服务端!

Flink读取kafka数据并以parquet格式写入HDFS

《2021年最新版大数据面试题全面开启更新》 《2021年最新版大数据面试题全面开启更新》 大数据业务场景中,经常有一种场景:外部数据发送到kafka中,flink作为中间件消费kafka数据并进行业务处理;处理完成之后的数据可能还需要写入到数据库或者文件系统中,比如写入hdfs中; 目前基于spark进行计算比较主流,需要读取hdfs上的数据,可以通过读取parquet:spark.read

Pulsar与Kafka消费模型对比

kafka kafka 属于 Stream 的消费模型,为了支持多 partition 的消费关系,引入了 consumer group 的概念,同时支持在消费端动态的 reblance 操作,当多个 Consumer 订阅了同一个 Topic 时,会根据分区策略进行消费者订阅分区的重分配。只要 consumer-group 与 topic 之间的关系发生变更,就会动态触发 reblance 操