大数据面试重点之Kafka(五)

43 篇文章 1 订阅
43 篇文章 7 订阅

大数据面试重点之Kafka(五)
Kafka是如何进行数据备份的?
问过的一些公司:祖龙娱乐参考答案:
Kafka的备份的单元是partition,也就是每个partition都都会有leader partiton和follow partiton。其中leader partition是用来进行和producer进行写交互,follow从leader副本进行拉数据进行同步,从而保证数据的冗余,防止数据丢失的目的。

在这里插入图片描述

Kafka里面存的数据格式是什么样的?
问过的一些公司:阿里云,祖龙娱乐参考答案:
1、先介绍几个重要概念
Broker:消息中间件处理结点,一个Kafka节点就是一个broker,多个broker可以组成一个Kafka集 群;
Topic:一类消息,例如page view日志、click日志等都可以以topic的形式存在,Kafka集群能够同时负责多个topic的分发;
Partition:topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队;
Segment:每个partition又由多个segment file组成;
oGset:每个partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到partition 中。partition中的每个消息都有一个连续的序列号叫做offset,用于partition唯一标识一条消息; message:这个算是kafka文件中最小的存储单位,即是a commit log。
kafka的message是以topic为基本单位,不同topic之间是相互独立的。每个topic又可分为几个不同的partition,每个partition存储一部的分message。topic与partition的关系如下:
在这里插入图片描述
其中,partition是以文件夹的形式存储在具体Broker本机上。
2、partition中的数据文件1)segment中的文件
对于一个partition(在Broker中以文件夹的形式存在),里面又有很多大小相等的segment数据文件(这 个文件的具体大小可以在 config/server.properties 中进行设置),这种特性可以方便old segment file的快速删除。
partition中的segment file的组成:
segment file组成:由2部分组成,分别为index file和data file,这两个文件是一一对应的,后缀”.index”和”.log”分别表示索引文件和数据文件;
segment file命名规则:partition的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset,ofsset的数值最大为64位(long类型),20位数字字符长度,没 有数字用0填充。如下图所示:
在这里插入图片描述
关于segment file中index与data file对应关系图,这里我们选用网上的一个图片,如下所示:
在这里插入图片描述
segment的索引文件中存储着大量的元数据,数据文件中存储着大量消息,索引文件中的元数据指向对 应数据文件中的message的物理偏移地址。以索引文件中的 3,497 为例,在数据文件中表示第3个message(在全局partition表示第368772个message),以及该消息的物理偏移地址为497。
注:Partition中的每条message由offset来表示它在这个partition中的偏移量,这个offset并不是该Message 在partition中实际存储位置,而是逻辑上的一个值(如上面的3),但它却唯一确定了partition中的一条Message(可以认为offset是partition中Message的id)。
2)message文件
message中的物理结构为:
在这里插入图片描述
参数说明:

关键字 解释说明

8 byte offset 在parition(分区)内的每条消息都有一个有序的id号,这个id号被称为偏移(offset),它 可以唯一确定每条消息在parition(分区)内的位置。即offset表示partiion的第多少message
4 byte message size
message大小
4 byte CRC32 用crc32校验message
1 byte “magic” 表示本次发布Kafka服务程序协议版本号
1 byte “attributes” 表示为独立版本、或标识压缩类型、或编码类型
4 byte key length 表示key的长度,当key为-1时,K byte key字段不填
K byte key 可选
value bytes payload 表示实际消息数据

Kafka是如何清理过期文件的?
问过的一些公司:祖龙娱乐参考答案:
Kafka将数据持久化到了硬盘上,我们可以配置一定的策略对数据进行清理,清理的策略有两个:删除
和压缩。
数据清理方式一:删除
启用删除策略:

1 log.cleanup.policy=delete
直接删除,删除后的消息不可恢复。可配置以下两个策略: 清理超过指定时间清理:

1 log.retention.hours=16
超过指定大小后,删除旧的消息:

1 log.retention.bytes=1073741824
为了避免在删除时阻塞读操作,采用了copy-on-write形式的实现,删除操作进行时,读取操作的二分查 找功能实际是在一个静态的快照副本上进行的,这类似于Java的CopyOnWriteArrayList。
数据清理方式二:压缩

将数据压缩,只保留每个key最后一个版本的数据。
首先在broker的配置中设置 log.cleaner.enable=true 启用cleaner,这个默认是关闭的。在topic的配置中设置 log.cleanup.policy=compact 启用压缩策略。
压缩策略的细节
在这里插入图片描述
如上图,在整个数据流中,每个Key都有可能出现多次,压缩时将根据Key将消息聚合,只保留最后一次 出现时的数据。这样,无论什么时候消费消息,都能拿到每个Key的最新版本的数据。压缩后的offset可 能是不连续的,比如上图中没有5和7,因为这些offset的消息被merge了,当从这些offset消费消息时, 将会拿到比这个offset大的offset对应的消息,比如,当试图获取offset为5的消息时,实际上会拿到offset 为6的消息,并从这个位置开始消费。
这种策略只适合特俗场景,比如消息的key是用户ID,消息体是用户的资料,通过这种压缩策略,整个 消息集里就保存了所有用户最新的资料。
压缩策略支持删除,当某个Key的最新版本的消息没有内容时,这个Key将被删除,这也符合以上逻辑。

Kafka的一条message中包含了哪些信息?
问过的一些公司:祖龙娱乐参考答案:
具体字段解释如下:
CRC32:4个字节,消息的校验码。

magic:1字节,魔数标识,与消息格式有关,取值为0或1。当magic为0时,消息的offset使用绝对offset且消息格式中没有timestamp部分;当magic为1时,消息的offset使用相对offset且消息格式中 存在timestamp部分。所以,magic值不同,消息的长度是不同的。
attributes: 1字节,消息的属性。其中第0~ 2位的组合表示消息使用的压缩类型,0表示无压缩,1 表示gzip压缩,2表示snappy压缩,3表示lz4压缩。第3位表示时间戳类型,0表示创建时间,1表示 追加时间。
timestamp: 时间戳,其含义由attributes的第3位确定。
key length:消息key的长度。key:消息的key。
value length:消息的value长度。value:消息的内容

Kafka如何保证数据的Exactly Once?
问过的一些公司:360,美团,360社招,中信信用卡中心,Shopee(2021.08) 参考答案:
Kafka可以通过两种机制来确保消息消费的精确一次:
幂等性(Idempotence) 事务(Transaction)
1、幂等性:每个分区中精确一次且有序
将服务器的ACK级别设置为-1,可以保证Producer到Server之间不会丢失数据,即At Least Once语义。相对的,将服务器ACK级别设置为0,可以保证生产者每条消息只会被发送一次,即At Most Once语义。
At Least Once可以保证数据不丢失,但是不能保证数据不重复;相对的,At Least Once可以保证数据不重复,但是不能保证数据不丢失。但是,对于一些非常重要的信息,比如说交易数据,下游数据消费者 要求数据既不重复也不丢失,即Exactly Once语义。在0.11版本以前的Kafka,对此是无能为力的,只能保证数据不丢失,再在下游消费者对数据做全局去重。对于多个下游应用的情况,每个都需要单独做全 局去重,这就对性能造成了很大影响。
0.11版本的Kafka,引入了一项重大特性:幂等性。所谓的幂等性就是指Producer不论向Server发送多少 次重复数据,Server端都只会持久化一条。幂等性结合At Least Once语义,就构成了Kafka的Exactly Once语义。即:
At Least Once + 幂等性 = Exactly Once
要启用幂等性,只需要将Producer的参数中enable.idompotence设置为true即可。Kafka的幂等性实现其 实就是将原来下游需要做的去重放在了数据上游。开启幂等性的Producer在初始化的时候会被分配一个PID,发往同一Partition的消息会附带Sequence Number。而Broker端会对<PID, Partition, SeqNumber>做缓存,当具有相同主键的消息提交时,Broker只会持久化一条。
2、事务:跨分区原子写入
Kafka现在通过新的事务API支持跨分区原子写入。这将允许一个生产者发送一批到不同分区的消息,这 些消息要么全部对任何一个消费者可见,要么对任何一个消费者都不可见。这个特性也允许你在一个事 务中处理消费数据和提交消费偏移量,从而实现端到端的精确一次语义。下面是的代码片段演示了事务API的使用:

  1. producer.initTransactions();
  2. try {
  3. producer.beginTransaction();
  4. producer.send(record1);
  5. producer.send(record2);
  6. producer.commitTransaction();
  7. } catch(ProducerFencedException e) {
  8. producer.close();
  9. } catch(KafkaException e) {
  10. producer.abortTransaction(); 11 }
    12
    上面的代码片段演示了你可以如何使用新生产者API来原子性地发送消息到topic的多个partition。值得注 意的是,一个Kafka topic的分区中的消息,可以有些是在事务中,有些不在事务中。
    因此在消费者方面,你有两种选择来读取事务性消息,通过隔离等级“isolation.level”消费者配置表示:
    read_commited :除了读取不属于事务的消息之外,还可以读取事务提交后的消息。
    read_uncommited :按照偏移位置读取所有消息,而不用等事务提交。这个选项类似Kafka消费者的当前语义。
    为了使用事务,需要配置消费者使用正确的隔离等级,使用新版生产者,并且将生产者的“transactional.id”配置项设置为某个唯一ID。 需要此唯一ID来提供跨越应用程序重新启动的事务状态的连续性。

Kafka消费者怎么保证Exactly Once
问过的一些公司:快手 x 2
参考答案:
Consumer端丢失数据主要体现在:拉取了消息,并提交了消费位移,但是在消息处理结束之前突然发生 了宕机等故障。消费者重生后,会从之前已提交的位移的下一个位置重新开始消费,之前未处理完成的 消息不会再次处理,即相当于消费者丢失了消息。
解决Consumer端丢失消息的方法也很简单:将位移提交的时机改为消息处理完成后,确认消费完成了一 批消息再提交相应的位移。这样做,即使处理消息的过程中发生了异常,由于没有提交位移,下次消费 时还会从上次的位移处重新拉取消息,不会发生消息丢失的情况。
具体的实现方法为,Consumer在消费消息时,关闭自动提交位移,由应用程序手动提交位移。

Kafka监控实现?
问过的一些公司:腾讯参考答案:
几种监控工具对比:
Kafka Manager:雅虎出品,可管理多个Kafka集群,是目前功能最全的管理工具。但是注意,当你的Topic太多,监控数据会占用你大量的带宽,造成你的机器负载增高。其监控功能偏弱,不满足需求。
Kafka Offset Monitor:程序一个jar包的形式运行,部署较为方便。只有监控功能,使用起来也较为安全。

Kafka Web Console:监控功能较为全面,可以预览消息,监控Offset、Lag等信息,不建议在生产环境中使用。
Burrow:是LinkedIn开源的一款专门监控consumer lag的框架。支持报警,只提供HTTP接口,没有webui。
Availability Monitor for Kafka:微软开源的Kafka可用性、延迟性的监控框架,提供JMX接口,用的很少。

Kafka中的数据能彻底删除吗?
问过的一些公司:腾讯参考答案:
如果用kafka-topics.sh的delete命令删除topic,会有两种情况:

  1. 如果当前topic没有使用过即没有传输过信息:可以彻底删除。
  2. 如果当前topic有使用过即有过传输过信息:并没有真正删除topic只是把这个topic标记为删除
    (marked for deletion)。
    要彻底把情况2中的topic删除必须把kafka中与当前topic相关的数据目录和zookeeper与当前topic相关的 路径一并删除。

Kafka复制机制?
问过的一些公司:腾讯参考答案:
Kafka 主题中的每个分区都有一个预写日志(write-ahead log),我们写入 Kafka 的消息就存储在这里面。这里面的每条消息都有一个唯一的偏移量,用于标识它在当前分区日志中的位置。如下图所示:

Kafka 中的每个主题分区都被复制了 n 次,其中的 n 是主题的复制因子(replication factor)。这允许Kafka 在集群服务器发生故障时自动切换到这些副本,以便在出现故障时消息仍然可用。Kafka 的复制是以分区为粒度的,分区的预写日志被复制到 n 个服务器。 在 n 个副本中,一个副本作为 leader,其他副本成为 followers。顾名思义,producer 只能往 leader 分区上写数据(读也只能从 leader 分区上进行),followers 只按顺序从 leader 上复制日志。
在这里插入图片描述

日志复制算法(log replication algorithm)必须提供的基本保证是,如果它告诉客户端消息已被提交, 而当前 leader 出现故障,新选出的 leader 也必须具有该消息。在出现故障时,Kafka 会从挂掉 leader 的ISR 里面选择一个 follower 作为这个分区新的 leader ;换句话说,是因为这个 follower 是跟上 leader 写进度的。
每个分区的 leader 会维护一个 in-sync replica(同步副本列表,又称 ISR)。当 producer 往 broker 发送消息,消息先写入到对应 leader 分区上,然后复制到这个分区的所有副本中。只有将消息成功复制到所有同步副本(ISR)后,这条消息才算被提交。由于消息复制延迟受到最慢同步副本的限制,因此快速 检测慢副本并将其从 ISR 中删除非常重要。

Kafka分区多副本机制?
可回答:1)Kafka副本机制;2)Kafka副本同步策略;3)Kafka副本间怎么同步的 问过的一些公司:字节,京东,恒生电子,Shopee(2021.08),soul(2021.09)
参考答案:
Kafka为分区引入了多副本(Replica)机制,通过增加副本数量可以提升容灾能力。同一分区的不同副 本中保存的是相同消息(在同一时刻,副本之前并非完全一样),副本之间是“一主多从”的关系,其中leader副本负责处理读写请求,follower副本只负责与leader副本的消息同步。副本处于不同的broker
中,当leader副本出现故障时,从follower副本中重新选举新的leader副本对外提供服务。Kafka通过多副 本机制实现了故障的自动转义,当Kafka集群中某个broker失效时扔然能够保证服务可用。
如下图,Kfaka集群中有4个broker,某个主题中有3个分区,且副本因子(即副本个数)也为3,如此每 个分区便有1个leader副本和2个follower副本。生产者和消费者只与leader副本进行交互,而follower副本 只负责消息的同步,很多时候follower副本中的消息相对leader副本而言会有一定的滞后。
在这里插入图片描述
Kafka消费端也具备一定的容灾能力。Consumer使用拉(Pull)模式从服务端拉去消息,并且保存消费的 具体位置,当消费者宕机后恢复上线时可以根据之前保存的消费位置重新拉取需要的消息进行消费,这 样就不会造成消息丢失。
分区中的所有副本统称为 AR ( Assigned Replicas )。所有与 leader 副本保持一定程度同步的副本(包括leader 副本在内〕组成 ISR On-Sync Replicas ) ,ISR集合是 AR 集合中的一个子集 。 消息会先发送到leadr 副本,然后follower副本才能从 leader 副本中拉取消息进行同步,同步期间内 follower 副本相对于leader 副本而言会有一定程度的滞后。前面所说的“一定程度的同步”是指可忍受的滞后范围,这个范围可以通过参数进行配置。与 leader 副本同步滞后过多的副本(不包括 leader 副本)组成 OSR ( Out-of- Sync Replicas ),由此可见,AR=ISR+OSR。在正常情况下, 所有的 follower 副本都应该与 leader 副本保持一定程度 的同步,即 AR=ISR,OSR 集合为空。
leader 副本负责维护和跟踪 ISR 集合中所有 follower 副 本 的滞后状态, 当 follower 副本落后太多或失效时, leader 副本会把它从 ISR 集合中剔除 。 如果 OSR 集合中有 follower 副本 “追上’’了 leader 副本, 那么 leader 副本会把它从 OSR 集合转移至 ISR 集合 。 默认情况下, 当 leader 副本发生故障时,只 有在 ISR 集合中的副本才有资格被选举为新的 leader, 而在 OSR 集合中的副本则没有任何机会(不过这个原则也可以通过修改相应的参数配置来改变)。
ISR 与 HW 和 LEO 也有紧密的关系 。 HW 是 High Watermark 的缩写,俗称高水位,它标识了一个特定的消息偏移量( offset),消费者只能拉取到这个offset之前的消息 。如图所示,它代表一个日志文件, 这个日志文件中有 9 条消息,第一条消息的 offset( LogStartOffset )为 0,最后一条消息的 offset 为 8, offset 为 9 的消息用虚线框表示,代表下一条待写入的消息。日志文件的 HW 为 6,表示消费者只能拉取到 offset 在 0 至 5 之间的消息,而offset为 6 的消息对消费者而言是不可见的 。
在这里插入图片描述

LEO是Log End Offset 的缩写,它标识当前日志文件中下一条待写入消息 的 offset,图中offset 为 9 的位置即为当前日志文件的LEO, LEO的大小相当于当前日志分区中最后一条消息的offset 值加 1。分区ISR 集合中的每个副本都会维护自身的LEO ,而 ISR集合中最小的 LEO即为分区的LEO ,对消费者而言只能消费HW之前的消息。
为了让读者更好地理解 ISR 集合, 以及 HW 和 LEO 之间的关系, 下面通过一个简单的示例来进行相关的说明 。 如下图所示,假设某个分区的 ISR 集合中有 3 个副本,即一个 leader副本和 2 个 follower 副本,此时分区的 LEO 和 HW 都为 3 。
在这里插入图片描述
消息3和消息4从生产者发出之后会被先存入leader副本,如下图所示
在这里插入图片描述
在消息写入 leader 副本之后, follower 副本会发送拉取请求来拉取消息 3 和消息 4 以进行消息同步。在同步过程中,不同的 follow副本的同步效率也不尽相同。如下图所示, 在某一时刻follower1完全跟上了leader 副本而 follower2 只同步了消息 3 ,如此 leader 副本的 LEO 为 5,follower1 的 LEO 为 5 , follower2 的 LEO 为 4 , 那么当前分区的 HW 取最小值 4 ,此时消费者可以消 费到 offset 为 0 至 3 之间的消息。
在这里插入图片描述
写入消息情形如下图所示,所有的副本都成功写入了消息 3 和消息 4,整个分区的HW 和 LEO 都变为
5,因此消费者可以消费到 offset 为 4 的消息了 。
在这里插入图片描述
由此可见, Kafka 的复制机制既不是完全的同步复制,也不是单纯的异步复制。事实上,同步复制要求所有能工作的 follower 副本都复制完,这条消息才会被确认为已成功提交,这种复制方式极大地影响了性能。而在异步复制方式下, follower 副本异步地从 leader 副本中 复制数据,数据只要被 leader 副本写入就被认为已经成功提交。在这种情况下,如果 follower 副本都还没有复制完而落后于 leader 副本, 突然 leader 副本着机,则会造成数据丢失。 Kafka 使用的这种 ISR 的方式则有效地权衡了数据可靠性和性能之间的关系。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据小理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值