Kafka经典面试题 附参考答案.docx
无论是作为面试官,还是应聘者,我都接触过很多Kafka面试题。而在最近面试了很多候选人,发现写了熟悉Kafka,但是对于KaflCa相关的知识却是只知道大概用处,简单搭建和使用。我想说,虽然我们是SRE(可靠性工程师),但不论你是业务层的SRE还是基础设施层的SRE,我们都需要对业务方的使用场景有足够理解,或者对我们要提供的服务有足够的了解才行,这样你才能整体的保证你的业务连续性以及业务可靠性。因此,专门总结了如下经典的kafl<a面试详解。以下面试题,参考胡夕胡大的Kafka核心源码解读,对相关的知识进行了补充和思考。基础题目ApacheKafka是什么?能问这道题,主要是想看候选人对于Kafka的使用场景以及定位认知理解有多深,同时候可以知道候选人对于这项技术的关注度。我们都知道,在开源软件中,大部分软件随着用户量的增加,整个软件的功能和定位也有了新的变化,而APaCheKafka一路发展到现在,已经由最初的分布式提交日志系统逐渐演变成了实时流处理框架。因此,这道题你最好这么回答:ApachKafka是一款分布式流处理平台,用于实时构建流处理应用。它有一个核心的功能广为人知,即作为企业级的消息引擎被广泛使用(通常也会称之为消息总线messagebus)o关于分布式流处理平台,其实从它官方的1.ogo以及Slogan我们就很容易看出来。什么是消费者组?消费者组是Kafka独有的概念,如果面试官问这个,就说明他对此是有一定了解的。胡大给的标准答案是:官网上的介绍言简意赅,即消费者组是Kafka提供的可扩展且具有容错性的消费者机制。但实际上,消费者组(ConSUmerGroUP)其实包含两个概念,作为队列,消费者组允许你分割数据处理到一组进程集合上(即一个消费者组中可以包含多个消费者进程,他们共同消费该t。PiC的数据),这有助于你的消费能力的动态调整;作为发布-订阅模型(PUbliSh-SUbSCribe),Kafka允许你将同一份消息广播到多个消费者组里,以此来丰富多种数据使用场景。需要注意的是:在消费者组中,多个实例共同订阅若干个主题,实现共同消费。同一个组下的每个实例都配置有相同的组ID,被分配不同的订阅分区。当某个实例挂掉的时候,其他实例会自动地承担起它负责消费的分区。因此,消费者组在一定程度上也保证了消费者程序的高可用性。KafkaCluster-Server1-pServer2PP3p1P2/X、/注意:消费者组的题目,能够帮你在某种程度上掌控下面的面试方向。如果你擅长位移值原理(OffSet),就不妨再提一下消费者组的位移提交机制;如果你擅长KafkaBroker,可以提一下消费者组与BrOker之间的交互;如果你擅长与消费者组完全不相关的Producer,那么就可以这么说:“消费者组要消费的数据完全来自于ProdUCer端生产的消息,我对PrOdUCer还是比较熟悉的。”总之,你总得对ConSUmergrOUP相关的方向有一定理解,然后才能像面试官表名你对某一块很理解。在Kafka中,ZooKeeper的作用是什么?这道题,也是我经常会问候选人的题,因为任何分布式系统中虽然都通过一些列的算法去除了传统的关系型数据存储,但是毕竟还是有些数据要存储的,同时分布式系统的特性往往是需要有一些中间人角色来统筹集群。比如我们在整个微服务框架中的Dubbo,它也是需要依赖一些注册中心或配置中心类的中间件的,以及云原生的Kubernetes使用etcd作为整个集群的枢纽。标准答案:目前,Kafka使用ZOoKeePer存放集群元数据、成员管理、COntrOlIer选举,以及其他一些管理类任务。之后,等KIP-500提案完成后,Kafka将完全不再依赖于ZooKeeper0“存放元数据”是指主题分区的所有数据都保存在ZOOKeePer中,且以它保存的数据为权威,其他“人''都要与它保持对齐。“成员管理”是指Broker节点的注册、注销以及属性变更,等等。“ContIer选举”是指选举集群COnglIer,而其他管理类任务包括但不限于主题删除、参数配置等。KIP-500思想,是使用社区自研的基于Raft的共识算法,替代ZOOKeeper,实现Controller自选举。解释下Kafka中位移(offset)的作用标准答案:在Kaflca中,每个主题分区下的每条消息都被赋予了一个唯一的ID数值,用于标识它在分区中的位置。这个ID数值,就被称为位移,或者叫偏移量。一旦消息被写入到分区日志,它的位移值将不能被修改。答完这些之后,你还可以把整个面试方向转移到你希望的地方:如果你深谙BrOker底层日志写入的逻辑,可以强调下消息在日志中的存放格式如果你明白位移值一旦被确定不能修改,可以强调下“1.ogCleaner组件都不能影响位移值”这件事情如果你对消费者的概念还算熟悉,可以再详细说说位移值和消费者位移值之间的区别阐述下Kafka中的领导者副本(1.eaderReplica)和追随者副本(FollowerReplica)的区别推荐的答案:Kafka副本当前分为领导者副本和追随者副本。只有1.eader副本才能对外提供读写服务,响应Clients端的请求。Follower副本只是采用拉(PU1.1.)的方式,被动地同步1.eader副本中的数据,并且在1.eader副本所在的Broker宕机后,随时准备应聘1.eader副本。加分点:强调FollOWer副本也能对外提供读服务。自Kafka2.4版本开始,社区通过引入新的Broker端参数,允许Follower副本有限度地提供读服务。强调1.eader和Follower的消息序列在实际场景中不一致。通常情况下,很多因素可能造成1.eader和Follower之间的不同步,比如程序问题,网络问题,broker问题等,短暂的不同步我们可以关注(秒级别),但长时间的不同步可能就需要深入排查了,因为一旦1.eader所在节点异常,可能直接影响可用性。注意:之前确保一致性的主要手段是高水位机制(HW),但高水位值无法保证1.eader连续变更场景下的数据一致性,因此,社区引入了1.eaderEpoch机制,来修复高水位值的弊端。实操题目如何设置Kafka能接收的最大消息的大小?对于SRE来讲,该题简直是送分题啊,但是,最大消息的设置通常情况下有生产者端,消费者端,broker端和topic级别的参数,我们需要正确设置,以保证可以正常的生产和消费。Broker端参数:message.max.bytes,max.message.bytes(topic级另J),replica.fetch.max.bytes(否则follow会同步失败)Consumer端参数:fetch.message.max.bytes监控Kafka的框架都有哪些?对于SRE来讲,依然是送分题。但基础的我们要知道,Kafka本身是提供了JMX(JavaManagementExtensions)的,我们可以通过它来获取到Kafka内部的一些基本数据。KafkaManager:更多是Kafka的管理,对于SRE非常友好,也提供了简单的瞬时指标监控。KafkaMonitor:1.inkedln开源的免费框架,支持对集群进行系统测试,并实时监控测试结果。CruiseControl:也是1.inkedln公司开源的监控框架,用于实时监测资源使用率,以及提供常用运维操作等。无Ul界面,只提供RESTAPI,可以进行多集群管理。JMX监控:由于Kafka提供的监控指标都是基于JMX的,因此,市面上任何能够集成JMX的框架都可以使用,比如Zabbix和Prometheuso已有大数据平台自己的监控体系:像Cloudera提供的CDH这类大数据平台,天然就提供Kafka监控方案。JMXTooI:社区提供的命令行工具,能够实时监控JMX指标。可以使用kafka-run-class.shkafka.tools.JmxTool来查看具体的用法。Broker的HeapSize如何设置?其实对于SRE还是送分题,因为目前来讲大部分公司的业务系统都是使用JaVa开发,因此SRE对于基本的JVM相关的参数应该至少都是非常了解的,核心就在于JVM的配置以及GC相关的知识。标准答案:任何Java进程JVM堆大小的设置都需要仔细地进行考量和测试。一个常见的做法是,以默认的初始JVM堆大小运行程序,当系统达到稳定状态后,手动触发一次FUnGe然后通过JVM工具查看Ge后的存活对象大小。之后,将堆大小设置成存活对象总大小的1.52倍。对于Kafka而言,这个方法也是适用的。不过,业界有个最佳实践,那就是将Broker的HeaPSiZe固定为6GB。经过很多公司的验证,这个大小是足够且良好的。如何估算Kafka集群的机器数量?该题也算是SRE的送分题吧,对于SRE来讲,任何生产的系统第一步需要做的就是容量预估以及集群的架构规划,实际上也就是机器数量和所用资源之间的关联关系,资源通常来讲就是CPU,内存,磁盘容量,带宽。但需要注意的是,Kafka因为独有的设计,对于磁盘的要求并不是特别高,普通机械硬盘足够,而通常的瓶颈会出现在带宽上。在预估磁盘的占用时,你一定不要忘记计算副本同步的开销。如果一条消息占用IKB的磁盘空间,那么,在有3个副本的主题中,你就需要3KB的总空间来保存这条消息。同时,需要考虑到整个业务TOPiC数据保存的最大时间,以上几个因素,基本可以预估出来磁盘的容量需求。需要注意的是:对于磁盘来讲,一定要提前和业务沟通好场景,而不是等待真正有磁盘容量瓶颈了才去扩容磁盘或者找业务方沟通方案。对于带宽来说,常见的带宽有IGbPS和IOGbPs,通常我们需要知道,当带宽占用接近总带宽的90%时,丢包情形就会发生。1.eader总是-1,怎么破?对于有经验的SRE来讲,早期的Kafka版本应该多多少少都遇到过该种情况,通常情况下就是COntrOner不工作了,导致无法分配Ieader,那既然知道问题后,解决方案也就很简单了。重启COntrOner节点上的Kafka进程,让其他节点重新注册Controller角色,但是如上面ZooKeeper的作用,你要知道为什么Controller可以自动注册。当然了,当你知道COntrolIer的注册机制后,你也可以说:删除ZooKe叩er节点/controller,触发Controller重选举。Controller重选举能够为所有主题分区重刷分区状态,可以有效解决因不一致导致的1.eader不可用问题。但是,需要注意的是,直接操作ZOOKe叩er是一件风险很大的操作,就好比在1.inUX中执行了ITn-rf/xxx一样,如果在/和XXX之间不小心多了几个空格,那恭喜你",今年白干了O炫技式题目1.EO、1.S0、AR、ISR、HW都表示什么含义?讲真,我不认为这是炫技的题目,特别是作为SRE来讲,对于一个开源软件的原理以及概念的理解,是非常重要的。1.EO(1.ogEndOffset):日志末端位移值或末端偏移量,表示日志下一条待插入消息的位移值。举个例子,如果日志有10条消息,位移值从0开始,那么,第10条消息的位移值就是9。此时,1.EO=1001.SO(1.ogStabIeOffset):这是Kafka事务的概念。如果你没有使用到事务,那么这个值不存在(其实也不是不存在,只是设置成一个无意义的值)。该值控制了事务型消费者能够看到的消息范围。它经常与1.ogStartOffset,即日志起始位移值相混淆,因为有些人将后者缩写成1.SO,这是不对的。在Kafka中,1.SO就是指代1.ogStableOffsetoAR(AssignedReplicas):AR是主题被创建后,分区创建时被分配的副本集合,副本个数由副本因子决定。ISR(In-SyncReplicas):Kafka中特别重要的概念,指代的是AR中那些与1.eader保持同步的副本集合。在AR中的副本可能不在ISR中,但1.eader副本天然就包含在ISR中。HW(Highwatermark):高水位值,这是控制消费者可读取消息范围的重要字段。一个普通消费者只能“看到”1.eader副本上介于1.ogStartOffset和HW(不含)之间的所有消息。水位以上的消息是对消费者不可见的。需要注意的是,通常在ISR中,可能会有人问到为什么有时候副本不在ISR中,这其实也就是上面说的1.eader和Follower不同步的情况,为什么我们前面说,短暂的不用步我们可以关注,但是长时间的不同步,我们需要个入排查了,因为ISR里的副本后面都是通过replica.lag.time.max.ms,即Follower副本的1.EO落后1.eader1.EO的时间是否超过阈值来决定副本是否在ISR内部的。Kafka能手动删除消息吗?Kafka不需要用户手动删除消息。它本身提供了留存策略,能够自动删除过期消息。当然,它是支持手动删除消息的。对于设置了Key且参数CIeanUP.policy=compact的主题而言,我们可以构造一条的消息发送给Broker,依靠1.ogCleaner组件提供的功能删除掉该Key的消息。对于普通主题而言,我们可以使用kafka-delete-records命令,或编写程序调用Admin.deleteRecords方法来删除消息。这两种方法殊途同归,底层都是调用Admin的deleteRecords方法,通过将分区1.ogStartOffset值抬高的方式间接删除消息。consumer_offsets是做什么用的?这是一个内面主题,主要用于存储消费者的偏移量,以及消费者的元数据信息(消费者实例,消费者id等等)需要注意的是:Kafka的GroupCoordinator组件提供对该主题完整的管理功能,包括该主题的创建、写入、读取和1.eader维护等。分区1.eader选举策略有几种?分区的1.eader副本选举对用户是完全透明的,它是由Controller独立完成的。你需要回答的是,在哪些场景下,需要执行分区1.eader选举。每一种场景对应于一种选举策略。OfflinePartition1.eader选举:每当有分区上线时,就需要执行1.eader选举。所谓的分区上线,可能是创建了新分区,也可能是之前的下线分区重新上线。这是最常见的分区1.eader选举场景。ReassignPartition1.eader选举:当你手动运行kafka-reassign-partitions命令,或者是调用Admin的alterPartitionReassignments方法执行分区副本重分配时,可能触发此类选举。假设原来的AR是1,2,3,1.eader是1,当执行副本重分配后,副本集合AR被设置成4,5,6,显然,1.eader必须要变更,此时会发生ReassignPartition1.eader选举。PreferredReplicaPartition1.eader选举:当你手动运行kafka-preferred-replica-election命令,或自动触发了Preferred1.eader选举时,该类策略被激活。所谓的Preferred1.eader,指的是AR中的第一个副本。比如AR是3,2,1,那么,PrefelTed1.eader就是3。ControlledShutdownPartition1.eader选举:当Broker正常关闭时,该Broker上的所有1.eader副本都会下线,因此,需要为受影响的分区执行相应的1.eader选举。这4类选举策略的大致思想是类似的,即从AR中挑选首个在ISR中的副本,作为新1.eaderoKafka的哪些场景中使用了零拷贝(ZerOCOPy)?其实这道题对于SRE来讲,有点超纲了,不过既然ZerOeoPy是Kafka高性能的保证,我们需要了解它。ZeroCopy是特别容易被问到的高阶题目。在Kafka中,体现ZeroCopy使用场景的地方有两处:基于mm即的索引和日志文件读写所用的Transport1.ayero先说第一个。索引都是基于M叩PedByteBUffer的,也就是让用户态和内核态共享内核态的数据缓冲区,此时,数据不需要复制到用户态空间。不过,mmap虽然避免了不必要的拷贝,但不一定就能保证很高的性能。在不同的操作系统下,mmap的创建和销毁成本可能是不一样的。很高的创建和销毁开销会抵消ZerOCOPy带来的性能优势。由于这种不确定性,在Kafka中,只有索引应用了mmap,最核心的日志并未使用mmap机制。再说第二个。TmnSPOrt1.ayer是Kafka传输层的接口。它的某个实现类使用了FileChannel的transfeTo方法。该方法底层使用sendfile实现了ZeroCopy0对Kaflca而言,如果I/O通道使用普通的P1.AINTEXT,那么,Kafka就可以利用ZerOCOPy特性,直接将页缓存中的数据发送到网卡的BUffer中,避免中间的多次拷贝。相反,如果I/O通道启用了SS1.,那么,Kafka便无法利用ZeroCopy特性了。深度思考题Kafka为什么不支持读写分离?这其实是分布式场景下的通用问题,因为我们知道CAP理论下,我们只能保证C(可用性)和A(一致性)取其一,如果支持读写分离,那其实对于一致性的要求可能就会有一定折扣,因为通常的场景下,副本之间都是通过同步来实现副本数据一致的,那同步过程中肯定会有时间的消耗,如果支持了读写分离,就意味着可能的数据不一致,或数据滞后。1.eader/Follower模型并没有规定Follower副本不可以对外提供读服务。很多框架都是允许这么做的,只是Kafka最初为了避免不一致性的问题,而采用了让1.eader统一提供服务的方式。不过,自Kafka2.4之后,Kafka提供了有限度的读写分离,也就是说,Follower副本能够对外提供读服务。如何调优Kafka?作为SRE来讲,任何生产环境的调优,首先需要识别问题和瓶颈点,而不是随意的进行臆想调优。随后,需要确定优化目标,并且定量给出目标。对于Kafka来讲,常见的调优方向基本为:吞吐量、延时、持久性和可用性,每种目标之前都是由冲突点,这也就要求了,我们在对业务接入使用时,要进行业务场景的了解,以对业务进行相对的集群隔离,因为每一个方向的优化思路都是不同的,甚至是相反的。确定了目标之后,还要明确优化的维度。有些调优属于通用的优化思路,比如对操作系统、JVM等的优化;有些则是有针对性的,比如要优化Kafka的TPSo我们需要从3个方向去考虑:PrOdUCer端:增加batch.size和Iinger.ms,启用压缩,关闭重试Broker端:增加num.replica.fetchers提升Follower同步TPS,避免BrokerFullGC等。Consumer:增力口fetch.min.bytesCe)ntroller发生网络分区(NetWOrkPartitioning)时,Kafka会怎么样?这道题目能够诱发我们对分布式系统设计、CAP理论、一致性等多方面的思考。一旦发生Controller网络分区,那么,第一要务就是查看集群是否出现“脑裂“,即同时出现两个甚至是多个Controner组件。这可以根据BrOker端监控指标ActiveControllerCount来判断。不过,通常而言,我们在设计整个部署架构时,为了避免这种网络分区的发生,一般会将broker节点尽可能的防止在一个机房或者可用区。由于Controller会给Broker发送3类请求,1.eaderAndISrReqUest,StopReplicaRequest,UPdateMetadataRequest,因此,一旦出现网络分区,这些请求将不能顺利到达Broker端。这将影响主题的创建、修改、删除操作的信息同步,表现为集群仿佛僵住了一样,无法感知到后面的所有操作。因此,网络分区通常都是非常严重的问题,要赶快修复。JavaConsumer为什么采用单线程来获取消息、?在回答之前,如果先把这句话说出来,一定会加分:JaVaConSUmer是双线程的设计。一个线程是用户主线程,负责获取消息;另一个线程是心跳线程,负责向Kafka汇报消费者存活情况。将心跳单独放入专属的线程,能够有效地规避因消息处理速度慢而被视为下线的“假死”情况。单线程获取消息的设计能够避免阻塞式的消息获取方式。单线程轮询方式容易实现异步非阻塞式,这样便于将消费者扩展成支持实时流处理的操作算子。因为很多实时流处理操作算子都不能是阻塞式的。另外一个可能的好处是,可以简化代码的开发。多线程交互的代码是非常容易出错的。简述Follower副本消息同步的完整流程首先,FOnOWer发送FETCH请求给1.eade接着71.eader会读取底层日志文件中的消息数据,再更新它内存中的Follower副本的1.EO值,更新为FETCH请求中的fetchffset值。最后,尝试更新分区高水位值。FoHoWer接收到FETCH响应之后,会把消息写入到底层日志,接着更新1.EO和HW值。1.eader和Follower的HW值更新时机是不同的,Follower的HW更新永远落后于1.eader的HWo这种时间上的错配是造成各种不一致的原因。因此,对于消费者而言,消费到的消息永远是所有副本中最小的那个HW。附架构师面试题之Kafka专题篇1、Kafka是什么Kafka是一种高吞吐量、分布式、基于发布/订阅的消息系统,最初由1.inkedIn公司开发,使用SCala语言编写,目前是APaChe的开源项目。broker:Kafka服务器,负责消息存储和转发topic:消息类别,Kafka按照topic来分类消息Partition:topic的分区,一个topic可以包含多个partition,topic消息保存在各个partition±offset:消息在日志中的位置,可以理解是消息在PartitiOn上的偏移量,也是代表该消息的唯一序号Producer:消息生产者Consumer:消息消费者ConsumerGroup:消费者分组,每个Consumer必须属于一个groupZookeeper:保存着集群broker>topic>partition等meta数据;另外,还负责broker故障.现,partitionleader,而载均衡等功能2 .Kafka的设计时什么样的呢Kafka将消息以topic为单位进行归纳将向Kafkatopic发布消息的程序成为ProdUCers.将预订topics并消费消息的程序成为consumer.Kafka以集群的方式运行,可以由一个或爹个服务组成,每个服务叫做一个broker.producers通过网络将消息发送到Kafka集群,集群向消费者提供消息。3 .为什么要使用kafka,为什么要使用消息队列?缓冲和削峰:上游数据时有突发流量,下游可能扛不住,或者下游没有足够多的机器来保证冗余,kafka在中间可以起到一个缓冲的作用,把消息暂存在kafka中,下游服务就可以按照自己的节奏进行慢慢处理。解耦和扩展性:项目开始的时候,并不能确定具体需求。消息队列可以作为一个接口层,解耦重要的业务流程。只需要遵守约定,针对数据编程即可获取扩展能力。冗余:可以采用一对多的方式,一个生产者发布消息,可以被多个订阅topic的服务消费到,供多个毫无关联的业务使用。健壮性:消息队列可以堆积请求,所以消费端业务即使短时间死掉,也不会影响主要业务的正常进行。异步通信:很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。4 .数据传输的事物定义有哪三种?数据传输的事务定义通常有以下三种级别:(1)最多一次:消息不会被重复发送,最多被传输一次,但也有可能一次不传输(2)最少一次:消息不会被漏发送,最少被传输一次,但也有可能被重复传输.(3)精确的一次(EXaCtIyOnCe):不会漏传输也不会重复传输,每个消息都传输被一次而且仅仅被传输一次,这是大家所期望的5 .Kafka判断一个节点是否还活着有那两个条件?(1)节点必须可以维护和ZooKeeper的连接,Zookeeper通过心跳机制检查每个节点的连接(2)如果节点是个follower,他必须能及时的同步leader的写操作,延时不能太久6 .Kafka中的ISR、AR又代表什么?ISR的伸缩又指什么IsRiIn-SyncReplicas副本同步队列ARzAssignedReplicas所有副本ISR是由leader维护,follower从leader同步数据有一些延迟(包括延迟时间replica.lag.time.max.ms和延迟条数replica.lag.max.messages两个维度,当前最新的版本0.10.x中只支持replica.lag.time.max.ms这个维度),任意一个超过阈值都会把follower剔除出ISR,存入C)SR(Outof-SyncReplicas)列表,新加入的follower也会先存放在C)SR中。AR=ISR+0SRo7 .kafka中的broker是干什么的broker是消息的代理,Producers往Brokers里面的指定Topic中写消息,Consumers从Brokers里面拉取指定Topic的消息,然后进行业务处理,broker在中间起到一个代理保存消息的中转站。8 .producer是否直接将数据发送到broker的Ieader(主节点)?producer直接将数据发送到broker的Ieader(主节点),不需要在多个节点进行分发,为了帮助producer做到这点,所有的KaflCa节点都可以及时的告知:咖些节点是活动的,目标topic目标分区的Ieader在哪。这样PrOdUCer就可以直接将消息发送到目的地了9 .什么情况下一个broker会从isr中踢出去leader会维护一个与其基本保持同步的Replica列表,该列表称为ISR(in-syncReplica),每个Partition都会有一个ISR,而且是由Ieader动态维护,如果一个follower比一个leader落后太多,或者超过一定时间未发起数据复制请求,则leader将其重ISR中移除。10、Kafaconsumer是否可以消费指定分区消息?Kafkaconsumer消费消息时,向broker发出"fetch”请求去消费特定分区的消息,consumer指定消息在日志中的偏移量(offset),就可以消费从这个位置开始的消息,customer拥有了OffSet的控制权,可以向后回滚去重新消费之前的消息,这是很有意义的H>Kafka消息是采用PIIn模式,还是PUSh模式?Kafka最初考虑的问题是,customer应该从brokes拉取消息还是brokers将消息推送到COnSUmer,也就是PUIl还PUSh。在这方面,Kafka遵循了一种大部分消息系统共同的传统的设计:ProdUCer将消息推送到broker,consumer从broker拉取消息一些消息系统比如Scribe和ApacheFlume采用了push模式,将消息推送到下游的COnSUmer。这样做有好处也有坏处:由broker正定消息推送的速率,对于不同消费速率的consumer就不太好处理了。消息系统都致力于让consumer以最大的速率最快速的消费消息,但不幸的是,push模式下,当broker推送的速率远大于consumer消费的速率时,consumer恐怕就要崩溃了。最终Kafka还是选取了传统的pull模式Pull模式的另外一个好处是consumer可以自主决定是否批量的从broker拉取数据。Push模式必须在不知道下游consumer消费能力和消费策略的情况下决定是立即推送每条消息还是缓存之后批量推送。如果为了避免consumer崩溃而采用较低的推送速率,将可能导致一次只推送较少的消息而造成浪费。Pull模式下,consumer就可以根据自己的消费能力去决定这些策略PUII有个缺点是,如果broker没有可供消费的消息,将导致COnSUmer不断在循环中轮询,直到新消息到t达。为了避免这点,Kafl<a有个参数可以让COnSUmer阻塞知道新消息到达(当然也可以阻塞知道消息的数量达到某个特定的量这样就可以批量发)12 .Kafka存储在硬盘上的消息格式是什么?消息由一个固定长度的头部和可变长度的字节数组组成。头部包含了一个版本号和CRC32校验码。13 消息长度4bytes(value:l+4+n)14 版本号:lbyte3CRC15 校验码:4bytes16 具体的消息:nbytes13 .Kafka高效文件存储设计特点:(1) .Kafka把topic中一个parition大文件分成多个小文件段,通过多个小文件段,就容易定期清除或删除已经消费完文件,减少磁盘占用。(2).通过索引信息可以快速定位message和确定response的最大大小。(3).通过index元数据全部映射到memory,可以避免segmentfile的IO磁盘操作。(4).通过索引文件稀疏存储,可以大幅降低index文件元数据占用空间大小。14 .Kafka与传统消息系统之间有三个关键区别(I),Kaflca持久化日志,这些日志可以被重复读取和无限期保留(2).Kafka是一个分布式系统:它以集群的方式运行,可以灵活伸缩,在内部通过复制数据提升容错能力和高可用性(3).Kafka支持实时的流式处理15 .Kafka创建Topic时如何将分区放置到不同的Broker中(1) .副本因子不能大于Broker的个数;(2).第一个分区(编号为0)的第一个副本放置位置是随机从broker1.ist选择的;(3).其他分区的第一个副本放置位置相对于第0个分区依次往后移。也就是如果我们有5个BrOker,5个分区,假设第一个分区放在第四个BrOker上,那么第二个分区将会放在第五个Broker上;第三个分区将会放在第一个BrokerJt;第四个分区将会放在第二个Broker上,依次类推;(4).剩余的副本相对于第一个副本放置位置其实是由nextReplicaShift决定的,而这个数也是随机产生的16 .Kafka新建的分区会在哪个目录下创建在启动Kafka集群之前,我们需要配置好Iogdirs参数,其值是Kafka数据的存放目录,这个参数可以配置多个目录,目录之间使用逗号分隔,通常这些目录是分布在不同的磁盘上用于提高读写性能。当然我们也可以配置Iogdr参数,含义样。只需要:“'置.其中.个即可。如果iog.dirs参数只配置.个II#,那么分配到各个BrOker上的分区肯定只能在这个目录下创建文件夹用于存放数据。但是如果Iog.dirs参数配置了多个目录,那么Kafka会在哪个文件夹中创建分区目录呢?答案是:Kafka会在含有分区目录最少的文件夹中创建新的分区目录,分区目录名为TOPiC名十分区ID。注意,是分区文件夹总数最少的目录,而不是磁盘使用量最少的目录!也就是说,如果你给Iog.dirs参数新增了一个新的磁盘,新的分区目录肯定是先在这个新的磁盘上创建直到这个新的磁盘目录拥有的分区目录不是最少为止。17 .partition的数据如何保存到硬盘topic中的多个partition以文件夹的形式保存到broker,每个分区序号从0递增,且消息有序PartitiOn文件下有多个Segment(XXX.index,xxx.log)segment文件里的大小和配置文件大小一致可以根据要求修改默认为Ig如果大小大于Ig时,会滚动一个新的segment并且以上一个segment最后一条消息的偏移量命名18、讲讲kafka维护消费状态跟踪的方法大部分消息系统在broker端的维护消息被消费的记录:一个消息被分发到consumer后broker就马上进行标记或者等待customer的通知后进行标记。这样也可以在消息在消费后立马就删除以减少空间占用。但是这样会不会有什么问题呢?如果一条消息发送出去之后就立即被标记为消费过的,一旦COnSUmer处理消息时失败了(比如程序崩溃)消息就丢失了。为了解决这个问题,很多消息系统提供了另外一个个功能:当消息被发送出去之后仅仅被标记为已发送状态,当接到ConSUmer已经消费成功的通知后才标记为已被消费的状态。这虽然解决了消息丢失的问题,但产生了新问题,首先如果ConSUmer处理消息成功了但是向broker发送响应时失败了,这条消息将被消费两次。第二个问题时,broker必须维护每条消息的状态,并且每次都要先锁住消息然后更改状态然后释放锁。这样麻烦又来了,且不说要维护大量的状态数据,比如如果消息发送出去但没有收到消费成功的通知,这条消息将一直处于被锁定的状态,KaflCa采用了不同的策略。ToPiC被分成了若干分区,每个分区在同一时间只被一个ConSUmer消费。这意味着每个分区被消费的消息在日志中的位置仅仅是一个简单的整数:offset。这样就很容易标记每个分区消费状态就很容易了,仅仅需要一个整数而已。这样消费状态的跟踪就很简单了。这带来了另外一个好处:consumer可以把OffSet调成一个较老的值,去重新消费老的消息。这对传统的消息系统来说看起来有些不可思议,但确实是非常有用的,谁规定了一条消息只能被消费一次呢?19 .kafka的ack机制request.required.acks有三个值Ol-IO:生产者不会等待broker的ack,这个延迟最低彳旦是存需的保证最弱当SerVer挂掉的时候就会丢数据1:服务端会等待ack值leader副本确认接收到消息后发送ack但是如果leader挂掉后他不确保是否复制完成新Ieader也会导致数据丢失-1:同样在1的基础上服务端会等所有的follower的副本受到数据后才会受到leader发出的ack,这样数据不会丢失20 .Kafka的消费者如何消费数据消费者每次消费数据的时候,消费者都会记录消费的物理偏移量(offset)的位置等到下次消费时,他会接着上次位置继续消费21 .消费者负载均衡策略一个消费者组中的一个分片对应一个消费者成员,他能保证每个消费者成员都能访问,如果组中成员太多会有空闲的成员22 .数据有序一个消费者组里它的内部是有序的消费者组与消费者组之间是无序的23 .kafaka生产数据时数据的分组策略生产者决定数据产生到集群的哪个partition中每一条消息都是以(key,value)格式Key是由生产者发送数据传入所以生产者(key)决定了数据产生到集群的哪个partition24 .Kafka中的消息是否会丢失和重复消费?要确定Kafka的消息是否丢失或重复,从两个方面分析入手:消息发送和消息消费。1、消息发送Kafka消息发送有两种方式:同步(SynC)和异步(async),默认是同步方式,可通过producer.type属性进行配置。Kafka通过配置request.requi