KAFKA经典面试题

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

1、Kafka中的ISR、AR又代表什么?ISR的伸缩又指什么?

  • ISR (In Sync Replicas)
    所有与leader副本保持一定程度同步的副本(包括leader副本在内)组成。
  • OSR
    于leader副本同步滞后过多的副本(不包括leader副本)组成
  • AR
    AR= ISR + OSR。正常情况下,所有的follower副本都应该与leader 副本保持 一定程度的同步。
    即 AR=ISR,OSR集合为空。

2、Kafka中的HW、LEO、LSO、LW等分别代表什么?

](https://img-blog.csdnimg.cn/5a7f801361034df0872ab6b6ae29faa4.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5rC05Zyf5ZOl5ZOl,size_20,color_FFFFFF,t_70,g_se,x_16)
LW:是Low Watermark的缩写,俗称“低水位”,代表AR集合中最小的logStartOffset值。
LSO:特指LastStableOffset,它与kafka 事务有关。对于未完成的事务而言,LSO的值等于事 务中的第一条消息所在的位置(firstUnstableOffset);对于已经完成的事务而言,它的 值等同于HW相同。
LEO: (Log End Offset),它表示了当前日志文件中下一条待写入消息的offset。分区ISR集合中 的每个副本都会维护自身的LEO,而ISR集合中最小的LEO即为分区的HW。
HW: (High Watermark) ,俗称高水位,分区ISR集合中的每个副本都会维护自身的LEO,而 ISR集合中最小的LEO即为分区的HW。消费者只能拉取到这个offset之前的消息

3、Kafka中是怎么体现消息顺序性的?

Kafka只能保证分区内消息顺序有序,无法保证全局有序(因为消息会发送到不一样的分区,分 区之间发送的顺序是无法保证的)

4、Kafka中的分区器、序列化器、拦截器是否了解?它们之间的处理顺序是什么?

   主程序  --> 拦截器 --> 序列化器  --> 分区器  -->  发送到消息收集器

5、Kafka生产者客户端的整体结构是什么样子的?

在这里插入图片描述

6、Kafka生产者客户端中使用了几个线程来处理?分别是什么?

2个,主线程和Sender线程。
主线程:负责创建消息,然后通过拦截器、序列化器、分区器作用之后缓存到累加器 RecordAccumulator中。
Sender线程:负责将RecordAccumulator中消息发送到kafka中.

7、“消费组中的消费者个数如果超过topic的分区,就会有消费者消费不到数据”这句话是否正确?

正确

8、消费者提交消费位移时提交的是当前消费到的最新消息的offset还是offset+1?

offset+1

9、有哪些情形会造成重复消费?

 消费者消费后没有commit offset(程序崩溃/强行kill/消费耗时/自动提交偏移情况下unscrible)

10、那些情景下会造成消息漏消费?

消费者没有处理完消息 提交offset(自动提交偏移 未处理情况下程序异常结束)

11、Kafka的Consumer是非线程安全的,怎么样实现多线程消费?

1.在每个线程中新建一个KafkaConsumer

2.单线程创建KafkaConsumer,多个处理线程处理消息(难点在于是否要考虑消息顺序性,offset的提交方式

12、简述消费者与消费组之间的关系

消费组是一个逻辑上的概念,它将旗下的消费者归为一类,每一个消费者只隶属于一个消费组。每一个消费组都会有一个固定的名称,消费者在进行消费前需要指定其所属消费组的名称,这个可以通过消费者客户端参数 group.id 来配置,默认值为空字符串。

消费者并非逻辑上的概念,它是实际的应用实例,它可以是一个线程,也可以是一个进程。同一个消费组内的消费者既可以部署在同一台机器上,也可以部署在不同的机器上

13、当你使用kafka-topics.sh创建(删除)了一个topic之后,Kafka背后会执行什么逻辑?

创建:在zk上/brokers/topics/下节点 kafkabroker会监听节点变化创建主题

删除:调用脚本删除topic会在zk上将topic设置待删除标志,kafka后台有定时的线程会扫描所有需要删除的topic进行删除

14、topic的分区数可不可以增加或减少?

可以增加,不可以减少,被删除的分区数据难以处理(详情看参考文档)

15、创建topic时如何选择合适的分区数?

根据集群的机器数量和需要的吞吐量来决定适合的分区数(参考引荐)

16、Kafka目前有哪些内部topic,它们都有什么特征?各自的作用又是什么?

__consumer_offsets,保存消费者offset

17、优先副本是什么?它有什么特殊的作用?

优先副本 会是默认的leader副本 发生leader变化时重选举会优先选择优先副本作为leader

18、Kafka有哪几处地方有分区分配的概念?简述大致的过程及原理。

创建主题时
如果不手动指定分配方式 有两种分配方式
消费组内分配

19、简述Kafka的日志目录结构

1.每个分区对应一个文件夹,文件夹的命名为topic-0,topic-1
2.每个目录下面有三个日志文件,xxx.log是消息集文件, xxx.index 偏移量索引文件 ,xxx.timeindex 时间戳索引文件
3. 通过 index上的偏移量找到 log文件具体消息
4. 当在kafka中使用时间戳索引的时候,需要根据需要寻找的时间戳在时间戳索引seek到对应的时间戳段,然后通过这个时间戳段对应的offset段,再从在**.index**文件中找到对应的offset段,然后再偏移到实际数据的位置。 可以由此看出,时间戳索引是一个二级索引,需要完成两次索引操作

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

1.通过文件名前缀数字x找到该绝对offset 对应消息所在文件
2.offset-x为在文件中的相对偏移
3.通过index文件中记录的索引找到最近的消息的位置
4.从最近位置开始逐条寻找

21、聊一聊你对Kafka的Log Retention的理解

简要来说可分为两种方式控制消息保留,空间(retention.bytes)和时间(retention.ms)
运行机制:

生产者保存到broker中的消息,会保存在本地的logs/__consumer_offsets-xx/00000000000000000000.log文件中。
默认情况,这些文件不会永久保留,当超过了保留时间或体积后,kafka会对这些文件进行删除。
首先,根据log.retention条件判断,以segment为单位,判断该segment是否为可删除。
如果满足条件,将其标记为可删除。并且在日志文件cleaner-offset-checkpoint中记录当前清理到的位置。
由组件LogCleaner实现,将null写入该log文件中,这样该文件就被置空了

1.清除单位:日志清除的单位是日志段,即删除符合清楚策略的日志段文件和对应的索引文件;
2.清除策略
(1).基于时间的留存策略:Kafka默认会清除7天前的日志算数据,可以根据参数进行配置;
(2).基于大小的留存策略:Kafka默认只会为每个log保留log.retention.bytes参数值大小的字节数,可以根据参数进行配置;
3.清除过程:日志清除过程是一个异步过程,Kafkabroker启动后会创建单独的县城处理日志清除事宜;
4.注意事项:日志清除对于当前日志段是不生效的;

22、聊一聊你对Kafka的Log Compaction的理解

日志压实:确保Kafka topic每个分区下的每条具有相同key的消息都至少保存最新的value的消息,它提供了更加细粒度话的留存策略,也就是说,如果要使用log.compaction2,Kafka必须为每条消息设置key;
特点:log.compaction只会根据某种策略有选择的移除.log中的消息,并不会更改分区日志的offset值;
配置:log.compaction是topic级别的配置,逻辑划分上,log.compaction会将日志划分为已清理部分和未清理部分,后者又可以进一步划分为可清理和不可清理部分;
注意事项:当前日志段永远属于不可清理部分;
典型应用:__consumer_offsets内部topic用来保存位移信息,这个topic就是采用log.compaction留存期策略的。

23、聊一聊你对Kafka底层存储的理解(页缓存、内核层、块层、设备层)

页缓存:
1.本质:页缓存是操作系统实现的一种主要的磁盘缓存,以次用来减少对磁盘I/O的操作,具体来说,就是把磁盘的数据缓存在内存中,把对磁盘的访问变为对内存的访问;
2.数据读取:当一个进程准备读取磁盘上的文件内容时,操作系统回先查看待读取的数据所在的页(page)是否在页缓存上,如果命中,则直接返回数据,从而避免了队伍里磁盘的I/O操作,如果没有命中,操作系统会向磁盘发起读取请求并将读取的数据页存入页缓存中,之后再将数据返回给进程;
3.数据写入:如果一个进程需要将数据写入磁盘,那么操作系统也会监测数据对应的页是否在页缓存中,如果不在,则会先在页缓存中添加相应的页,最后将数据写入对应的页,被修改过的页也就变成了脏页,操作系统会在合适的时间把脏页中的数据写入磁盘中,以保持数据的一致性;
4.java的劣势:Java中,对象的内存开销非常大,通常时真实数据大笑的几倍甚至更多,空间使用率底下,Java的垃圾回收会随着堆内数据的增多而变得越来越慢,基于这些因素,使用文件系统并依赖也缓存的做法明显要由于维护一个进程内缓存或其他结构,至少我们可以省去了以根进程内部的缓存消耗,同时还可以通过结构紧凑的字节码来替代使用对象的方式以节省更多的空间。
5.其他优势:积时Kafka服务重启,页缓存还是会保持有效,然而进程中的缓存却需要重建,这样页极大的简化了代码逻辑,因为维护页缓存和文件之间的一致性交给操作系统来负责,比在进程内维护更加安全有效;
零拷贝:
直接让操作系统的 Cache 中的数据发送到网卡后传输给下游的消费者,中间跳过了两次拷贝数据的步骤,Socket 缓存中仅仅会拷贝一个描述符过去,不会拷贝数据到 Socket 缓存

24、聊一聊Kafka的延时操作的原理

1.Kafka中由多种延时操作,比如延时生产,延时拉取,延时数据删除等;
2.延时操作创建之后会被加入到延时操作管理器中来做专门的处理,演示操作有时候会超时,每个延时操作管理器都会配备一个定时器来做超时管理,定时器的底层就是采用时间轮实现的

25、聊一聊Kafka控制器的作用

原理:就是处理集群中所有的管理事务,并向集群中各个broker同步元数据信息的。
1.controller生成:Kafka集群启动时,第一个在zookeeper的/controller目录下新建子节点的broker被选举为该kafka集群的控制器;
2.controller高可用:通过zookeeper的临时节点+watcher事件实现,/controller下的子节点为临时节点,controller所在的broker崩溃就会消失,这样其他broker通过watcher事件收到消息,又会进行新的controller选举(第一个在zookeeper的/controller目录下新建子节点的broker为新的controller);
3.controller职责:负责管理集群中所有分区和读本状态,当某个分区的leader副本出现故障时,由controller负责为该分区选举出新的leader副本,检测到某个分区的ISR集合发生变化时,由controller负责将元数据信息同步到Kafka集群中,他还负责topic的增加于删除,分区的重分配,优先副本的选举,topic的分区扩展,Kafka集群的扩展,broker崩溃,受控关闭,controller leader的选举等等事项;

26、消费再均衡的原理是什么?(提示:消费者协调器和消费组协调器)

一、触发操作:
1.组成员发生变更:比如新的consumer加入组,或者已有的conusmer主动离开组,或者已有的consumer崩溃触发rebalance;
2.组订阅topic数发生变更:比如使用基于正则表达式的订阅,当匹配到正则表达式的topic被创建时就会触发rebalance;
3.组订阅topic的分区数发生变化:比如使用命令行脚本增加了订阅topic的分区数;
二、rebalance协议:

1.JoinGroup:consumer请求加入组;
2.SyncGroup:group leader把分配方案同步更新到组内所有成员中;
3.HeartBeat:cousumer定期向coordinate汇报心跳表示自己依然存活;
4.LeaveGroup:consumer主动通知coordinate自己即将离组;
5.DescribeGroup:查看组信息,包括成员信息,协议信息,分配方案,订阅信息等;

三、rebalance流程:
1.首先确定coordinate所在的broker,并创建与该broker相互通信的socket连接;
2.成功连接coordinate之后就可以进行热balance操作;
3.rebalance:
1.加入组:
1.所有consumer(group.id相同的所有consumer实例)向coordinate发送JoinGroup请求;
2.当收集全JoinGroup后,coordinate会从中选择一个consumer担任group的leader,并把所有成员信息以及他们的的订阅信息发送给leader;
2.同步更新分配方案:
1.leader开始制定分配方案,即根据前面提到的分区分配策略决定每个consumer都负责哪些topic的哪些分区;
2.分配完成后,leader就会将分配方案装进SyncGroup请求中并发送给coordinate;
3.coordinate接收到分配方案后,把属于每个consumer的方案单独取出来作为SyncGroup请求的response返还给各自的consumer;
在这里插入图片描述
在这里插入图片描述

27、Kafka中的幂等性是怎么实现的:

生产者的幂等性:
1.producer id:PID,每个生产者在初始化时都会被分配一个PID,这个过程对用户而言是完全透明的;
2.序列号:对于每个 PID,消息发送到的每一个分区都有对应的序列号,这些序列号从0开始单调递增。生产者每发送一条消息就会将 <PID,分区> 对应的序列号的值加1;
3.broker端:broker 端会在内存中为每一对 <PID,分区> 维护一个序列号。对于收到的每一条消息,只有当它的序列号的值(SN_new)比 broker 端中维护的对应的序列号的值(SN_old)大1(即 SN_new = SN_old + 1)时,broker 才会接收它。

29、Kafka中的事务是怎么实现的:

Kafka中的事务:可以使应用程序将消费消息、生产消息、提交消费位移当作原子操作来处理,同时成功或失败,即使该生产或消费会跨多个分区。
实现:
1.Kafka为实现事务要求应用程序必须提供唯一一个id表证事务(事务ID),他必须在应用程序所有的会话上是唯一的,事务ID和PID不同,事务ID是用户显式提供,后者是prodcuer自行分配的;
2.有了事务Id后,Kafka就能确保:
1.跨应用程序会话间幂等性发送语义(类似generation);
2.支持跨会话的事务恢复;
3.Kafka在消息属性字段中添加控制信息来实现事务,控制信息有两类——COMMIT和ABORT,分别表示事务提交和事务种植,将控制信息保存在Kafka日志中的目的是为了让consumer能够识别事务边界,从而整体的读取某个事务下的所有消息;
4.通俗地说,凡是被标记事务ID的消息都在一个事务里,然后在消息中保存事务控制信息 ,可以使consumer分辨事务边界,停止事务;
consumer端事务支持:略微弱一点,原因如下:
1.对于compactted的topic而言,事务中的消息可能已经被删除了;
2.事务可能跨日志段,若老的日志段被删除,则用户将丢失事务中的部分消息;
3.consumer层序可能使用seek方法定位事务中的任意为止,造成部分消息的丢失;
4.consumer可能选择不消费事务中的所有消息,即无法保证读取失去的全部消息;

30、Kafka中有那些地方需要选举,这些地方的选举策略又有哪些:

**controller:**在Kafka集群中选取一个broker用于管理Kafka集群,Kafka集群启动时,第一个注册到zookeeper的/controller节点上的broker称为该集群的controller;
Leader Replica:负责partition中的数据读写,而follower副本会被动从leader中同步数据,leader的选举由controller负责(设置优先副本时,按照优先副本来确定);
coordinator:负责协调consumer group的管理事宜,由controller进行选举;
Leader consumer:负责指定rebalance分配方案,第一个发送给coordinate JoinGroup消息的consumer会被选举为Leader consumer;

31、失效副本是指什么?有那些应对措施:

失效副本:follower replica中消息的进度落后于leader;
应对措施
1.将失效副本移除LEO组,当失效副本中消息进度赶上leader副本时,再将其加入LEO组合;
2.找到副本追赶不上的原因,是broker端参数配置不合理,还是follower副本端程序有问题,还是网络问题等,排查出原因后解决。
副本失效场景
1.follower 副本进程卡住,在一段时间内根本没有向 leader 副本发起同步请求,比如频繁的 Full GC;
2.follower 副本进程同步过慢,在一段时间内都无法追赶上 leader 副本,比如 I/O 开销过大;
3.如果通过工具增加了副本因子,那么新增加的副本在赶上 leader 副本之前也都是处于失效状态的;
4.如果一个 follower 副本由于某些原因(比如宕机)而下线,之后又上线,在追赶上 leader 副本之前也处于失效状态;

32、多副本下,各个副本中的HW和LEO的演变过程:

1.副本属性初始状态图:
在这里插入图片描述

2.leader副本写入消息后follower副本发送FETCH请求:
1.leader写入消息到底层日志,同时更新inleader副本的LEO属性;
2.尝试更新leader副本的HW值(失败);
3.follower发送fetch请求,leader端读取底层log数据;
4.更新remote LEO=0;
5.尝试更新分区HW,此时Leader LEo=1,remoteLEO=0,所以HW=0,更新失败;
6.把数据和当前分区的HW值发送给follower副本;
7.follower副本接收到fetch response后,将数据写入本地log,同时更新follower LEO;
8.更新follow HW(失败);
在这里插入图片描述

3.第二轮Fetch请求:
1.leader端姐到请求后,读取底层log数据;
2.更新remote LEO=1;
3.尝试更新分区HW=1,更新成功,因为此时的lEO和remote LEO都等于1;
4.把数据(实际上没有数据)和当前分区HW值(已经为1)发送给follower副本;
5.follower副本接收到Fetch response请求后,写入本地log(无东西可写);
6.更新LEO,没有写数据,就不会更新,故LEO=1;
7更新HW,比较本地LEO和当前leader的LEO取最小值,最小值为1,此时更新follower上的HW=1;
在这里插入图片描述

33、为什么Kafka不支持读写分离:

读写分离缺点:
数据一致性问题:数据从主节点转到从节点,必然会有一个延时的时间窗口,这个时间窗口会导致主从节点之间的数据不一致;
延时问题:数据从写入主节点到同步至从节点中的过程,需要经历经历网络→主节点内存→主节点磁盘→网络→从节点内存→从节点磁盘阶段,对延时敏感的应用而言,主写从读的功能并不太适用。
当前方案收益
1.可以简化代码的实现逻辑,减少出错的可能;
2.将负载粒度细化均摊,与主写从读相比,不仅负载效能更好,而且对用户可控(使用partition);
3.没有延时的影响;
4.在副本稳定的情况下,不会出现数据不一致的情况。

34、Kafka在可靠性方面做了哪些改进:

HW:高水位,消费者只能消费位移再HW之前的消息,分区 ISR 集合中的每个副本都会维护自身的 LEO,而 ISR 集合中最小的 LEO 即为分区的 HW;
leader epoch:leader epoch 代表 leader 的纪元信息(epoch),初始值为0。每当 leader 变更一次,leader epoch 的值就会加1,相当于为 leader 增设了一个版本号。epoch是一对值<epoch,offset>,每个leader会保存一个缓存,定期将其写入一个检查点文件中,如果leader首次写消息,则会在缓存中增加一个条目,负责不做更新,每次副本称为新的leader是会查询这部分缓存,获取对应的leader版本位移

35、Kafka中怎么实现死信队列和重试队列:

死信队列:可以看作消费者不能处理收到的消息,也可以看作消费者不想处理收到的消息,还可以看作不符合处理要求的消息。比如消息内包含的消息内容无法被消费者解析,为了确保消息的可靠性而不被随意丢弃,故将其投递到死信队列中;
重试队列:可以看作一种回退队列,具体指消费端消费消息失败时,为了防止消息无故丢失而重新将消息回滚到 broker 中,重试队列一般分成多个重试等级,每个重试等级一般也会设置重新投递延时,重试次数越多投递延时就越大;
设置重试队列:消息第一次消费失败入重试队列 Q1,Q1 的重新投递延时为5s,5s过后重新投递该消息;如果消息再次消费失败则入重试队列 Q2,Q2 的重新投递延时为10s,10s过后再次投递该消息;
设置死信队列:重试越多次重新投递的时间就越久,并且需要设置一个上限,超过投递次数就进入死信队列;
注:仅作了解即可。

36、Kafka中的延迟队列怎么实现:

延迟队列:在发送延时消息的时候并不是先投递到要发送的真实主题中,而是先投递到一些 Kafka 内部的主题中,这些内部主题对用户不可见,然后通过一个自定义的服务拉取这些内部主题中的消息,并将满足条件的消息再投递到要发送的真实的主题中,消费者所订阅的还是真实的主题。
注:仅作了解即可。

37、Kafka中怎么做消息审计:

消息审计:在消息生产、存储和消费的整个过程之间对消息个数及延迟的审计,以此来检测是否有数据丢失、是否有数据重复、端到端的延迟又是多少等内容。
实现:主要通过在消息中内嵌消息对应的时间戳 timestamp 或全局的唯一标识 ID来实现消息的审计功能。
内嵌 timestamp: 设置一个审计的时间间隔 time_bucket_interval,根据这个 time_bucket_interval 和消息所属的 timestamp 来计算相应的时间桶(time_bucket)。
内嵌 ID :对于每一条消息都会被分配一个全局唯一标识 ID。如果主题和相应的分区固定,则可以为每个分区设置一个全局的 ID。当有消息发送时,首先获取对应的 ID,然后内嵌到消息中,最后才将它发送到 broker 中。消费者进行消费审计时,可以判断出哪条消息丢失、哪条消息重复

38、Kafka中怎么做消息轨迹:

消息轨迹:指的是一条消息从生产者发出,经由 broker 存储,再到消费者消费的整个过程中,各个相关节点的状态、时间、地点等数据汇聚而成的完整链路信息。生产者、broker、消费者这3个角色在处理消息的过程中都会在链路中增加相应的信息,将这些信息汇聚、处理之后就可以查询任意消息的状态;
实现:封装客户端,在保证正常生产消费的同时添加相应的轨迹信息埋点逻辑。无论生产,还是消费,在执行之后都会有相应的轨迹信息,我们需要将这些信息保存起来。

39、Kafka有哪些指标需要着重关注:

BytesIn/BytesOut:Broker 端每秒入站和出站字节数,接近网络带宽会出现网络丢包;
NetworkProcessorAvgIdlePercent:即网络线程池线程平均的空闲比例。
RequestHandlerAvgIdlePercent:即 I/O 线程池线程平均的空闲比例。
UnderReplicatedPartitions:即未充分备份的分区数。
ISRShrink/ISRExpand:即 ISR 收缩和扩容的频次指标。
Broker 端每秒入站和出站字节数:即当前处于激活状态的控制器的数量。正常情况下,Controller 所在 Broker 上的这个 JMX 指标值应该是 1,其他 Broker 上的这个值是 0。如果你发现存在多台 Broker 上该值都是 1 的情况,表示集群出现了脑裂。
注:仅做了解,实际应用时使用;

40、怎么计算Lag(注意read_uncommitted和read_committed状态下的不同):

1.如果消费者客户端为“read_uncommitted”,它对应的 Lag 等于HW – ConsumerOffset 的值,其中 ConsumerOffset 表示当前的消费位移。
-2.如果这个参数配置为“read_committed”,它对应的 Lag 等于 LSO(LastStableOffset ) – ConsumerOffset 的值。

41、Kafka的那些设计让它有如此高的性能:

1.partition,producer和consumer端的批处理:提高并行度;
2.页缓存:大量使用页缓存,内存操作比磁盘操作快很多,数据写入直接写道页缓存,由操作系统负责刷盘,数据读取也是直接命中页缓存,从内存中直接拿到数据;
3.零拷贝:如果数据读取命中了页缓存,数据会从页缓存直接发送到网卡进行数据传输,省略了用户态和内核态的切换以及多次的数据拷贝;
4.顺序读写:Kafka的数据是顺序追加的,避免了低效率的随机读写;
5.优秀的文件存储机制:分区规则设置合理的话,所有消息都可以均匀的分不到不同分区,分区日志还可以分段,相当于举行文件被平均分配为多个相对较小的文件,便于文件维护和清理;
索引文件:Kafka含有.index和.timeindex索引,以稀疏索引的方式进行构造,查找时可以根据二分法在索引文件中快速定位到目标数据附近位置,然后再.log文件中顺序读取到目标数据;

42、Kafka有什么优缺点:

kafka的优点:
1.支持多个生产者和消费者;
2.支持broker的横向拓展;
3.副本集机制,实现数据冗余,保证数据不丢失;
4.通过分批发送压缩数据的方式,减少数据传输开销,提高吞高量
5.支持点对点和发布订阅;
6.基于磁盘实现数据的持久化;
7.毫秒级延迟;
8.对CPU和内存,网络的消耗比较小;
缺点:
1.由于是批量发送,所以数据达不到真正的实时;
2.只能支持统一分区内消息有序,无法实现全局消息有序;
3.需要配合zookeeper进行元数据管理;
4.可能会重复消费数据,消息会乱序;

43、为什么选择Kafka:

1.kafka特点:
1.支持点对点以及发布订阅模式:Kafka的consumer group策略,同一个consumer group中的consumer不能同时订阅同一个partition,这实现了点对点策略,一个topic中的partition可以被不同的consumer group订阅,这是实现了发布订阅模式;
2.语言支持:支持多种语言,Java优先,新版本的produce和consumer都是用Java语言写的;
3.单机吞吐量:十万级,因为Kafka的写入策略是将消息写入到页缓存,写入内存速度自然是非常高的;
4.消息延迟:毫秒级,因为消息读取时首先从页缓存中进行命中,且采用了零拷贝策略,省略了消息传递时的IO时间,以及消息传递时再用户态和内核态切换的时间;
5.API完备性:高;
6.可用性:非常高,使用zookeeper实现,kafka中的元数据都存储在zookeeper的节点上,利用zookeeper的临时节点+watcher事件机制实现数据一致性,故可用性非常高;
7.消息丢失:可以配置produce端和consumer端的参数保证消息不会丢失;

producer端:
ack=all/-1:全部ISR中的服务器将消息写入到页缓存时给客户端返回相应消息;
retire=Interger.MaAX_VALUE:全部ISR中的服务器将消息写入到页缓存时给客户端返回相应消息;
max.in.flight.requests.per.connection=1:单次只能send一个消息给broker,避免消息分区offset错乱;
使用待回调机制的send发送消息;
unclean.leader.election.enable=flase:不允许非ISR的节点被选举为leader;
replication.factor=3:多副本保存;
min.insync.replicas:ISR至少拥有的节点数量;
replication.factor>min.insync.replicas;
consumer端:
enable.auto.commit = false:对消息进行处理后,再进行位移提交;

8.消息重复:理论上会有重复,但是kafka给重复消息赋了一个相同的ID来达到消息的幂等性;
9.文档完备性:高;
10.提供快速入门:高;

44、在使用Kafka的过程中遇到过什么困难,怎么解决的:

1.数据丢失:数据接入时,采用完全异步方式接入导致数据丢失
解决方案:使用异步+回调的方式进行数据接入;
2.多线程消费数据冲突:日志报错多线程消费数据冲突;
解决方案:使用一个consumer+worker线程池的方式解决问题;
多线程消费数据:
1.多线程维护专属consumer:

2.单consumer+worker线程池,数据拉取和数据处理解耦:
3.两种多线程方法实现的区别:
3.Kafka的优先副本:注:明天过去回顾下,和张蕾讨论下;

45、怎么样才能确保Kafka极大程度上的可靠性:

HW:consumer只能消费位移在HW以下的数据;
epoch:用于在更新HW和LEO时保证消息不丢失,且不发生消息不一致的情况;
保证消费者不重复消费:可以根据业务指定唯一性的key, 如果发现已经消费过,则直接跳过(事务机制)。
消费者消息不遗漏:关闭自动提交offset, 消息消费成功后,手动提交offset.
生产者不重复发消息:生产者不重复发消息,生产者会为每个消息附一个PID,broker发现PID相同的消息会自动丢弃去重;
生产者发消息不遗漏:生产者开启消息重试机制;
保证生产者消息的顺序是正确的:sender线程每次发送消息只发送一条;
不允许非ISr中的broker成为新的leader:可以保证broker端不会丢数据;
ISR中存活的broker不能少于一个:保证数据高可靠性;

46、Kafka的用途有哪些,使用场景如何:

1.异步处理:
场景:用户注册账号后需要发送注册邮件和注册短信:
方案:引入消息队列将不是必须的业务逻辑,异步处理。
2.应用解耦:
场景:用户下订单后,订单系统需要通知库存系统,缺点是订单系统和库存系统耦合,如果库存系统无法访问,那么订单则减库存失败,导致用户下订单失败;
方案:引入消息队列进行应用解耦。
3.数据削峰:
场景:秒杀活动,会因为流量过大,导致流量暴增,应用挂掉
方案:引入消息队列控制活动的人数,缓解短时间内高流量压垮应用:
步骤:1.用户发出请求后,服务器接收,首先写入消息队列中,加入消息队列长度超过最大数量,则直接抛弃用户请求或者直接跳转到用户界面;2.秒杀业务根据消息队列中的请求消息,在做后续处理;
4.日志处理:
场景:秒杀活动,会因为流量过大,导致流量暴增,应用挂掉
方案:引入消息队列控制活动的人数,缓解短时间内高流量压垮应用:
步骤:1.用户发出请求后,服务器接收,首先写入消息队列中,加入消息队列长度超过最大数量,则直接抛弃用户请求或者直接跳转到用户界面;2.秒杀业务根据消息队列中的请求消息,在做后续处理;

**

总结: 引用了网上很多大佬的帖子,感谢大佬的付出。我自己根据自己理解整理了一下,希望对看到的小伙伴有所帮助。加油各位!!

**

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值