【博学谷学习记录】超强总结,用心分享|Kafka的各类机制

文章详细介绍了Kafka的核心机制,包括Topic的分片和副本机制用于提高效率和数据可靠性,消息存储采用分文件方式,便于数据管理与删除。生产者数据分发涉及轮询、Hash取模和粘性分区策略,而消费者负载均衡确保每个分片仅被一个消费者接收,实现高效的消息处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【博学谷学习记录】超强总结,用心分享|Kafka的各类机制

Kafka的各类机制

1 Topic的分片和副本机制

(1)什么是分片?
分片:  逻辑概念
	相当于将一个Topic(大容器)拆分为N多个小容器, 多个小的容器构建为一个Topic。

目的:
	1- 提高读写的效率: 分片可以分布在不同节点上, 在进行读写的时候, 可以让多个节点一起参与(提高并行度);
	2- 分布式存储: 解决了单台节点存储容量有限的问题。
分片的数量:分片是可以创建N多个, 理论上没有任何的限制。 
(2)什么是副本?
副本: 物理的概念
	针对每个分片的数据, 可以设置备份, 可以将其备份多个。
	
目的: 
	提高数据的可靠性, 防止数据丢失。

副本的数量: 副本的数量最多和集群节点数量保持一致, 但是一般设置为 2个 或者 3个。

2 kafka的消息存储和查询机制

(1)kafka的消息存储机制

在这里插入图片描述

存儲路径:  /export/server/kafka/data

在此目录下,根据topic名称和分片编号创建一个目录,在此目录下存储对应分片的数据

1- Kafka中数据是存储在磁盘中,通过分文件的方式来存储的,一个log文件默认最大为1GB,当达到1GB后,就会滚动形成一个新的log文件,同时对应的index文件也会滚动形成一个新的文件;

2- 每一个消息数据片段都是由两个文件组成的:
      index文件: 对log文件中数据索引信息
      log文件: 存储是真正消息数据

3- 文件名表示什么?
      当前这个文件存储的消息起始偏移量

思考: kafka为啥要分文件的方式来存储数据呢?如果把数据放置到同一个文件中, 不更好嘛?

原因:  kafka本质是消息队列的中间件产品,当消息被消费者所消费后,存储在kafka中数据其实也就没啥用了,或者说随着时间的推移,存储在kafka的消息数据,其数据价值会越来越低的,所以说kafka存储数据仅仅是一种临时存储。

默认情况下,kafka会自动删除超过168小时(7天)的数据,通过分文件的方式,kafka只需要查看文件最后修改时间,如果超过7天,自动将其删除即可。

相关配置: server.properties
log.retention.hours=168 (小时)
log.segment.bytes=1073741824(1GB)
(2)kafka的查询机制
1- 确定消息被存储在那个segment片段中;
2- 先去对应segment片段中index文件,从这个索引文件中,查询对应消息偏移量,在log文件的什么位置上进行存储着;
3- 根据返回的log文件的具体的位置信息,底层会基于磁盘顺序查询方式查询log文件,找到对应位置上数据即可。

注意:
磁盘的读写方式主要有二种: 顺序读写随机读写
顺序读写的效率是远远高于随机读写的效率

3 kafka的生产者数据分发机制

生产者将数据生产到kafka的某个Topic中,Topic可以被分为多个分片的,最终一条消息只能被其中一个分片所接收,那么最终是有哪个分片来接收数据呢? 这就是生产者的分发机制。
Kafka支持的策略如下:
1- 轮询策略(2.4版本以下),目前为 粘性分发策略,是Java客户端拥有的;
2- Hash取模分发策略;
3- 指定分发策略;
4- 随机分发策略 (Python 客户端支持, Java 客户端不支持);
5- 自定义分区策略。

(1)指定分区策略
public ProducerRecord(String topic, Integer partition, K key, V value) {
        this(topic, partition, null, key, value, null);
}
在生产端, 构建数据承载对象的时候, 采用此构造方式, 即可实现指定分区的策略
分区编号: 从 0 开始
(2)Hash 取模分发策略
2.1 创建数据承载对象的时候, 必须使用仅传递 k 和 v的构造方法, 即可使用hash模式
public ProducerRecord(String topic, K key, V value) {
    this(topic, null, null, key, value, null);
}

2.2 当执行Hash取模分区策略,底层是通过一个默认的分区类实现完成Hash取模: DefaultPartitioner
public class DefaultPartitioner implements Partitioner {

    private final StickyPartitionCache stickyPartitionCache = new StickyPartitionCache();
	// 执行分区的核心方法, 返回内容表示将当前这条数据发送到那个分片上
    public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
        if (keyBytes == null) {
            return stickyPartitionCache.partition(topic, cluster);
        } 
        List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
        int numPartitions = partitions.size();
        // hash the keyBytes to choose a partition
        return Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
    }

说明: 在使用此种分发策略的时候, key值一定是可变的, 千万不要固定不变
(3)粘性分区策略
3.1 创建生产者的数据承载对象的时候, 只需要传递value即可, 此时底层会采用粘性的分区策略
public ProducerRecord(String topic, V value) {
    this(topic, null, null, null, value, null);
}

3.2 当执行粘性分区策略,底层是通过一个默认的分区类实现完成Hash取模: DefaultPartitioner

public class DefaultPartitioner implements Partitioner {

    private final StickyPartitionCache stickyPartitionCache = new StickyPartitionCache();
	// 执行分区的核心方法, 返回内容表示将当前这条数据发送到那个分片上
    public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
        // 当key为null的时候, 执行的是粘性的分区策略
        if (keyBytes == null) {
            return stickyPartitionCache.partition(topic, cluster);
        } 
        List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
        int numPartitions = partitions.size();
        // hash the keyBytes to choose a partition
        return Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
    }

什么叫粘性分区策略:
	当生产者发送数据的时候, 一般都是采用异步()发送方案,当发送一批数据到Broker端后, 首先会随机的选择其中一个分片, 然后尽可能黏上这个分区, 将这一批的数据全部都交给这一个分区即可
	
什么是轮询策略: 
	当生产者发送数据的时候, 一般都是采用异步()发送方案,当发送一批数据到Broker端后, 根据topic的分片的数量, 将一批数据拆分为N多个小的批次, 一个批次对应一个分片, 然后写入到topic的各个分片上
	
粘性分区的优势:
	减少中间的这个切分的操作, 直接将一批数据全部写入到某一个分片上, 同时也减少了中间ack的响应的次数, 减少网络的带宽, 提升效率。但是如果生成的数量非常的块, 会导致大量的数据写入到同一个分片上, 无法解开。

4 kafka的消费者的负载均衡机制

在这里插入图片描述
Kafka的消费者负载均衡机制规定:
1- 在一个消费者组内,消费者的数量最多和所监听的topic的分片数量是相等的,如果有大于分片数量的消费者,一定会有消费者处于闲置的状态;

2- 在一个消费者组内,topic的一个分片的数据只能被一个消费者所接收,不允许出现一个分片被多个消费者所接收的情况,而一个消费者是可以接收多个分片的数据。

如何模拟点对点消费模式: 让所有监听这个topic的消费者,都处在同一个消费组内。
如何模拟发布订阅模式: 让所有监听这个topic的消费者都不在同一个消费组内。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值