特点:
n-1
个节点失败)包括:
ISR:In-Sync Replicas,副本同步队列
OSR:Out-of-Sync Replicas,非副本同步队列
AR:Assigned Replicas所有副本
ISR是由Leader维护,Follower从Leader同步数据有一些延迟,超过配置的阈值会把Follower剔除出ISR,存入OSR列表,新加入的Follower也会先存放在OSR中。AR=ISR+OSR。
Offset:偏移量
LEO:Log End Offset,当前日志文件中下一条,每个副本最大的Offset
HW:High Watermark,高水位,通常被用在流式处理领域,以表征元素或事件在基于时间层面上的进度。是ISR队列中最小的LEO。消费者最多只能消费到HW所在的位置上一条信息。
LSO:Last Stable Offset,对未完成的事务而言,LSO的值等于事务中第一条消息的位置(First Unstable Offset),对已完成的事务而言,它的值同HW相同
LW:Low Watermark,低水位,代表AR集合中最小的LSO值。
Kafka的负载均衡就是每个Broker都有均等的机会为Kafka的客户端(生产者与消费者)提供服务,可以将负载分散到集群中的所有机器上。通过智能化的分区领导者选举来实现负载均衡,可在集群的所有机器上均匀分散各个Partition的Leader,从而整体上实现负载均衡。
故障分Follower故障和Leader故障:
Follower发生故障后会被临时踢出ISR,待该Follower恢复后,Follower会读取本地磁盘记录的上次的HW,并将log文件高于HW的部分截取掉,从HW开始与Leader进行同步。等该Follower的LEO大于等于该Partition的HW,即Follower追上Leader后,可重新加入ISR。
Leader发生故障后,会从ISR中选出一个新的Leader,为保证多个副本之间的数据一致性,其余的Follower会先将各自的log文件高于HW的部分截掉,然后从新的Leader同步数据。
注意:这只能保证副本之间的数据一致性,并不能保证数据不丢失或者不重复
Kafka的故障转移是通过使用会话机制实现的,每台Kafka服务器启动后会以会话的形式把自己注册到ZK服务器上。一旦服务器运转出现问题,就会导致与ZK的会话不能维持从而超时断连,此时Kafka集群会选举出另一台服务器来完全替代这台服务器继续提供服务。
Q:分区的作用?
A:实现Broker负载均衡。对于消费者来说,提高并发度。
Q:一个Topic对应几个Partition?
Q:分区取值原则?
A:按照如下顺序判断:
Q:Kafka分区数可以增加或减少吗?
A:可使用bin/kafka-topics.sh
命令增加Kafka的分区数,但不支持减少分区数。
Kafka分区数据不支持减少是由很多原因的,比如减少的分区内数据放到哪里去?是删除,还是保留?删除的话,这些没消费的消息不就丢了。如果保留这些消息如何放到其他分区里面?追加到其他分区后面的话那么就破坏Kafka单个分区的有序性。如果要保证删除分区数据插入到其他分区保证有序性,实现起来逻辑就会非常复杂。
Q:Kafka新建的分区会在哪个目录下创建?
A:在启动Kafka集群之前,需提前配置好log.dirs
或log.dir
参数,其值是Kafka数据的存放目录,可配置多个目录,使用逗号分隔,通常这些目录是分布在不同的磁盘上用于提高读写性能。
如果log.dirs
参数只配置一个目录,那么分配到各个Broker上的分区肯定只能在这个目录下创建文件夹用于存放数据。
如果log.dirs
参数配置多个目录,Kafka会在哪个文件夹中创建分区目录呢?Kafka会在含有分区目录最少的文件夹中创建新的分区目录,分区目录名为Topic名+分区ID
。分区文件夹总数最少的目录,而不是磁盘使用量最少的目录!即,如果你给log.dirs
参数新增一个新的磁盘,新的分区目录肯定是先在这个新的磁盘上创建直到这个新的磁盘目录拥有的分区目录不是最少为止。
Producer有三种ACK机制
有两种:
方案 | 优点 | 缺点 |
---|---|---|
半数以上完成同步,就发送ACK | 延迟低 | 选举新Leader,容忍n台节点的故障,需2n+1 个副本 |
全部完成同步,才发送ACK | 选举新Leader,容忍n台节点的故障,需n+1 个副本 | 延迟高 |
选方案二原因:
n+1
个副本,因Kafka每个分区都有大量的数据,第一种方案会造成大量数据的冗余不能保证消息不丢失,只能尽力。措施如下:
Kafka不能完全保证消息的重复发送和投递,需要借助于业务系统。可从三个端来保证消息的唯一性:
和上面的去重,很多场景下是一回事。
Kafka中的每个Partition中的消息在写入时都是有序的,一个Partition只能由一个消费者去消费,可以在里面保证消息的顺序性。但是分区之间的消息是不保证有序的。
在创建一个消费者程序时,如果没有指定消费者组ID,则该消费者程序会被分配到一个默认的消费者组。
对应源码org.apache.kafka.clients.consumer.KafkaConsumer
,实现Consumer
接口。
在Kafka 0.10.0.x版本以前,消费状态信息维护在ZK集群里,以后的版本,维护在两个地方:
__consumer_offsets
__consumer_offsets
以消费者组(Group)、主题(Topic)和分区(Partition)作为组合主键,所有消费者程序产生的偏移量都会提交到该内部主题中进行存储。极端重要数据,故而设置其应答Ack级别设置为−1。
即Rebalance,重新均衡消费者消费,在同一个消费者组当中,分区的所有权从一个消费者转移到另外一个消费者。会触发Rebalance机制的场景:
Rebalance的过程如下:
GroupCoordinator,负责协调多个消费者之间的行为,以确保他们能够正确地从Kafka主题中消费数据。由Kafka集群中的一个或多个服务器组成,主要作用包括:
对应源码org.apache.kafka.clients.consumer.internals.ConsumerCoordinator
:
实现原理:
每个消费者从属于消费组。具体关系如下:
消费者组特性:
消费者程序的数量尽量不要超过主题的最大分区数,多出来的消费者程序是空闲的,会浪费系统资源。
比如RabbitMQ,ActiveMQ,RocketMQ,Apache Pulsar。
Apache Kafka和Apache Pulsar都是流处理平台,用于处理和传输大规模的实时数据流。尽管它们在目标上有很多相似之处,但在架构、特性、性能等方面存在显著差异。以下是两者的详细对比:
架构
消息模型
性能和可扩展性
消费者模型
功能特性
社区和生态系统
Kafka适合需要高吞吐量、简单架构以及现有生态系统支持的场景,尤其是在需要复杂流处理的情况下。
Pulsar则在多租户支持、动态扩展、延迟消息处理等方面表现出色,适合需要灵活消费模式和复杂存储管理的场景。
Kafka控制器在启动时会创建一个独立的删除线程,用来执行主题删除操作。删除线程会检测删除的主题集合是否为空:
Kafka各Broker在启动时都要在ZK上注册,由ZK统一协调管理。如果任何节点失败,可通过ZK从先前提交的偏移量中恢复,因为它会做周期性提交偏移量工作。同一个Topic的消息会被分成多个分区并将其分布在多个Broker上,这些分区信息及与Broker的对应关系也是ZK在维护。
Kafka 2.8.0版本引入Kafka原生集群管理新特性,官方说法是Kafka Raft Metadata Mode。Kafka可以独立运行,不再强制依赖于ZK来提供集群管理和元数据存储功能。
基于Raft一致性协议实现,使得Kafka Broker可以直接通过Raft协议来选举领导者和维护元数据的一致性,减少外部依赖,使Kafka集群的部署和维护更简单。
Producer将消息Push到Broker集群,Consumer从Broker集群Pull消息。
纵观各大消息中间件,Producer将消息Push到Broker集群。Apache Pulsar可能是唯一的例外,Broker可以主动从Producer拉取消息,而不是等待Consumer。在某些特定场景下可能会有用,如需要Broker对消息进行一些处理或者过滤,然后再转发给Consumer。
消息如何从Broker触达到Consumer,各大中间件的实现有Push和Pull模式的不同。如Scribe和Flume采用push模式,即Broker将消息推送到下游的Consumer。
Push模式的缺点:由Broker决定消息推送的速率,对于不同消费速率的Consumer就不太好处理。消息系统都致力于让Consumer以最大的速率快速消费消息,当Broker推送速率远大于Consumer消费速率时,Consumer可能会崩溃。
Pull模式的好处:Consumer可以自主决定是否批量的从broker拉取数据。Push模式必须在不知道下游Consumer消费能力和消费策略的情况下决定是立即推送每条消息还是缓存之后批量推送。如果为了避免Consumer崩溃而采用较低的推送速率,将可能导致一次只推送较少的消息而造成浪费。Pull模式下,Consumer就可以根据自己的消费能力去决定这些策略。
Pull的缺点:如果Broker没有可供消费的消息,将导致Consumer不断在循环中轮询,直到新消息到达。为了避免这点,Kafka有个参数可以让Consumer阻塞知道新消息到达(当然也可以阻塞直到消息的数量达到某个特定的量),这样就可以批量发。
消息传输的事务(又叫消息投递语义)定义通常有以下三种级别:
分为Linux和Windows版;随着Kafka版本的迭代更新,脚本数量一直在新增。每个脚本的使用又有相应的参数和用途,虽然不同脚本之间参数的命名和用途有迹可循,都有规律。
需要另起一篇。面试时提到2~3个即可。
和上面的脚步有部分重复:
一台Kafka服务器就是一个Broker,集群由多个Broker组成,一个Broker可以容纳多个Topic。
如何判断一个Broker是否还存活?
配置文件:
server.properties
:producer.properties
:consumer.properties
:zookeeper.properties
:包括:
Kafka的设计是把所有的消息都写入速度低容量大的硬盘,以此来换取更强的存储能力,但实际上,使用硬盘并没有带来过多的性能损失。技术要点:
顺序读写
操作系统每次从磁盘读写数据的时候,需要先寻址,也就是先要找到数据在磁盘上的物理位置,然后再进行数据读写,如果是机械硬盘,寻址就需要较长的时间。
Kafka的设计中,数据其实是存储在磁盘上面,一般来说,会把数据存储在内存上面性能才会好。
但是Kafka用的是顺序写,追加数据是追加到末尾,磁盘顺序写的性能极高,在磁盘个数一定,转数达到一定的情况下,基本和内存速度一致。
随机写的话是在文件的某个位置修改数据,性能会较低。
消息格式经过四次大变化。
Kafka中消息是以Topic进行分类,生产者通过Topic向broker发送消息,消费者通过Topic读取数据。物理层面,一个Topic可以分成若干个Partition,Partition还可以细分为segment:
多租户技术,Multi-Tenancy Technology,是一种软件架构技术,实现如何在多用户的环境下共用相同的系统或程序组件,并且仍可确保各用户间数据的隔离性。
通过配置哪个主题可以生产或消费数据来启用多租户,也有对配额的操作支持。管理员可以对请求定义和强制配额,以控制客户端使用的Broker资源。
Kafka集群的监控是确保其性能和稳定性的重要组成部分。有效的监控可以帮助预防问题,快速定位和解决故障,保障系统的正常运行。
监控的关键指标如下:
Broker的CPU、内存和磁盘使用情况
网络流量和I/O性能
活跃的Controller数量
每个主题和分区的消息吞吐量。
副本同步情况ISR
分区的日志大小和滞后情况
生产者的消息发送速率和失败率
请求的延迟时间
消费者的消费速率和失败率
消费者延迟(消费滞后)
ZK节点的状态和会话数
ZK的请求处理延迟
常用监控方案:
kafka-topics.sh
:管理和查看主题信息kafka-consumer-groups.sh
:管理和查看消费者组信息kafka-configs.sh
:查看和修改配置kafka-run-class.sh kafka.tools.GetOffsetShell
:获取主题的最新偏移量在0.9版本之前,Kafka集群是没有安全机制的。当前Kafka系统支持多种认证机制:SSL、SASL/Kerberos、SASL/PLAIN、SASL/SCRAM。
认证范围包括: