kafka

文章介绍了消息队列的基本概念,如其作为临时存储的作用、消息队列中间件如Kafka、ActiveMQ等,以及在应用解耦、流量削峰等方面的应用。Kafka作为一个分布式流平台,具备发布订阅模式和点对点模式。文中还详细阐述了Kafka的架构,包括生产者、消费者、副本、分区等核心概念,并讨论了Kafka的配置、使用场景和数据清理策略。
摘要由CSDN通过智能技术生成

简介:

消息队列用于存放消息的组件

程序员可以将消息放入到队列中,也可以从消息队列中获取消息

很多时候消息队列不是一个永久性的存储,是作为临时存储存在的(设定一个期限:设置消息中MQ中保存10天)

消息队列中间件:消息队列的组件,例如:Kafka,ActiveMQ,RabbitMQ,rocketMQ,ZeroMQ

应用场景:

应用解耦、数据管道、消息系统、流处理日志收集与分发

好处:

异步处理

可以将一些比较耗时的操作放在其他系统中,通过消息队列将需要处理的消息进行存储,其他系统可以消费消息队列中的数据

系统解偶

原先一个微服务生死勇敢接口http调用另一个微服务,这时候耦合很严重,只要接口发生变化就会导致系统不可用

使用消息队列呀将系统进行解偶,现在第一个微服务可以将消息放入到消息队列中,另一个微服务可以从消息队列中把消息取出来进行处理,进行系统解偶

流量削峰

因为消息队列是低延迟,高可靠,高吞吐的(Kafka吞吐量10W),可以应对大量并发

日志处理

可以使用消息队列作为临时存储,或者一种通信管道

mysql吞吐量8000,kafka响应快低延迟,mysql延迟比kafka高,先放到kafka中让用户等待

消息队列的两种模型

生产者和消费者模型

生产者负责将消息生产到MQ中

消费者负责从MQ中获取消息

生产者和消费者是解偶的,可能是生产者一个程序、消费者是另外一个程序

消息队列的两种模式:

点对点模式 :一个消费者消费一个消息

特点:

        每个消息只有一个接收者(即一旦被消费,消息就不再消息队列中)

        发送者和接收者间没有依赖性,发送者发送消息之后,不关有没有接收者在运行,都不影响到发送者下次发送消息

        接收者在成功接收消息之后需向队列应答成功,以便消息队列删除当前接收的消息

发布订阅模式: 多个消费者可以消费一个消息

特点:

        每个消息可以多个订阅者

        发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,

Kafaka是一个分布式的流平台

特点:发布和订阅流数据流,类似于消息队列或者是企业消息传递系统

            以容错的持久化方式存储数据流

            处理数据流

Kafka集群搭建

Kafka3.0之前依赖Zookeeper的

注意:每一个kafka的节点都需要修改broker.id(每个节点的标识,不能重复)

log.dir数据存储目录需要配置

Kafka的生产者/消费者/工具

安装kafka集群,可以测试以下

创建一个topic主题(消息都是存放在topic中,类似mysql建表的过程)

基于kafka的内置测试生产者脚本来读取标准输入(键盘输入)的数据,并放入到topic中

基于kafka的内置测试消费者脚本来消费topic中的数据

推荐大家开发的使用 kafka tool

浏览kafka集群节点,多个topic,多个分区

创建topic/删除topic

浏览zookeeper中的数据

kafka介绍

Producer:发布消息的对象称之为主题生产者(kafka topic producer)

Partition:分区,每个主题可以创建多个分区,每个分区都由一系列有序和不可变的消息组成

Topic:kafka将消息分门别类,每一类的消息称之为一个主题(Topic)

Consumer:订阅消息并处理发布的消息的对象称之为主题消费者(consumers)

Broker:已发布的消息保存中一组服务器中,称之为kafka集群。集群中的每一个服务器都是一个代理(broker)。消费者可以订阅一个或多个主题(topic),并从Broker拉数据,从而消费这些已发布的消息

Record:消息,消息队列基础通信单位

Replica:副本,每个分区都由一个至多个副本存在,它的主要作用是存储保存数据,以日志对象的形式体现。副本又分为leader副本和follower副本

Offset:偏移量,每一个消息在日志文件中的位置都对应一个按序递增的偏移量,你可以理解为类似数组的存储形式

kafka2.0和3.0

kafka2.0:一个集群所有节点都是broker角色,利用zookeeper的选举能力从多个broker中选举处理一个controller控制器,同时控制器将集群元数据信息(比如主题分类、消费进度等)保存到zookeeper,用于集群个节点之间分布式交互

kafka3.0:假设一个集群有四个broker,配置指定其中三个作为controller角色。使用Kraft机制实现controller主控制器的选举,从三个controller中选举出来一个Controller作为主控制器,其他的两个备用。zookeeper不再被需要。相关的集群元数据信息以kafka日志的形式存在(即:以消息队列消息的形式存在)

Kafka的基准测试工具

kafka单机基准测试,单机搭建及介绍_kafka 单机-CSDN博客

Kafka中提供了内置的性能测试工具

生产者:测试生成美妙传输的数据量(多少条数据、多少m的数据)

消费者:测试消费每条拉取的数据量

对比生产者和消费者:消费者的速度更快

生产者程序开发

1.创建链接

bootstrap.servers:kafka的服务器地址

Acks:表示当生产者数据到kafka中kafka中会以什么样的策略返回

key.serializer:kafka中的消息是以可以,value键值对存储的,而是生产者生产的消息是需要在网络上传到的,这里指定的事StringSerializer方式,就是以字符串方式发送(将来还可以使用其他的一些序列化框架:GoogleProtoBuf、Avro)

value.serializer:同上

2.创建一个生产者对象KafkaProducer

3.调用send方法发送消息(ProducerRecor,封装是key-value键值对)

4.调用Future.get表示带服务端的相应

5.关闭生产者

消费者程序开发

group.id:消费者组的概念,可以在一个消费组中包含多个消费者。如果若干个消费者的group.id是一样的,表示它们就在一个组中,一个组中的消费者是共同消费kafka中topic的数据

Kafka是一种拉消息模式的消息队列,中消费者中会有一个offset,表示从哪条消息开始拉取数据

kafka Consumer.poll:Kafka的消费者API是一批一批数据的拉取

生产者使用一步方式生产消息

使用匿名内部类实现CallBack接口,该接口中表示kafka服务响应给客户端,会自动调用onCompletion方法

Metadata:消息的元数据(属于哪个topic、属于哪个partition、对应的offset是什么)

Exception:这个对象kafka生产消息封装了出现的异常,如果为null,表示发送成功,如果不为null,表示出现异常

Kafka中的重要概念

broker

Kafka服务器进程,生产者、消费者都要连接broker

一个集群由多个broker组成,功能实现kafka集群的负载均衡、容错

producer:生产者

consumer:消费者

topic:主题,一个kafka集群中,可以包含多个topic。一个topic可以包含多个分区是一个逻辑结构,生产、消费消息都需要指定topic

Partition:kafka集群的分布式就是由分区来实现的。一个topic中的消息可以分布在topic中不同partition中

Repica:副本,实现kafka集群的容错,收拾下partition的容错。一个topic至少应该包含大于一个的副本

Consumer group:消费者组,一个消费者组中的消费者可以共同消费topic中的分区数据。每一个消费组都一个唯一的名字。配置group.id一样的消费者生死属于同一个组的

Offset:偏移量。相对消费者、partition来说,可以通过offset来拉取数据

消费者组

一个消费者组中可以包含多个消费者,共同来消费topic中的数据

一个topic中如果只有一个分区,那么这个分区只能呗某个组中的一个消费者消费

有多少个分区,那么就可以被同一个组内的多少个消费者消费

Comsumer group是kafka提供的可扩展且具有容错性的消费者机制

一个消费者组可以包含多个消费者

一个消费者组有一个唯一的ID(group id)

组内的消费者一起消费主体的所有分区数据

分区(partition)

在kafka集群中,主题 被分为多个分区

副本(Replicas)

副本可以确保某个服务器出现故障时,确保数据依然可用

Kafka中,一般都会设计副本的个数>1

主题(topic)

主题是一个逻辑概念,用于生产者发布数据,消费者拉取数据

Kafka中的主题必须要有标识符,二期是唯一的,kafka中可以有任意数量的主题,没有数量上的限制

在主题中的消息是有结构的,一般一个主题包含某一类消息

一旦生产者发送消息到主题中,这些消息就不背更新(更改)

偏移量(offset)

Offset记录者下一条江要发送给consumer的消息的序号

默认kafka江offset存储在zookeeper中

在一个分区中,消息是有顺序的方式存储着,每个在分区的消费都是有一个递增的id,这个就是偏移量的offset

偏移量在分区中才是有意义的。在分区之间,offset是没有任何意义的

Kafka生产者幂等性

Kafka中生产者生产消息到partition,如果直接发送消息,Kafka会将消息保存到分区中,单kafka会返回一个ack给生产者,表示当前操作是否成功,是否已经保存了这条消息,如果ack响应的过程失败了,此时生产者会重试,继续发送没有发送成功的消息,kafka优惠保存一条一摸一样的消息

在kafka中可以开启幂等性

当kafka的生产者生产消息时,会增加一个pid(生产者的唯一编号)和sequence number(针对消息的一个递增序列)

发送消息,会连着pid和sequence number 一并保存下来

如果ack响应失败,生产者重试,再次发送消息时,kafka会根据pid,sequence number是否需要在保存一条消息

判断条件:生产者发送过来的色quence number 是否小于等于partition中消息对应的sequence

Kafka中的分区副本机制

生产者写入分区策略

一个topic有多个分区

轮训策略:(按照消息尽量保证每个分区的负载)策略,消息会均匀的分布到每个oartition

写入消息的时候,可以为null的时候好,默认使用的是轮训策略

随机策略(不使用)

按key分配策略,可以.hash()%分区的数量

自定义分区策略(类似于MapReduce指定分区)

乱序问题

在Kafka中生产者是有写入策略,如果topic有多个分区,就会将数据分散在不同的partition中存储

当partition数量大于1的时候,数据(消息)会打散在不同的partition中

如果只有一个的分区,消息是有序的

Kafka中的消息是全局乱序的,局部partition是有序的

如果外卖要实现消息总说有序的,可以将连续的消息放到一个partition,但kafka就失去了分布式的意义

消费者组Consumer Group Rebalance机制

再均衡:

在某些情况下,消费者组中的消费者消费的分区会产生变化,会导致消费者分配不均匀(例如:有两个消费者消费3个,因为某个partition崩溃了,还有一个消费者当前没有分区要削峰),kafka Consumer Group就会启用rebalance机制,重新平衡这个Consumer Group内的消费者消费的分区分配

触发机制

消费者数量发送变化:

1.某个消费者crash

2.新增消费者

Topic的数量发送变化

1.某个topic被删除

partition的数量发送变化

1.删除partition

2.新增partition

不良影响

发送rebalance,所有的consumer将不再工作,共同来参与再均衡,直到每个消费者都已经被成功分配所需要消费的分区为止(rebakance结束)

消费者的分区分配策略

分区分配策略:保障每个消费者尽量能够均衡的消费分区的数据,不能出现某些消费者消费分区的数量特别多,某个消费者消费的分区特别少

Range分配策略(返回分配策略):kafka默认的分配策略

n:分区的数量/消费者数量

m:分区的数量%消费者数量

前m个消费者消费n+1个分区

剩余的消费者n个分区

RoundRobin分配策略(轮询分配策略)

消费者挨个分配消费的分区

Skriky粘性分配策略

在没有发送rebalance跟轮询分配策略是一致的

在发生了rebalance,轮询分配测试,重新走一遍轮询分配的过程。二粘性会保证跟上一次的尽量一致,至少将新的需要分配的分区,均匀的分配到现有可用的消费者中即可

减少上下文的切换

副本的ACK机制

Producer是不断的往kafka中写入数据,写入数据会有一个返回结果,表示是否写入成功。这里对应有一个ACKs的配置

acks=0:生产者只管写入,不管是否写入成功,可能会数据丢失。性能是最好的

acks=1:生产者会等到leader分区写入成功后,返回成功,接着发送下一条

acks=-1/all:确保消息写入到leader分区、还确保消息写入到对应副本都成功后,接着发送下一条,性能是最差的

根据业务情况来选择ack机制,是要求性能最高,一部分火速数据丢失影响不大,可以选择0/1。如果要求数据一定不能丢失,就给配置为-1/all。

分区中是有leader和follower的概念,为了确保消费或者消费的数据寒山寺一致的,只能从分区leader去读写消息,follewer做的事情就是同步数据,Backup。

高级API(High-Level API)、低级API(Low-level API)

高级API就是直接让Kafka帮助管理、处理分配、数据

offset存储中ZK中

有kafka的rebalance来控制消费者分配的分区

开发起来比较简单,无需开发者关注底层细节

无法做到细颗粒度的控制

低级API:又便携的程序自己控制逻辑

自己来管理offset,可以将offset存储中ZK、mysql、Redis、HBase、Flink的状态存储

指定消费者拉取某个分区的是苏剧

可以做到细颗粒度的控制

原有的Kafka的策略会失效,需要我们自己来实现消费机制

Kafka的可视化工具kafka-eagle

kafka原理

leader和follower

leader与follower相对分区有意义,不是相对broker

Kafka在创建topic的时候好,会尽量分配分区在不同的broker中,其实就是负载均衡

Leader职责:读写数据

Follower职责:同步数据、参与选举(leader crash之后,会选举一个follower重新称为分区leader

注意和zookeeper区分

zk的leader负责读、写,follower可以读取

Kafka的leader负责读写、follower不能读写数据(确保每个消费者的数据是一致的),kafka一个topic有多个分区leader,一样可以实现数据操作的负载均衡

AR/ISR/OSR

AR指的是一个topic分区的全部副本

ISR指的是正在同步的副本(当前有几个follower存活的)

OSR指的是不再同步的副本

AR=ISR+OSR

leader选举

Controller:controller是kafka集群的老大,是针对Broker的一个角色

Controller是2高可用的,是用过zzk来进行选举

Leader:是针对partition的一个角色

Leader是通过ISR来进行快速选举

如果kafka是基于ZK来进行选举,ZK的压力可能会比较大。例如:某个节点崩溃,这个节点上不仅仅只有一个leader,是有不少的leader需要选举。通过ISR快速进行选举

leader的负载均衡

如果某个broker crash之后,就可能会导致partition的leader分布不均匀,就是一个broker上存在一个topic下不停partition的leader

通过一下指令,可以将leader分配到有限的leader对应的broker,确保leader是均匀的

重启指定节点下的分区命令:

bin/kafka-leader-election.sh —bootstrap-server node1.itcast.cn:9092 —topic test —partition=2 —election-type preferred

node1.itcast.cn:9092kafka节点名称和端口号

partition=2:数字2是重启的那个leader

Kafka的读写流程

写流程:通过zookeeper找到partition对应的leader,leader是负责读写的

producer开始找写入数据

ISR里面的foolower开始同步数据,并返回给leader ACK

返回给producerACK

读流程:通过zookeeper找partition对应的leader,leader是负责读的

通过zookeeper找到消费者对应的offset

然后开始offset往后顺序拉取数据

提交offfset(自动提交—每个多少秒体检一次offset、手动提交—放入到事物中提交)

Kafka的物理存储

稠密索引和稀疏索引

因为消费者对应的offset是针对整个分区的,而消息是存储在具体某一个segment段中,所以需要通过这个offset,找到在当前这个segment中的offset

Kafka的数据组织结构

Topic->partition->segment->.log数据文件、.inexd(稀疏索引)、.timeindex(根据时间做的索引)

深入了解读数据的流程

消费者者的offset是一个针对partition全局offset

可以根据这个offset找到segment段

接着需要将全局的offset转换成segment的局部offset

根据局部的offset,就可以从(.index稀疏索引)找到对应的数据位置

开始顺序读取

 消息传递的语义性

Finl里面有对应的每种不同机制的保障,提供Exactly-Once保障(二阶段事物提交方式)

At-most once:最多一次(直接把 数据消费到,不管有没有成功,可能会有数据丢失)

At-least once:最少一次(有可能会出现重复消费)

Exactly-Once:仅有一次(事物性的保障,保证消息有且仅被处理一次)

Kafka的消息不丢失

Broker消息不丢失:因为有副本relicas的存在,会不断的从leader中通不副本,所以,一个broker crash,不会导致数据丢失,除非是只有一个副本

生产者消息不丢失:ACK机制(配置成ALL/-1)、配置0或者1可能会存在丢失

消费者消费不丢失:重点控制offset

At-least once:一种数据可能会重复消费

Exactly-Once:仅有一次

Kafka数据积压

数据积压值得是消费者因为有一些外部的IO、一些比较耗时的的操作(Full GC—Stop the world),就会造成消息在partition中一直存在得不到消费,就会产生是数据积压

在企业中,我们要有监控系统,如果出现这种情况,需要尽快处理。虽然后续的Spark Streaming/Flink可以实现背压机制,电脑上数据累积太多一定对实时性是有说影响的

数据积压的情况:

MySQL错误、网络延迟

Kafka中数据清理

两种清理方式:

日志清理(Log Deletion):按照指令的策略直接删除不符合条件的日志

日志压缩(Log Compaction):按照消息的key进行整合,有相同key的但有不同value值,只保留最后一个版本

日志删除

日志删除是以(segment日志)为单位来进行定期清理的

定时日记删除任务

定期检测和删除不符合保留提哦啊就的日记分段文件,周期默认是300000(五分钟),可以通过broker端参数log.retention.check.interval.ms来配置。

日志分段保留策略三种:

1.基于实际的保留策略

log.retention.hours

log.retention.minutes

log.retention.ms

2.基于日志大小的保留策略

3.基于日志起始偏移量的保留策略

删除日志分段时,将删除日志分段文件添加上“.deleted“的后缀,Kafka后台定时任务回定期删除这些文件,任务的延迟执行时间可以通过file.delete.delay.ms参数来设置,默认值为60000(一分钟)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值