深入读懂 Kafka集群

image

前言

概述

Kafka是一个多分区、多副本的分布式流处理平台,以高吞吐、可持久化、可水平扩展、支持流数据处理等多种特性被广泛使用。

应用场景

(1)缓冲削峰:有利于解决生产消息和消费消息的处理速度不一致的情况,不会因为突发超负荷请求而崩溃,消息队列能够使用关键组件顶住突发和访问压力
(2)解耦:允许独立的扩展或修改队列两边的处理过程
(3)异步通信:允许用户将消息放入队列但不立即处理它

消息队列类型

(1)点对点模式
(2)发布/订阅模式 Topic队列

专有名词解释

(1)Leader:Kafka的Topic分区被划分为一个Leader副本和多个Follower副本,Producer和Consumer的请求都由Leader来响应
(2)ISR:(同步副本集)Leader以及与Leader保持同步的所有副本的集合,如果一个副本在30s内没有追上Leader的Log End Offset,就会被移除ISR集合,对应参数为replica.lag.time.max.ms
image
(3)LEO:全称Log End Offset,每一个副本的最后一个Offset,也就是副本当前Offset+1
(4)High Watermark:高水位线,所有副本当中最小的LEO+1

基础架构

Broker对应服务器,由多台Broker组成Kafka集群,每一个broker内可以包含多个消息队列,每一个Topic又可以划分多个分区存放于不同的Broker上,同一个分区可以设置多个副本,同一分区及其副本当中包含一个Leader副本和剩余的Follower副本,Leader副本负责对外提供读写服务,Follower副本只起到数据同步做高可用的作用,当Leader副本失效时其余Follower副本可以在短时间内选出新的Leader分区来对外提供服务。为提供消息的消费速度,消费者也可以由消费者构成消费者组,组内每个消费者只能对应消费一个topic分区的数据,换句话说也就是一个分区只能由一个组内消费者消费,不同消费者组之间互不影响。ps:消费者组是逻辑上的一个订阅者。

分区的好处

每一个Partition在一个broker上存储,可以把海量的数据按照分区切割成一块一块的存储在多台Broker上,合理控制分区的任务,能够实现一个消费者组在同一个Topic的多个分区并发消费,提高并发,达到负载均衡的效果,注意:同一Topic的多个分区在并发消费时并不能保证消费消息顺序的顺序,因为虽然每一个分区内的消息被索引并联同时间戳存储在一起,每个分区的数据因时间戳而有序(表现形式为一个个文文件夹)

副本的好处

副本机制也可以称作备份机制,在Kafka集群中分区多副本策略好处在于
(1)能够提够数据冗余,一定程度上保障高可用
Kafka是基于Leader-based的副本机制,一个分区的多个副本中包含一个Leader副本和Follower副本,Follower副本对外不提供服务,依托Kraft模式的kafka集群感知,会立即开启新一轮选举epoch,老Leader副本重新上线后只能作为follower副本加入到集群中

Partition与Topic的关系

(1)一个Partition只属于一个Topic,每一个Partition里的消息都是有序的
(2)一个Topic理论上可以拥有无数个Partition,过少不满足消费者组的并发,过多会占用内存和文件描述符
(3)同一个Topic的不同Partition内容不一样,每个分区对其上的消费者组都有详细Offset,在消费者者断线后可以通过Partition上记录上一次消费到的Offset来继续消费,保证了同一分区不重复消费。
(4)同一Topic不同的Partition能够分布到不同Broker上
(5)Partition规则设置得当能够使同一个Topic的消息均匀落在不同的Partition,如果消费者对消费的消息有强制的顺序要求,那么其消费的Topic只能设置Partition为一个,因为只有这样才可以因为

默认分区规则

(1)如果生产者没有指定分区,也没有指定Key,那么遵守Sticky Partition(粘性分区)策略,消息batch会尽可能均衡到某几个消息分区(也包含一定程度的轮询)

kafka在这里做了缓存,如果第一次获取到了粘性分区后面会缓存起来
 public int partition(String topic, Cluster cluster) {
        Integer part = indexCache.get(topic);
        if (part == null) {
            return nextPartition(topic, cluster, -1);
        }
        return part;
    }

(2)如果生产者没有指定分区,但是指定了Key,那么会通过对Key进行Hash操作来判断消息落在哪个分区上
(3)如果生产者指定了分区,那么消息会直接进入该分区

(4)自定义类实现Partitioner接口,重写Partition方法,补充接口的close和configure函数

同步复制和异步复制

同步复制
ACK=ALL
确保所有Follower副本从Leader副本拉取到了最新消息到本地Leader再向生产者发送ACK,这样才能保证Leader挂掉之后,Follow选举新Leader时新Leader存有完整数据;
异步复制
ACK=[数字number]
确保有指定数量number个Follower副本从Leader副本拉取到了最新消息到本地Leader再向生产者发送ACK,这样节省了时间,也保障了故障时的高可用

ISR In-Sync Replicas

如果采取所有副本同步完再让Leader节点发送ACK那遇到Follower故障时就会出现问题,为解决这个问题kafka开发者为Leader维护一个动态的ISR,只要ISR中已同步的副本数超过了我们设置的最小数,Leader就可以发送ACK了,

Kafka的删除策略

(1)由参数 log.retention.hours=168 控制,默认是7天,生产环境中建议根据数据量设置3天以下
也可以有Kafka管控平台进行设置
(2)由参数 log.retention.bytes=1073741820 保留最近GB数据
(3)也可以通过log.retention.bytes=compact设置保留参数,到期后消息不会被删除,但会被进行去重处理,但是设置这种模式要求每一个消息都设置Key

kafka数据IO中的零拷贝

深入Kafka之零拷贝技术By_Iamxiaofu

Unclean领导者选举

由于ISR是动态的,在某些故障情况下可能出现ISR为空的情况,导致Leader副本出现问题时没有Leader的备选Follower副本,此时Kafka提供了配置unclean.leader.election.enable ,此配置设置为true即允许在ISR集合为空的情况下,允许数据不完整的Follower副本选举为Leader,此举保证了业务的连续性,但是存在数据丢失的风险,不建议在敏感生产环境使用
CAP理论中此配置是牺牲了一致性,保证了高可用性

posted @ 2023-10-19 08:50  付同學  阅读(65)  评论(0编辑  收藏  举报