Kafka

kafka知识记录

基本概念

  • Broker

    • 消息代理

  • Topic

    • 主题

  • Partition

    • 分区

    • 有序的、不可变的提交日志

  • Offset

    • 偏移量

  • Replication

    • 每个分区都有一个server作为leader,0个或多个server作为follower

    • 每个server可以作为多个分区的leader和其他若干个分区的follower

  • Producer

    • 生产者

    • 生产者决定将消息发送到哪个分区

  • Consumer

    • 消费者

    • 消费者通过Offset类记录消费位置

Topic(主题)

/*
kafka的消息存在topic中
topic类似于数据库中的表,通常将相同类型的消息,存储到同一个主题中
也可以将不同类型的消息,存储到同一个主题
topic属于半结构化的数据
*/

Partition(分区)

/*
主题下可以包含很多个分区
kafka是一个分布式的消息系统
一个主题下,不同的分区可以存储在不同的服务器上,这样就使得kafka具有很高的扩展性
可以通过调整分区的数量,节点的数量
​
分区保证了kafka的集群,可以线性扩展
如果分区只存在一份的话,一旦这个分区损坏;那么数据就会丢失,
kafka通过副本机制,保证数据的可靠性
*/

Offset

/*
分区是一个线性增长不可变的提交日志
当消息存储到分区中以后,消息就不可变更
kafka会为每个消息分配一个偏移量offset
Offset可以记录每条消息的位置,kafka通过偏移量来对消息进行提取;
但是没法对消息的内容进行检索和查询
​
偏移量在每个分区中是唯一的不可重复的。并且是递增的‘
不同分区之间的偏移量是可以重复的
*/

kafka中的消息记录

/*
Record 消息记录
key   value
kafka中的每条消息是以键值队的形式进行存储
*/

发送消息

/*
如果不指定key,即当key的值为空
当发送消息时,如果key值为空,那么kafka将以轮询的方式,将消息写入到不同的分区中
*/
​
/*
当指定key,发送消息时
具有相同key的消息,按照一定的顺序会被写入到同一个分区
*/

kafkaDataReplication

replication-factor=3

设置kafka副本的数量

 

kafka消息模型以及消息顺序

/*
分区是最小的并行单位,
一个消费者可以消费多个分区,
一个分区可以被多个消费者组里的消费者消费
但是:一个分区不能同时被同一个消费者组里的多个消费者消费
*/

生产者发送消息顺序

/*
同一个生产者发送到同一分区的消息,先发送的Offset比后发送的Offset小
同一个生产者发送不到不同分区的消息,消息顺序无法保证
*/

 

消费者消息顺序

/*
消费者按照消息在分区里存放的顺序进行消费的,
kafka只保证分区内的消息顺序,不保证分区间的消息顺序
​
​
*/

保证所有的消息都顺序消费

/*
1、设置一个分区,这样就可以保证所有消息的顺序,但失去了扩展性和性能
2、支持通过设置消息的key,相同key的消息会发送到同一个分区
*/

消息传递语义

  • 最多一次

    • 消息可能会丢失,永远不重复发送

  • 最少一次

    • 消息不会丢失,但是可能会重复

  • 精确一次

    • 保证消息被传递到服务端且在服务端不重复

正常发送流程

/*
当生产者向Broker发送一个消息时,Broker收到消息后,会告诉生产者这个消息收到了
*/

 

最多一次

最多一次:即生产者向消费者发送消息的时候就失败了,(即可能收到了,也可能没收到;但是生产者不管,就发送一次)broker没有收到,或者是在回值的过程中失败了,导致producer没有收到broker回复的消息,导致producer认为这个消息发送失败了

这时候不进行重试

至少一次

即消费者先从主题下的分区,先读取消息,后提交消费的offset

/*
producer成功的把消息发送到Broker。Broker也成功的把这个消息存放到服务端了,但是再回值告诉producer的时候失败了;这样producer没有收到消息,它会认为这个消息没有在服务端进行保存;那么这样生产者会进行重试,服务端就可能出现重复;这样叫做至少一次
​
etl往数仓提交kafka消息采取的策略就是这种,重试三次,如果还不行,任务就失败
*/

 

至多一次

先提交消费位置offset,再读取消息

精确一次

/*
通过offset来防止重复消费并不是一个好办法
通常在消息中加入唯一ID,例如:流水ID、订单ID,在处理业务时,通过判断ID来防止重复处理
*/

 

批量发送

二者满足其一就会触发发送

-- 每一批消息最大大小
props.put("batch.size",16384)
​
-- 延迟时间
props.put("linger.ms",1000)
​
-- etl往数仓发送消息,是按时间发送的,1秒大概能发送10000条左右把

kafka重复消费带来的问题

/*
数据不一致:如果消息被多次消费,可能会导致数据重复或丢失,从而导致数据不一致的问题。
​
资源浪费:多次消费相同的消息会导致系统资源的浪费,包括计算能力、内存、网络带宽等。这可能会影响系统的性能和可伸缩性。
​
业务逻辑错误:如果消费者处理消息的逻辑不正确,可能会导致意外的行为,例如意外更改数据库或发送不正确的通知等。
*/

怎么避免重复消费

/*
在生产者向Kafka发送消息时添加唯一标识,消费消息时候,做幂等性检查,即使发送多次,Kafka也只会将消息写入一次,从而保证消息的副本不会重复。
*/
posted @ 2023-03-18 22:04  无敌大牛牛  阅读(37)  评论(0编辑  收藏  举报