扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
大家好,这里是 菜农曰,欢迎来到我的频道。
创新互联于2013年成立,先为昌黎等服务建站,昌黎等地企业,进行企业商务咨询服务。为昌黎企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。充满寒气的互联网如何在面试中脱颖而出,平时积累很重要,八股文更不能少!下面带来的这篇 Kafka 问答希望能够在你的 offer 上增添一把🔥。
Kafka最初是由Linkedin公司开发的,是一个分布式的、可扩展的、容错的、支持分区的(Partition)、多副本的(replica)、基于Zookeeper框架的发布-订阅消息系统,Kafka适合离线和在线消息消费。它是分布式应用系统中的重要组件之一,也被广泛应用于大数据处理。Kafka是用Scala语言开发,它的Java版本称为Jafka。Linkedin于2010年将该系统贡献给了Apache基金会并成为顶级开源项目之一。
Kafka 是个大家伙,本篇将通过40道问答作为路线,由浅入深,大程度上覆盖整个 Kafka 的问答内容(预习+复习一步到位)
Kafka 将消息以 topic 为单位进行归纳,发布消息的程序称为 Producer,消费消息的程序称为 Consumer。它是以集群的方式运行,可以由一个或多个服务组成,每个服务叫做一个 Broker,Producer 通过网络将消息发送到 kafka 集群,集群向消费者提供消息,broker 在中间起到一个代理保存消息的中转站。
Kafka 中重要的组件
1)Producer: 消息生产者,发布消息到Kafka集群的终端或服务
2)Broker:一个 Kafka 节点就是一个 Broker,多个Broker可组成一个Kafka 集群。
如果某个 Topic 下有 n 个Partition 且集群有 n 个Broker,那么每个 Broker会存储该 Topic 下的一个 Partition
如果某个 Topic 下有 n 个Partition 且集群中有 m+n 个Broker,那么只有 n 个Broker会存储该Topic下的一个 Partition
如果某个 Topic 下有 n 个Partition 且集群中的Broker数量小于 n,那么一个 Broker 会存储该 Topic 下的一个或多个 Partition,这种情况尽量避免,会导致集群数据不均衡
3)Topic:消息主题,每条发布到Kafka集群的消息都会归集于此,Kafka是面向Topic 的
4)Partition:Partition 是Topic在物理上的分区,一个Topic可以分为多个Partition,每个Partition是一个有序的不可变的记录序列。单一主题中的分区有序,但无法保证主题中所有分区的消息有序。
5)Consumer:从Kafka集群中消费消息的终端或服务
6)Consumer Group:每个Consumer都属于一个Consumer Group,每条消息只能被Consumer Group中的一个Consumer消费,但可以被多个Consumer Group消费。
7)Replica:Partition 的副本,用来保障Partition的高可用性。
8)Controller:Kafka 集群中的其中一个服务器,用来进行Leader election以及各种 Failover 操作。
9)Zookeeper:Kafka 通过Zookeeper来存储集群中的 meta 消息
2、Kafka 性能高原因优点
缺点
主题是一个逻辑上的概念,还可以细分为多个分区,一个分区只属于单个主题,很多时候也会把分区称为主题分区(Topic-Partition)。同一主题下的不同分区包含的消息是不同的,分区在存储层面可以看做一个可追加的日志文件
,消息在被追加到分区日志文件的时候都会分配一个特定的偏移量(offset)。offset 是消息在分区中的唯一标识,kafka 通过它来保证消息在分区内的顺序性,不过 offset 并不跨越分区,也就是说,kafka保证的是分区有序而不是主题有序。
在分区中又引入了多副本(replica)的概念,通过增加副本数量可以提高容灾能力。同一分区的不同副本中保存的是相同的消息。副本之间是一主多从的关系,其中主副本负责读写,从副本只负责消息同步。副本处于不同的 broker 中,当主副本出现异常,便会在从副本中提升一个为主副本。
7、Kafka 中分区的原则在Kafka 中 Producer 可以 Batch的方式推送数据达到提高效率的作用。Kafka Producer 可以将消息在内存中累积到一定数量后作为一个 Batch 发送请求。Batch 的数量大小可以通过 Producer 的参数进行控制,可以从三个维度进行控制
通过增加 Batch 的大小,可以减少网络请求和磁盘I/O的频次,具体参数配置需要在效率和时效性做一个权衡。
11、Kafka 消息的消费模式Kafka采用大部分消息系统遵循的传统模式:Producer将消息推送到Broker,Consumer从Broker获取消息。
如果采用 Push 模式,则Consumer难以处理不同速率的上游推送消息。
采用 Pull 模式的好处是Consumer可以自主决定是否批量的从Broker拉取数据。Pull模式有个缺点是,如果Broker没有可供消费的消息,将导致Consumer不断在循环中轮询,直到新消息到达。为了避免这点,Kafka有个参数可以让Consumer阻塞直到新消息到达。
12、Kafka 如何实现负载均衡与故障转移负载均衡是指让系统的负载根据一定的规则均衡地分配在所有参与工作的服务器上,从而大限度保证系统整体运行效率与稳定性
负载均衡
Kakfa 的负载均衡就是每个 Broker 都有均等的机会为 Kafka 的客户端(生产者与消费者)提供服务,可以负载分散到所有集群中的机器上。Kafka 通过智能化的分区领导者选举来实现负载均衡,提供智能化的 Leader 选举算法,可在集群的所有机器上均匀分散各个Partition的Leader,从而整体上实现负载均衡。
故障转移
Kafka 的故障转移是通过使用会话机制实现的,每台 Kafka 服务器启动后会以会话的形式把自己注册到 Zookeeper 服务器上。一旦服务器运转出现问题,就会导致与Zookeeper 的会话不能维持从而超时断连,此时Kafka集群会选举出另一台服务器来完全替代这台服务器继续提供服务。
13、Kafka 中 Zookeeper 的作用Kafka 是一个使用 Zookeeper 构建的分布式系统。Kafka 的各 Broker 在启动时都要在Zookeeper上注册,由Zookeeper统一协调管理。如果任何节点失败,可通过Zookeeper从先前提交的偏移量中恢复,因为它会做周期性提交偏移量工作。同一个Topic的消息会被分成多个分区并将其分布在多个Broker上,这些分区信息及与Broker的对应关系也是Zookeeper在维护。
14、Kafka 提供了哪些系统工具Consumer Group 是Kafka独有的可扩展且具有容错性的消费者机制。一个组内可以有多个Consumer,它们共享一个全局唯一的Group ID。组内的所有Consumer协调在一起来消费订阅主题(Topic)内的所有分区(Partition)。当然,每个Partition只能由同一个Consumer Group内的一个Consumer 来消费。消费组内的消费者可以使用多线程的方式实现,消费者的数量通常不超过分区的数量,且二者最好保持整数倍的关系,这样不会造成有空闲的消费者。
Consumer 订阅的是Topic的Partition,而不是Message。所以在同一时间点上,订阅到同一个分区的Consumer必然属于不同的Consumer Group
Consumer Group与Consumer的关系是动态维护的,当一个Consumer进程挂掉或者是卡住时,该Consumer所订阅的Partition会被重新分配到改组内的其他Consumer上,当一个Consumer加入到一个Consumer Group中时,同样会从其他的Consumer中分配出一个或者多个Partition到这个新加入的Consumer。
负载均衡
当启动一个Consumer时,会指定它要加入的Group,使用的配置项是:Group.id
为了维持Consumer与Consumer Group之间的关系,Consumer 会周期性地发送 hearbeat 到 coodinator(协调者),如果有 hearbeat 超时或未收到 hearbeat,coordinator 会认为该Consumer已经退出,那么它所订阅的Partition会分配到同一组内的其他Consumer上,这个过程称为 rebalance(再平衡)
16、Kafka 中消息偏移的作用生产过程中给分区中的消息提供一个顺序ID号,称之为偏移量,偏移量的主要作用为了唯一地区别分区中的每条消息。Kafka的存储文件都是按照offset.kafka来命名
17、 生产过程中何时会发生QueueFullExpection以及如何处理何时发生
当生产者试图发送消息的速度快于Broker可以处理的速度时,通常会发生 QueueFullException
如何解决
首先先进行判断生产者是否能够降低生产速率,如果生产者不能阻止这种情况,为了处理增加的负载,用户需要添加足够的 Broker。或者选择生产阻塞,设置Queue.enQueueTimeout.ms
为 -1,通过这样处理,如果队列已满的情况,生产者将组织而不是删除消息。或者容忍这种异常,进行消息丢弃。
Cosumer 消费消息时,想Broker 发出fetch
请求去消费特定分区的消息,Consumer 可以通过指定消息在日志中的偏移量 offset,就可以从这个位置开始消息消息,Consumer 拥有了 offset 的控制权,也可以向后回滚去重新消费之前的消息。
也可以使用seek(Long topicPartition)
来指定消费的位置。
Kafka 中的 Partition 是有序消息日志,为了实现高可用性,需要采用备份机制,将相同的数据复制到多个Broker上,而这些备份日志就是 Replica,目的是为了 防止数据丢失。
所有Partition 的副本默认情况下都会均匀地分布到所有 Broker 上,一旦领导者副本所在的Broker宕机,Kafka 会从追随者副本中选举出新的领导者继续提供服务。
Leader: 副本中的领导者。负责对外提供服务,与客户端进行交互。生产者总是向 Leader副本些消息,消费者总是从 Leader 读消息
Follower: 副本中的追随者。被动地追随 Leader,不能与外界进行交付。只是向Leader发送消息,请求Leader把最新生产的消息发给它,进而保持同步。
20、Replica 的重要性Replica 可以确保发布的消息不会丢失,保证了Kafka的高可用性。并且可以在发生任何机器错误、程序错误或软件升级、扩容时都能生产使用。
21、Kafka 中的 Geo-Replication 是什么Kafka官方提供了MirrorMaker组件,作为跨集群的流数据同步方案。借助MirrorMaker,消息可以跨多个数据中心或云区域进行复制。您可以在主动/被动场景中将其用于备份和恢复,或者在主动/主动方案中将数据放置得更靠近用户,或支持数据本地化要求。
它的实现原理比较简单,就是通过从源集群消费消息,然后将消息生产到目标集群,即普通的消息生产和消费。用户只要通过简单的Consumer配置和Producer配置,然后启动Mirror,就可以实现集群之间的准实时的数据同步.
22、Kafka 中 AR、ISR、OSR 三者的概念AR
:分区中所有副本称为 ARISR
:所有与主副本保持一定程度同步的副本(包括主副本)称为 ISROSR
:与主副本滞后过多的副本组成 OSRLeader 会维护一个与自己基本保持同步的Replica列表,该列表称为ISR,每个Partition都会有一个ISR,而且是由Leader动态维护。所谓动态维护,就是说如果一个Follower比一个Leader落后太多,或者超过一定时间未发起数据复制请求,则Leader将其从ISR中移除。当ISR中所有Replica都向Leader发送ACK(Acknowledgement确认)时,Leader才commit。
24、分区副本中的 Leader 如果宕机但 ISR 却为空该如何处理可以通过配置unclean.leader.election
:
Kafka可以接收的大消息默认为1000000字节,如果想调整它的大小,可在Broker中修改配置参数:Message.max.bytes
的值
27、Kafka 的 ACK 机制但要注意的是,修改这个值,还要同时注意其他对应的参数值是正确的,否则就可能引发一些系统异常。首先这个值要比消费端的fetch.Message.max.bytes(默认值1MB,表示消费者能读取的大消息的字节数)参数值要小才是正确的设置,否则Broker就会因为消费端无法使用这个消息而挂起。
Kafka的Producer有三种ack机制,参数值有0、1 和 -1
在Kafka中,Producers将消息推送给Broker端,在Consumer和Broker建立连接之后,会主动去 Pull(或者说Fetch)消息。这种模式有些优点,首先Consumer端可以根据自己的消费能力适时的去fetch消息并处理,且可以控制消息消费的进度(offset);此外,消费者可以控制每次消费的数,实现批量消费。
29、Kafka 提供的API有哪些Kafka 提供了两套 Consumer API,分为 High-level API 和 Sample API
Sample API
这是一个底层API,它维持了一个与单一 Broker 的连接,并且这个API 是完全无状态的,每次请求都需要指定 offset 值,因此这套 API 也是最灵活的。
High-level API
该API封装了对集群中一系列Broker的访问,可以透明地消费下一个Topic,它自己维护了已消费消息的状态,即每次消费的都会下一个消息。High-level API 还支持以组的形式消费Topic,如果 Consumers 有同一个组名,那么Kafka就相当于一个队列消息服务,而各个 Consumer 均衡地消费相应Partition中的数据。若Consumers有不同的组名,那么此时Kafka就相当于一个广播服务,会把Topic中的所有消息广播到每个Consumer
30、Kafka 的Topic中 Partition 数据是怎么存储到磁盘的Topic 中的多个 Partition 以文件夹的形式保存到 Broker,每个分区序号从0递增,且消息有序。Partition 文件下有多个Segment(xxx.index,xxx.log),Segment文件里的大小和配置文件大小一致。默认为1GB,但可以根据实际需要修改。如果大小大于1GB时,会滚动一个新的Segment并且以上一个Segment最后一条消息的偏移量命名。
31、Kafka 创建Topic后如何将分区放置到不同的 Broker 中Kafka创建Topic将分区放置到不同的Broker时遵循以下规则:
nextReplicaShift
决定的,而这个数也是随机产生的。概念
保留期内保留了Kafka群集中的所有已发布消息,超过保期的数据将被按清理策略进行清理。默认保留时间是7天,如果想修改时间,在server.properties
里更改参数log.retention.hours/minutes/ms
的值便可。
清理策略
log.cleanup.policy=delete
表示启用删除策略,这也是默认策略。一开始只是标记为delete,文件无法被索引。只有过了log.Segment.delete.delay.ms
这个参数设置的时间,才会真正被删除。log.cleanup.policy=compact
表示启用压缩策略,将数据压缩,只保留每个Key最后一个版本的数据。首先在Broker的配置中设置log.cleaner.enable=true
启用 cleaner,这个默认是关闭的。Kafka一个Message由固定长度的header和一个变长的消息体body组成。将Message存储在日志时采用不同于Producer发送的消息格式。每个日志文件都是一个log entries(日志项)序列:
34、Kafka 是否支持多租户隔离Kafka没有限定单个消息的大小,但一般推荐消息大小不要超过1MB,通常一般消息大小都在1~10KB之间。
多租户技术(multi-tenancy technology)是一种软件架构技术,它是实现如何在多用户的环境下共用相同的系统或程序组件,并且仍可确保各用户间数据的隔离性。
解决方案
通过配置哪个主题可以生产或消费数据来启用多租户,也有对配额的操作支持。管理员可以对请求定义和强制配额,以控制客户端使用的Broker资源。
35、Kafka 的日志分段策略与刷新策略日志分段(Segment)策略
log.roll.hours/ms
:日志滚动的周期时间,到达指定周期时间时,强制生成一个新的Segment,默认值168h(7day)。log.Segment.bytes
:每个Segment的大容量。到达指定容量时,将强制生成一个新的Segment。默认值1GB(-1代表不限制)。log.retention.check.interval.ms
:日志片段文件检查的周期时间。默认值60000ms。日志刷新策略
Kafka的日志实际上是开始是在缓存中的,然后根据实际参数配置的策略定期一批一批写入到日志文件中,以提高吞吐量。
log.flush.interval.Messages
:消息达到多少条时将数据写入到日志文件。默认值为10000。log.flush.interval.ms
:当达到该时间时,强制执行一次flush。默认值为null。log.flush.scheduler.interval.ms
:周期性检查,是否需要将信息flush。默认为很大的值。Kafka动态维护了一个同步状态的副本的集合(a set of In-SyncReplicas),简称ISR,在这个集合中的结点都是和Leader保持高度一致的,任何一条消息只有被这个集合中的每个结点读取并追加到日志中,才会向外部通知“这个消息已经被提交”。
kafka 通过配置producer.type
来确定是异步还是同步,默认是同步
同步复制
Producer 会先通过Zookeeper识别到Leader,然后向 Leader 发送消息,Leader 收到消息后写入到本地 log文件。这个时候Follower 再向 Leader Pull 消息,Pull 回来的消息会写入的本地 log 中,写入完成后会向 Leader 发送 Ack 回执,等到 Leader 收到所有 Follower 的回执之后,才会向 Producer 回传 Ack。
异步复制
Kafka 中 Producer 异步发送消息是基于同步发送消息的接口来实现的,异步发送消息的实现很简单,客户端消息发送过来以后,会先放入一个BlackingQueue
队列中然后就返回了。Producer 再开启一个线程ProducerSendTread
不断从队列中取出消息,然后调用同步发送消息的接口将消息发送给 Broker。
37、Kafka 中什么情况下会出现消息丢失/不一致的问题Producer的这种在内存缓存消息,当累计达到阀值时批量发送请求,小数据I/O太多,会拖慢整体的网络延迟,批量延迟发送事实上提升了网络效率。但是如果在达到阀值前,Producer不可用了,缓存的数据将会丢失。
消息发送时
消息发送有两种方式:同步 - sync
和异步 - async
。默认是同步的方式,可以通过 producer.type 属性进行配置,kafka 也可以通过配置 acks 属性来确认消息的生产
0
:表示不进行消息接收是否成功的确认1
:表示当 leader 接收成功时的确认-1
:表示 leader 和 follower 都接收成功的确认当 acks = 0 时,不和 Kafka 进行消息接收确认,可能会因为网络异常,缓冲区满的问题,导致消息丢失
当 acks = 1 时,只有 leader 同步成功而 follower 尚未完成同步,如果 leader 挂了,就会造成数据丢失
消息消费时
Kafka 有两个消息消费的 consumer 接口,分别是low-level
和hign-level
low-level
:消费者自己维护 offset 等值,可以实现对 kafka 的完全控制high-level
:封装了对 partition 和 offset,使用简单如果使用高级接口,可能存在一个消费者提取了一个消息后便提交了 offset,那么还没来得及消费就已经挂了,下次消费时的数据就是 offset + 1 的位置,那么原先 offset 的数据就丢失了。
38、Kafka 作为流处理平台的特点流处理就是连续、实时、并发和以逐条记录的方式处理数据的意思。Kafka 是一个分布式流处理平台,它的高吞吐量、低延时、高可靠性、容错性、高可扩展性都使得Kafka非常适合作为流式平台。
活锁的概念:消费者持续的维持心跳,但没有进行消息处理。
为了预防消费者在这种情况一直持有分区,通常会利用max.poll.interval.ms
活跃检测机制,如果调用 Poll 的频率大于大间隔,那么消费者将会主动离开消费组,以便其他消费者接管该分区
Kafka 的消费单元是 Partition,同一个 Partition 使用 offset 作为唯一标识保证顺序性,但这只是保证了在 Partition 内部的顺序性而不是 Topic 中的顺序,因此我们需要将所有消息发往统一 Partition 才能保证消息顺序消费,那么可以在发送的时候指定 MessageKey,同一个 key 的消息会发到同一个 Partition 中。
以上便是本篇的全部内容,不要空谈,不要贪懒,和小菜一起做个吹着牛X做架构
的程序猿吧~点个关注做个伴,让小菜不再孤单。咱们下文见!
今天的你多努力一点,明天的你就能少说一句求人的话!
我是小菜,一个和你一起变强的男人。
💋
微信公众号已开启,菜农曰,没关注的同学们记得关注哦!
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流