大数据面试——kafka

一、kafka 基础概念

1.Apach Kafka

Apach Kafka 是一款分布式流处理框架,用于实时构建流处理应用。作为企业级的消息引擎被广泛使用。

2.生产者与消费者

  • 生产者(Producer):也称为发布者,创建消息
  • 消费者(Consumer):也称为订阅者,负责消费 or 读取消息
    在这里插入图片描述

3.主题与分区

3.1 定义

  • 主题(topic):Kafka中用于区分不同类别信息的类别名称。由producer指定
  • 分区(Partition):Topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)

3.2二者关系

Kafka的消息通过主题进行分类。主题就好比数据库的表,或者文件系统里面的文件夹。主题可以被分为诺干个分区,一个分区就是一个提交日志。消息以追加的方式写入分区,然后以陷入显出的顺序读取。一般一个主题包含几个分区,因此无法整个主题范围内保证消息的顺序,但可以保证消息在单个分区内的顺序。如下图所示的主题有四个分区,消息被追加写入每个分区的尾部。kafka通过分区来实现数据冗余和伸缩性。分区可以分布在不同的服务器上,也就是一个主题可以横跨多个服务器,一次来提供比单个服务器更大的性能。在这里插入图片描述
3.4Broker 和集群(Cluster)

  • **broker:**Kafka集群中的机器/服务被成为broker, 是一个物理概念
    一个独立的Kafka服务器称为broker,broker接收来自生产者的消息,为消息设置偏移量,并提交消息到磁盘保存。broker为消费者提供服务,对读取分区的请求作出相应,返回已经提交到磁盘上的消息。根据特定的硬件及其性能特征,单个broker可以轻松处理数千个分区以及每秒百万级的消息量
  • **Cluster:**多个 broker 可以组成的 Kafka 集群
    broker是集群的组成部分。每个集群都有一个broker同时充当了集群控制器的角色(自动从集群的活跃成员中选举出来)。控制器负责管理工作,包括将分区分配给broker和监控broker。在集群中,一个分区从属于一个broker,该broker被称为分区的首领。一个分区可以分配多个broker,这个时候会发生分区复制。这种复制机制为分区提供了消息冗余,如果一个broker失效,其他broker可以接管领导权。不过,相关的消费者和生产者都要重新连接到新的首领。
    在这里插入图片描述

保留消息是Kafka的一个重要特性。Kafka broker默认的消息保留策略有两种。

  • 保留一段固定的时间。比如7天。
  • 保留到消息达到一定大小的字节数,如1GB 当达到上限后,旧的消息会被过期删除。所以在任何时刻,可用消息的总量不会超过配置参数所指定的大小。
    3.5 多集群
    多集群的优势:基于数据的隔离、基于安全的隔离、多数据中心(容灾)
    Kafka的消息复制机制只能在单个集群里面进行,不能在多个集群之间进行。Kafka提供了一个叫做MirrorMaker的工具,可以用它来实现集群间的消息复制。MirrorMaker的核心组件包含了一个生产者和一个消费者,两者通过一个队列相连。消费者从一个集群读取消息,生产者把消息发送到另一个集群。
    在这里插入图片描述

4.消费者组(Consumer Group)

4.1消费者组的定义与原理

  • 定义:即消费者组是 Kafka 提供的可扩展且具有容错性的消费者机制。
  • 原理:在 Kafka 中,消费者组是一个由多个消费者实例 构成的组。多个实例共同订阅若干个主题,实现共同消费。同一个组下的每个实例都配置有 相同的组 ID,被分配不同的订阅分区。当某个实例挂掉的时候,其他实例会自动地承担起 它负责消费的分区。
  • 一个topic 可以被 多个消费者组 消费,但是每个消费者组消费的数据是 互不干扰 的,也就是说,每个 消费组 消费的都是 完整的数据。
  • 一个分区只能被 同一个消费组内的一个消费者 消费,而 不能拆给多个消费者 消费,也就是说如果你某个 消费者组内的消费者数 比 该 Topic 的分区数还多,那么多余的消费者是不起作用的。
    在这里插入图片描述
  • 超出分区的消费者事没有消费能力的,理想的情况是消费者数量分区数量 是一致的,但是消费者数量和分区数量没有必然关系
    在这里插入图片描述
    4.2分区分配
    (1)触发条件
  • 同一个Consumer Group内新增消费者
  • 消费者离开当前所属的Consumer Group,包括关闭或崩溃
  • 订阅的主题(topic)新增分区(partition)
    (2)分配策略——Range
    针对topic而言,首先按照partition(分区)序号排序,然后将消费者排序。分区数/消费者数=m,如果m!=0,前m个消费者多消费一个分区。(每个topic)
    eg:如有6个partition,5个消费者,那么第一个消费者要消费第0,1分区,第二个消费者消费第2分区,以此类推。

(3)分配策略——RoundRobin
RoundRobinAssignor策略的原理是将消费组内所有消费者以及消费者所订阅的所有topic的partition按照字典序排序,然后通过轮询消费者方式逐个将分区分配给每个消费者。RoundRobinAssignor策略对应的partition.assignment.strategy参数值为:org.apache.kafka.clients.consumer.RoundRobinAssignor。

  • 消费者订阅相同 Topic
    如果同一个消费组内所有的消费者的订阅信息都是相同的,那么RoundRobinAssignor策略的分区分配会是均匀的。
    举例,假设消费组中有2个消费者C0和C1,都订阅了主题t0和t1,并且每个主题都有3个分区,那么所订阅的所有分区可以标识为:t0p0、t0p1、t0p2、t1p0、t1p1、t1p2。最终的分配结果为:
    消费者C0:t0p0、t0p2、t1p1
    消费者C1:t0p1、t1p0、t1p2
    在这里插入图片描述
  • 消费者订阅不同的topic
    如果同一个消费组内的消费者所订阅的Topic 是不相同的,那么在执行分区分配的时候就不是完全的轮询分配,有可能会导致分区分配的不均匀。如果某个消费者没有订阅消费组内的某个topic,那么在分配分区的时候此消费者将分配不到这个topic的任何分区。

举例,假设消费组内有3个消费者C0、C1和C2,它们共订阅了3个主题:t0、t1、t2,这3个主题分别有1、2、3个分区,即整个消费组订阅了t0p0、t1p0、t1p1、t2p0、t2p1、t2p2这6个分区。具体而言,消费者C0订阅的是主题t0,消费者C1订阅的是主题t0和t1,消费者C2订阅的是主题t0、t1和t2,那么最终的分配结果为:
消费者C0:t0p0
消费者C1:t1p0
消费者C2:t1p1、t2p0、t2p1、t2p2
在这里插入图片描述

二、常见面试题

1.Kafka写入的数据如何保证不丢失

(1)kafka特性
(a)分布式存储架构
kafka中一个 Topic 数据集合拆分为多个partiton(数据分区),每个 Partition 可以在不同的机器上,储存部分数据。实现把一个超大的数据集合分布式存储在多台机器上。
在这里插入图片描述
(b)Kafka 高可用架构
为了防止数据丢失,kafka会做副本冗余,每个 Partition 会复制一个副本放在别的机器上,这样某台机器宕机,只不过是 Partition 其中一个副本丢失。如果某个 Partition 有多副本的话,Kafka 会选举其中一个 Parititon 副本作为 Leader,然后其他的 Partition 副本是 Follower。只有 Leader Partition 是对外提供读写操作,Follower Partition 就是从 Leader Partition 同步数据。一旦 Leader Partition 宕机了,就会选举其他的 Follower Partition 作为新的 Leader Partition 对外提供读写服务。
在这里插入图片描述
(2)Kafka写入的数据如何保证不丢失
(a)ISR机制:ISR是用于Kafka 自动维护和监控哪些 Follower 及时的跟上了 Leader 的数据同步。ISR机制简单来说,就是会自动给每个 Partition 维护一个 ISR 列表,这个列表里一定会有 Leader,然后还会包含跟 Leader 保持同步的 Follower。也就是说,只要 Leader 的某个 Follower 一直跟他保持数据同步,那么就会存在于 ISR 列表里。但是如果 Follower 因为自身发生一些问题,导致不能及时的从 Leader 同步数据过去,那么这个 Follower 就会被认为是“out-of-sync”,被从 ISR 列表里踢出去。
**(b)**每个 Partition 都至少得有 1 个 Follower 在 ISR 列表里,跟上了 Leader 的数据同步
**(c)**每次写入数据的时候,都要求至少写入 Partition Leader 成功,同时还有至少一个 ISR 里的 Follower 也写入成功,才算这个写入是成功了
在这里插入图片描述
**(d)**不满足以上条件,就一直写入失败,让生产系统不停的尝试重试,直到满足上述两个条件,然后才能认为写入成功。

2.kafka的三中消费模式

2.1 at-most-once模式
配置应答模式ack为0时,只要消息到了broker无论是否写成功,就回复ok,这样可能导致消息没有写入kafka;这种做法一般是为了减少消息的重复性,而且业务必须接受数据的丢失
2.2 at-least-once模式
producer在收到ack时,证明消息已经写入kafka;但是ack超时或者返回错误,producer会尝试重新发送消息
数据重复消费情况:如果消息已经写入kafka,但是在回复ack时异常,此时会导致消息被写入kafka两次,消费者在处理消息时要做去重处理
2.3 at-exactly-once模式
即使 producer 重试发送消息,消息也会保证最多一次地传递给最终consumer。
核心思想是将offset作为唯一id与消息同时处理,并且保证处理的原子性;设置自动提交为false;消息处理成功之后再提交;
比如对于关系型数据库来说,可以将id设置为消息处理结果的唯一索引,再次处理时,如果发现该索引已经存在,那么就不处理;

3.kafka如何保证不重复消费

3.1重复消费场景
(1)设置offset为自动提交,正在消费数据,kill消费者线程;
(2)设置offset为自动提交,关闭kafka时,如果在close之前,调用 consumer.unsubscribe() 则有可能部分offset没提交,下次重启会重复消费;
(3)消费kafka与业务逻辑在一个线程中处理,可能出现消费程序业务处理逻辑阻塞超时,导致一个周期内,offset还未提交;继而重复消费,但是业务逻辑可能采用发送kafka或者其他无法回滚的方式。

3.2问题原因
**(1)底层根本原因:**已经消费了数据,但是offset没提交。
**(2)配置问题:**设置了offset自动提交
**(3)重复消费最常见的情况:**re-balance问题,通常会遇到消费的数据,处理很耗时,导致超过了Kafka的session timeout时间(0.10.x版本默认是30秒),那么就会re-balance重平衡,此时有一定几率offset没提交,会导致重平衡后重复消费。

3.3问题解决
**解决办法:**至少成功发送一次+去重操作(幂等性)
(1)如何保证至少成功发送一次
保证不丢失消息:
生产者(ack=all 代表至少成功发送一次)
消费者 (offset手动提交,业务逻辑成功处理后,提交offset)
(2)去重操作(幂等性)
去重问题:消息可以使用唯一id标识
保证不重复消费:落表(主键或者唯一索引的方式,避免重复数据)
业务逻辑处理(选择唯一主键存储到Redis或者mongdb中,先查询是否存在,若存在则不处理;若不存在,先插入Redis或Mongdb,再进行业务逻辑处理)

4.zookeeper与kafka

一个典型的Kafka集群中包含若干Produce,若干broker(一般broker数量越多,集群吞吐率越高),若干Consumer Group,以及一个Zookeeper集群。Kafka通过Zookeeper管理集群配置,选举leader,以及在Consumer Group发生变化时进行rebalance。Producer使用push模式将消息发布到broker,Consumer使用pull模式从broker订阅并消费消息。
在这里插入图片描述

1)Producer端直接连接broker.list列表,从列表中返回TopicMetadataResponse,该Metadata包含Topic下每个partition leader建立socket连接并发送消息.
2)Broker端使用zookeeper用来注册broker信息,以及监控partition leader存活性.
3)Consumer端使用zookeeper用来注册consumer信息,其中包括consumer消费的partition列表等,同时也用来发现broker列表,并和partition leader建立socket连接,并获取消息。

**Zookeeper作用:**管理broker、consumer

创建Broker后,向zookeeper注册新的broker信息,实现在服务器正常运行下的水平拓展。具体的,通过注册watcher,获取partition的信息。
Topic的注册,zookeeper会维护topic与broker的关系,通/brokers/topics/topic.name节点来记录。
Producer向zookeeper中注册watcher,了解topic的partition的消息,以动态了解运行情况,实现负载均衡。Zookeepr不管理producer,只是能够提供当前broker的相关信息。
Consumer可以使用group形式消费kafka中的数据。所有的group将以轮询的方式消费broker中的数据,具体的按照启动的顺序。Zookeeper会给每个consumer group一个ID,即同一份数据可以被不同的用户ID多次消费。因此这就是单播与多播的实现。以单个消费者还是以组别的方式去消费数据,由用户自己去定义。Zookeeper管理consumer的offset跟踪当前消费的offset。
kafka使用ZooKeeper用于管理、协调代理。每个Kafka代理通过Zookeeper协调其他Kafka代理。
当Kafka系统中新增了代理或某个代理失效时,Zookeeper服务将通知生产者和消费者。生产者与消费者据此开始与其他代理协调工作。

Zookeeper在Kakfa中扮演的角色:Kafka将元数据信息保存在Zookeeper中,但是发送给Topic本身的数据是不会发到Zk上的

· kafka使用zookeeper来实现动态的集群扩展,不需要更改客户端(producer和consumer)的配置。broker会在zookeeper注册并保持相关的元数据(topic,partition信息等)更新。
· 而客户端会在zookeeper上注册相关的watcher。一旦zookeeper发生变化,客户端能及时感知并作出相应调整。这样就保证了添加或去除 broker时,各broker间仍能自动实现负载均衡。这里的客户端指的是Kafka的消息生产端(Producer)和消息消费端(Consumer)
· Broker端使用zookeeper来注册broker信息,以及监测partitionleader存活性.
· Consumer端使用zookeeper用来注册consumer信息,其中包括consumer消费的partition列表等,同时也用来发现broker列表,并和partitionleader建立socket连接,并获取消息.
· Zookeer和Producer没有建立关系,只和Brokers、Consumers建立关系以实现负载均衡,即同一个ConsumerGroup中的Consumers可以实现负载均衡(因为Producer是瞬态的,可以发送后关闭,无需直接等待)

5.others

https://www.jianshu.com/p/511962462e58
https://www.cnblogs.com/kx33389/p/11182082.html

三、参考资料

1.https://zhuanlan.zhihu.com/p/95907920
2.https://blog.csdn.net/u010022158/article/details/106271208
3.https://www.jianshu.com/p/6cb86599dd60
4.https://www.jianshu.com/p/9389fcc51040
5.https://blog.csdn.net/weixin_39657094/article/details/110802319
6.https://www.cnblogs.com/gxyandwmm/p/11432598.html
7.https://blog.csdn.net/u010627840/article/details/76435385?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control
8.https://www.cnblogs.com/cuiyuanhao/p/13410442.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值