1、简述下使用 Kafka的原因。
(1)缓冲和削峰:上游数据时有突发流量,下游可能扛不住,或者下游没有足够多的机器来保证冗余,kafka 在中间可以起到一个缓冲的作用,把消息暂存在 kafka 中,下游服务就可以按照自己的节奏进行慢慢处理。
(2)解耦和扩展性:项目开始的时候,并不能确定具体需求。消息队列可以作为一个接口层,解耦重要的业务流程。只需要遵守约定,针对数据编程即可获取扩展能力。
(3)冗余:可以采用一对多的方式,一个生产者发布消息,可以被多个订阅 topic的服务消费到,供多个毫无关联的业务使用。
(4)健壮性:消息队列可以堆积请求,所以消费端业务即使短时间死掉,也不会影响主要业务的正常进行。
(5)异步通信:很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。
2、Kafka 消费过的消息如何再消费?
kafka 消费消息的 offset 是定义在 zookeeper 中的,如果想重复消费 kafka 的消息,可以在 redis 中自己记录 offset 的 checkpoint 点(n 个),当想重复消费消息时,通过读取 redis 中的 checkpoint 点进行 zookeeper 的 offset 重设,这样就可以达到重复消费消息的目的了。
3、Kafka 的数据是放在磁盘上还是内存上,为什么速度会快?
磁盘存储。
速度快的原因:
(1)顺序写入:因为硬盘是机械结构,每次读写都会寻址->写入,其中寻址是一个“机械动作”,它是耗时的。所以硬盘 “讨厌”随机 I/O, 喜欢顺序 I/O。为了提高读写硬盘的速度,Kafka 就是使用顺序 I/O。
(2)Memory Mapped Files(内存映射文件):64 位操作系统中一般可以表示20G 的数据文件,它的工作原理是直接利用操作系统的 Page 来实现文件到物理内存的直接映射。完成映射之后你对物理内存的操作会被同步到硬盘上。
(3) Kafka 高效文件存储设计: Kafka 把 topic 中一个 parition 大文件分成多个小文件段,通过多个小文件段,就容易定期清除或删除已经消费完文件,减少磁盘占用。通过索引信息可以快速定位 message和确定response的 大小。通过 index 元数据全部映射到 memory(内存映射文件), 可以避免segment file 的 IO 磁盘操作。通过索引文件稀疏存储,可以大幅降低 index文件元数据占用空间大小。
4、Kafka 数据怎么保障不丢失?
保障数据不丢失,主要分三块:生产者端、消费者端和broker 端。
(1)生产者数据的不丢失:kafka 的 ack 机制,在 kafka 发送数据的时候,每次发送消息都会有一个确认反馈机制,确保消息正常的能够被收到,其中状态有 0,1,-1。
(2)消费者数据的不丢失:通过offset commit 来保证数据的不丢失,kafka自己记录了每次消费的offset数值,下次继续消费的时候,会接着上次的 offset进行消费。
(3)kafka 集群中的 broker 的数据不丢失:每个 broker 中的 partition 我们一般都会设置有 replication(副本)的个数,生产者写入的时候首先根据分发策略(有 partition 按 partition,有 key 按 key,都没有轮询)写入到 leader 中,follower(副本)再跟 leader 同步数据,这样有了备份,也可以保证消息数据的不丢失。
5、采集数据为什么选择 Kafka?
Flume:Flume 是管道流方式,提供了很多的默认实现,让用户通过参数部署,及扩展 API. Kafka:Kafka 是一个可持久化的分布式的消息队列。 Kafka 是一个非常通用的系统。你可以有许多生产者和很多的消费者共享多个主题 Topics。
相比之下,Flume 是一个专用工具被设计为旨在往 HDFS,HBase 发送数据。它对HDFS 有特殊的优化,并且集成了 Hadoop 的安全特性。所以,Cloudera 建议如果数据被多个系统消费的话,使用 kafka;如果数据被设计给 Hadoop 使用,使用 Flume。
6、Kafka 重启会导致数据丢失吗?
(1)kafka 是将数据写到磁盘的,一般数据不会丢失;
(2)但是在重启 kafka 过程中,如果有消费者消费消息,那么 kafka 如果来不及提交 offset,可能会造成数据的不准确(丢失或者重复消费)。
7、Kafka 宕机了如何解决?
(1)先考虑业务是否受到影响:kafka 宕机了,首先我们考虑的问题应该是所提供的服务是否因为宕机的机器而受到影响,如果服务提供没问题,如果实现做好了集群的容灾机制,那么这块就不用担心了。
(2) 节点排错与恢复:想要恢复集群的节点,主要的步骤就是通过日志分析来查看节点宕机的原因,从而解决,重新恢复节点。
8、为什么 Kafka 不支持读写分离?
在 Kafka 中,生产者写入消息、消费者读取消息的操作都是与 leader 副本进行交互的,从 而实现的是一种主写主读的生产消费模型。 Kafka 并不支持主写从读,因为主写从读有 2 个很明显的缺点:数据一致性问题和延时问题。
kafka 的主写主读的优点:
(1)可以简化代码的实现逻辑,减少出错的可能;
(2) 将负载粒度细化均摊,与主写从读相比,不仅负载效能更好,而且对用户可控;
(3) 没有延时的影响;
(4)在副本稳定的情况下,不会出现数据不一致的情况。
9、Kafka 数据分区和消费者的关系?
每个分区只能由同一个消费组内的一个消费者(consumer)来消费,可以由不同的消费组的消费者来消费,同组的消费者则起到并发的效果。
10、简述下Kafka 的数据 offset 读取流程。
(1)连接 ZK 集群,从 ZK 中拿到对应 topic 的 partition 信息和 partition 的 Leader的相关信息;
(2)连接到对应 Leader 对应的 broker;
(3) consumer 将⾃自⼰己保存的 offset 发送给 Leader;
(4)Leader 根据 offset 等信息定位到 segment(索引⽂文件和⽇日志⽂文件);
(5)根据索引⽂文件中的内容,定位到⽇日志⽂文件中该偏移量量对应的开始位置读取相应⻓长度的数据并返回给 consumer。
11、Kafka 内部如何保证顺序,结合外部组件如何保证消费者的顺序?
kafka 只能保证 partition 内是有序的,但是 partition 间的有序是没办法的。
12、Kafka 消息数据积压,Kafka 消费能力不足怎么处理?
(1) 如果是 Kafka 消费能力不足,则可以考虑增加 Topic 的分区数,并且同时提升消费组的消费者数量,消费者数=分区数。(两者缺一不可);
(2)如果是下游的数据处理不及时:提高每批次拉取的数量。批次拉取数据过少(拉取数据/处理时间<生产速度),使处理的数据小于生产的数据,也会造成数据积压。
13、Kafka 单条日志传输大小。
kafka对于消息体的大小默认为单条最大值是1M但是在我们应用场景中, 常常会出现一条消息大于 1M,如果不对 kafka 进行配置。则会出现生产者无法将消息推送到 kafka 或消费者无法去消费 kafka 里面的数据, 这时我们就要对 kafka 进行以下配置:server.properties
replica.fetch.max.bytes: 1048576 broker 可复制的消息的最大字节数, 默认为 1M;
message.max.bytes: 1000012 kafka 会接收单个消息 size 的最大限制, 默认为 1M 左右。