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也只会将消息写入一次,从而保证消息的副本不会重复。
*/