Kafka面试题

101 阅读4分钟

1.Kafka分区器

  • 指明了partition,直接使用该partition
  • 指明了key,分区 = hash(key) % topic分区数
  • 没有partition & key, => 随机数 % topic分区数,下一次随机数自增

在之前的例子里(Kafka生产者——向Kafka写入数据).ProducerRecord对象包含了目标主题topic、键key和值value。Kafka的消息是一个个键值对,ProducerRecord对象可以只包含目标主题和值,键可以设置为默认的null,不过大多数应用程序会用到键。键有两个用途:可以作为消息的附加信息,也可以用来决定消息该被写到主题的哪个分区。拥有相同键的悄息将被写到同一个分区

1.png

我们需要将 producer 发送的数据封装成一个 ProducerRecord 对象 2.png

如果键值为null.井且使用了默认的分区器,那么记录将被随机地发送到主题内各个可用的分区上。分区器使用轮询(Round Robin)算法将消息均衡地分布到各个分区上。
如果键不为空,并且使用了默认的分区器,那么Kafka会对键进行散列(使用Kafka自己的散列算法,即使升级Java版本,散列值也不会发生变化),然后根据散列值把消息映射到特定的分区上。这里的关键之处在于,同一个键总是被映射到同一个分区上

只有在不改变主题分区数量的情况下,键与分区之间的映射才能保持不变。举个例子,在分区数量保持不变的情况下,可以保证用户045189的记录总是被写到分区34.

我们需要将 producer 发送的数据封装成一个 ProducerRecord 对象

1.png

Kafka 有内部的 topic 吗?如果有是什么?有什么所用?

  • Kafka 0.9 版本之前,consumer 默认将 offset 保存在 Zookeeper 中,从 0.9 版本开始,consumer 默认将 offset 保存在 Kafka 一个内置的 topic 中,
  • 该 topic 为__consumer_offsets 保存消费者offset

简述 Kafka 的日志目录结构?

kafka 稀疏索引

想要查询速度的快,为数据添加索引是个常用的方法, kafka 也不例外,但不同的是 kafka 使用的是稀疏索引

常见的索引一般是保存数据集中每条记录的部分字段,例如关系型数据库中的索引都是这种。但稀疏索引不会为每条记录都建索引,而是隔一段建一条,因此被称为稀疏索引

稀疏索引最大的好处是节约了磁盘空间,但代价是,查找速度不如普通索引,因为你只能找到一个大致的区间,想要找到具体的记录,就需要遍历区间的数据,相当于拿时间换空间

由于 kafka 设计为循序读写磁盘,因此遍历区间的数据并对速度有太大的影响,而选择稀疏索引还能节约大量的磁盘空间。

1.png

  • Kafka 采取了分片和索引机制,将每个 partition 分为多个 segment
  • index 和 log 文件以当前 segment 的第一条消息的 offset 命名
  • 该文件夹的命名规则为:topic 名称+分区序号
  • index:索引信息 log:数据 timeindex:时间索引
  • 其中index、log、timeindex文件是二进制文本
  • snapshot:是kafka对幂等型或者事务型producer所生成的快照文件
  • 保存了每一任leader开始写入消息时的offset,会定时更新 ,follower被选为leader时会根据这个确定哪些消息可用

1.png 1.png

如果我指定了一个 offset,Kafka Controller 怎么查找到对应的消息?

2.png

  1. 首先根据二分查找法找到segment对应的00000000000000000000.index索引文件

  2. 根据offset=3找到索引文件中的位置,该位置保存了一个偏移量的值756,根据偏移量756在00000000000000000000.log文件中找到对应的消息Message-3。

  3. 首先根据二分查找法找到segment的对应的00000000000000000006.index索引文件

  4. 根据offset=8找到对应的索引文件中的位置,该位置保存了一个偏移量326,根据偏移量326在00000000000000000006.log文件中找到对应的消息Message-8。