Kafka的相关

1. 防止重复消费消息

消息发送端只发送一次,

消费端手动提交偏移量(偏移量可以存储在redis等,key为topic+group+partition, value为偏移量)

幂等校验(根据唯一字段,从数据库或redis中查询是否已经消费过)

2. 防止消息丢失

ISR中的leader partition和follow partition的数据是一致的,如果不一致的follow partition会被转移到OSR

 ack设置为all表示leader partition已经消息同步给了follow partition完后再返回

并且还需设置如果leader partition挂了,重新选举需要从ISR中选举。

配置ISR中的副本数大于1

需要设置手动提交offset

broker中的pageCache会缓存发送端的消息,然后定期去持久化到硬盘,如果linux机器挂了,还没来得及持久化到硬盘会丢失消息,因此需要减少broker的刷盘间隔

设置消息发送失败重试次数大于1

3. 消息积压

1)线上有时因为发送方发送消息速度过快,或者消费方处理消息过慢,可能会导致broker积压大量未消费消息。
此种情况如果积压了上百万未消费消息需要紧急处理,可以修改消费端程序,让其将收到的消息快速转发到其他topic(可以设置很多分区),然后再启动多个消费者同时消费新主题的不同分区。
2)由于消息数据格式变动或消费者程序有bug,导致消费者一直消费不成功,也可能导致broker积压大量未消费消息。
此种情况可以将这些消费不成功的消息转发到其它队列里去(类似死信队列),后面再慢慢分析死信队列里的消息处理问题。
4. 消息乱序
如果发送端配置了重试机制,kafka不会等之前那条消息完全发送成功才去发送下一条消息,这样可能会出现,发送了1,2,3条消息,第一条超时了
,后面两条发送成功,再重试发送第1条消息,这时消息在broker端的顺序就是2,3,1了
所以,是否一定要配置重试要根据业务情况而定。也可以用同步发送的模式去发消息,当然acks不能设置为0,这样也能保证消息发送的有序。
kafka保证全链路消息顺序消费,需要从发送端开始,将所有有序消息发送到同一个分区,然后用一个消费者去消费
,但是这种性能比较低,可以在消费者端接收到消息后将需要保证顺序消费的几条消费发到内存队列(可以搞多个),一个内存队列开启一个线程顺序处理消息
 

 

1

Kafka 遵循了一种大部分消息系统共同的传统的设计:producer 将消息推送到 broker,consumer 从broker 拉取消息。

优点:pull模式消费者自主决定是否批量从broker拉取数据,而push模式在无法知道消费者消费能力情况下,不易控制推送速度,太快可能造成消费者奔溃,太慢又可能造成浪费。

缺点:如果 broker 没有可供消费的消息,将导致 consumer 不断在循环中轮询,直到新消息到到达。为了避免这点,Kafka 有个参数可以让 consumer阻塞知道新消息到达(当然也可以阻塞知道消息的数量达到某个特定的量这样就可以批量发送)。

2 zookeeper对于kafka的作用是什么?

Zookeeper 主要用于在集群中不同节点之间进行通信,在 Kafka 中,它被用于提交偏移量,因此如果节点在任何情况下都失败了,它都可以从之前提交的偏移量中获取,除此之外,它还执行其他活动,如: leader 检测、分布式同步、配置管理、识别新节点何时离开或连接、集群、节点实时状态等等。

 

3 kafka维护消息状态的跟踪方法
Kafka中的Topic 被分成了若干分区,每个分区在同一时间只被一个 consumer 消费。然后再通过offset进行消息位置标记,通过位置偏移来跟踪消费状态。相比其他一些消息队列使用“一个消息被分发到consumer 后 broker 就马上进行标记或者等待 customer 的通知后进行标记”的优点是,避免了通信消息发送后,可能出现的程序奔溃而出现消息丢失或者重复消费的情况。同时也无需维护消息的状态,不用加锁,提高了吞吐量。

4、kafka判断一个节点还活着的有那两个条件?
(1)节点必须维护和 ZooKeeper 的连接,Zookeeper 通过心跳机制检查每个节点的连接
(2)如果节点是个 follower,他必须能及时的同步 leader 的写操作,延时不能太久

5、讲一讲 kafka 的 ack 的三种机制
request.required.acks 有三个值 0 1 -1(all),具体如下:
0:生产者不会等待 broker 的 ack,这个延迟最低但是存储的保证最弱当 server 挂掉的时候就会丢数据。
1:服务端会等待 ack 值 leader 副本确认接收到消息后发送 ack 但是如果 leader挂掉后他不确保是否复制完成新 leader 也会导致数据丢失。
-1(all):服务端会等所有的 follower 的副本受到数据后才会受到 leader 发出的ack,这样数据不会丢失。

6、kafka 分布式(不是单机)的情况下,如何保证消息的顺序消费?
Kafka 中发送 1 条消息的时候,可以指定(topic, partition, key) 3 个参数,partiton 和 key 是可选的。

Kafka 分布式的单位是 partition,同一个 partition 用一个 write ahead log 组织,所以可以保证FIFO 的顺序。不同 partition 之间不能保证顺序。因此你可以指定 partition,将相应的消息发往同 1个 partition,并且在消费端,Kafka 保证1 个 partition 只能被1 个 consumer 消费,就可以实现这些消息的顺序消费。

另外,你也可以指定 key(比如 order id),具有同 1 个 key 的所有消息,会发往同 1 个partition,那这样也实现了消息的顺序消息。

7、kafka 如何不消费重复数据?比如扣款,我们不能重复的扣。
这个问题换种问法,就是kafka如何保证消息的幂等性。对于消息队列来说,出现重复消息的概率还是挺大的,不能完全依赖消息队列,而是应该在业务层进行数据的一致性幂等校验。

比如你处理的数据要写库(mysql,redis等),你先根据主键查一下,如果这数据都有了,你就别插入了,进行一些消息登记或者update等其他操作。另外,数据库层面也可以设置唯一健,确保数据不要重复插入等 。一般这里要求生产者在发送消息的时候,携带全局的唯一id。

8、讲一下kafka集群的组成?
kafka的集群图如下:

Broker(代理)

Kafka集群通常由多个代理组成以保持负载平衡。 Kafka代理是无状态的,所以他们使用ZooKeeper来维护它们的集群状态。 一个Kafka代理实例可以每秒处理数十万次读取和写入,每个Broker可以处理TB的消息,而没有性能影响。 Kafka经纪人领导选举可以由ZooKeeper完成。

ZooKeeper

ZooKeeper用于管理和协调Kafka代理。 ZooKeeper服务主要用于通知生产者和消费者Kafka系统中存在任何新代理或Kafka系统中代理失败。 根据Zookeeper接收到关于代理的存在或失败的通知,然后生产者和消费者采取决定并开始与某些其他代理协调他们的任务。

Producers(生产者)

生产者将数据推送给经纪人。 当新代理启动时,所有生产者搜索它并自动向该新代理发送消息。 Kafka生产者不等待来自代理的确认,并且发送消息的速度与代理可以处理的一样快。

Consumers(消费者)

因为Kafka代理是无状态的,这意味着消费者必须通过使用分区偏移来维护已经消耗了多少消息。 如果消费者确认特定的消息偏移,则意味着消费者已经消费了所有先前的消息。 消费者向代理发出异步拉取请求,以具有准备好消耗的字节缓冲区。 消费者可以简单地通过提供偏移值来快退或跳到分区中的任何点。 消费者偏移值由ZooKeeper通知。

9、kafka是什么?
Kafka是一种高吞吐量、分布式、基于发布/订阅的消息系统,最初由LinkedIn公司开发,使用Scala语言编写,目前是Apache的开源项目。

broker: Kafka服务器,负责消息存储和转发

topic:消息类别,Kafka按照topic来分类消息

partition: topic的分区,一个topic可以包含多个partition, topic 消息保存在各个partition上4. offset:消息在日志中的位置,可以理解是消息在partition上的偏移量,也是代表该消息的唯一序号

Producer:消息生产者

Consumer:消息消费者

Consumer Group:消费者分组,每个Consumer必须属于一个group

Zookeeper:保存着集群 broker、 topic、 partition等meta 数据;另外,还负责broker故障发现, partition leader选举,负载均衡等功能

10、partition的数据文件(offffset,MessageSize,data)
partition中的每条Message包含了以下三个属性: offset,MessageSize,data,其中offset表示Message在这个partition中的偏移量,offset不是该Message在partition数据文件中的实际存储位置,而是逻辑上一个值,它唯一确定了partition中的一条Message,可以认为offset是partition中Message的 id; MessageSize表示消息内容data的大小;data为Message的具体内容。

11、kafka如何实现数据的高效读取?(顺序读写、分段命令、二分查找)
Kafka为每个分段后的数据文件建立了索引文件,文件名与数据文件的名字是一样的,只是文件扩展名为index。 index文件中并没有为数据文件中的每条Message建立索引,而是采用了稀疏存储的方式,每隔一定字节的数据建立一条索引。这样避免了索引文件占用过多的空间,从而可以将索引文件保留在内存中。

12、 Kafka 消费者端的 Rebalance 操作什么时候发生?
同一个 consumer 消费者组 group.id 中,新增了消费者进来,会执行 Rebalance 操作
消费者离开当期所属的 consumer group组。比如宕机
分区数量发生变化时(即 topic 的分区数量发生变化时)
消费者主动取消订阅
Rebalance的过程如下:

第一步:所有成员都向coordinator发送请求,请求入组。一旦所有成员都发送了请求,coordinator会从中选择一个consumer担任leader的角色,并把组成员信息以及订阅信息发给leader。

第二步:leader开始分配消费方案,指明具体哪个consumer负责消费哪些topic的哪些partition。一旦完成分配,leader会将这个方案发给coordinator。coordinator接收到分配方案之后会把方案发给各个consumer,这样组内的所有成员就都知道自己应该消费哪些分区了。

所以对于Rebalance来说,Coordinator起着至关重要的作用

13、Kafka 中的ISR(InSyncRepli)、OSR(OutSyncRepli)、AR(AllRepli)代表什么?
答:kafka中与leader副本保持一定同步程度的副本(包括leader)组成ISR。与leader滞后太多的副本组成OSR。分区中所有的副本通称为AR。

ISR : 速率和leader相差低于10秒的follower的集合
OSR : 速率和leader相差大于10秒的follower
AR : 全部分区的follower

14、Kafka 中的HW、LEO等分别代表什么?
答:HW:高水位,指消费者只能拉取到这个offset之前的数据

LEO:标识当前日志文件中下一条待写入的消息的offset,大小等于当前日志文件最后一条消息的offset+1.

15、Kafka的那些设计让它有如此高的性能?
1.kafka是分布式的消息队列
2.对log文件进行了segment,并对segment创建了索引
3.(对于单节点)使用了顺序读写,速度能够达到600M/s
4.引用了zero拷贝,在os系统就完成了读写操做

16、Kafka为什么不支持读写分离?
1、 这其实是分布式场景下的通用问题,因为我们知道CAP理论下,我们只能保证C(一致性)和A(可用性)取其一,如果支持读写分离,那其实对于一致性的要求可能就会有一定折扣,因为通常的场景下,副本之间都是通过同步来实现副本数据一致的,那同步过程中肯定会有时间的消耗,如果支持了读写分离,就意味着可能的数据不一致,或数据滞后。

2、 Leader/Follower模型并没有规定Follower副本不可以对外提供读服务。很多框架都是允许这么做的,只是 Kafka最初为了避免不一致性的问题,而采用了让Leader统一提供服务的方式。

3、 不过,自Kafka 2.4之后,Kafka提供了有限度的读写分离,也就是说,Follower副本能够对外提供读服务。

17、分区Leader选举策略有几种?
分区的Leader副本选举对用户是完全透明的,它是由Controller独立完成的。你需要回答的是,在哪些场景下,需要执行分区Leader选举。每一种场景对应于一种选举策略。

1、 OfflinePartition Leader选举:每当有分区上线时,就需要执行Leader选举。所谓的分区上线,可能是创建了新分区,也可能是之前的下线分区重新上线。这是最常见的分区Leader选举场景。

2、 ReassignPartition Leader选举:当你手动运行Kafka-reassign-partitions命令,或者是调用Admin的alterPartitionReassignments方法执行分区副本重分配时,可能触发此类选举。假设原来的AR是[1,2,3],Leader是1,当执行副本重分配后,副本集合AR被设置成[4,5,6],显然,Leader必须要变更,此时会发生Reassign Partition Leader选举。

3、 PreferredReplicaPartition Leader选举:当你手动运行Kafka-preferred-replica-election命令,或自动触发了Preferred Leader选举时,该类策略被激活。所谓的Preferred Leader,指的是AR中的第一个副本。比如AR是[3,2,1],那么,Preferred Leader就是3。

4、 ControlledShutdownPartition Leader选举:当Broker正常关闭时,该Broker上的所有Leader副本都会下线,因此,需要为受影响的分区执行相应的Leader选举。

这4类选举策略的大致思想是类似的,即从AR中挑选首个在ISR中的副本,作为新Leader。

18、请简述下你在哪些场景下会选择 Kafka?
•日志收集:一个公司可以用Kafka可以收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer,例如hadoop、HBase、Solr等。
•消息系统:解耦和生产者和消费者、缓存消息等。
•用户活动跟踪:Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到hadoop、数据仓库中做离线分析和挖掘。
•运营指标:Kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告。
•流式处理:比如spark streaming和 Flink

19、请谈一谈 Kafka 数据一致性原理
一致性就是说不论是老的 Leader 还是新选举的 Leader,Consumer 都能读到一样的数据。


假设分区的副本为3,其中副本0是 Leader,副本1和副本2是 follower,并且在 ISR 列表里面。虽然副本0已经写入了 Message4,但是 Consumer 只能读取到 Message2。因为所有的 ISR 都同步了 Message2,只有 High Water Mark 以上的消息才支持 Consumer 读取,而 High Water Mark 取决于 ISR 列表里面偏移量最小的分区,对应于上图的副本2,这个很类似于木桶原理。

这样做的原因是还没有被足够多副本复制的消息被认为是“不安全”的,如果 Leader 发生崩溃,另一个副本成为新 Leader,那么这些消息很可能丢失了。如果我们允许消费者读取这些消息,可能就会破坏一致性。试想,一个消费者从当前 Leader(副本0) 读取并处理了 Message4,这个时候 Leader 挂掉了,选举了副本1为新的 Leader,这时候另一个消费者再去从新的 Leader 读取消息,发现这个消息其实并不存在,这就导致了数据不一致性问题。

当然,引入了 High Water Mark 机制,会导致 Broker 间的消息复制因为某些原因变慢,那么消息到达消费者的时间也会随之变长(因为我们会先等待消息复制完毕)。延迟时间可以通过参数 replica.lag.time.max.ms 参数配置,它指定了副本在复制消息时可被允许的最大延迟时间。

20、Kafka 缺点?
由于是批量发送,数据并非真正的实时;
•对于mqtt协议不支持;
•不支持物联网传感数据直接接入;
•仅支持统一分区内消息有序,无法实现全局消息有序;
•监控不完善,需要安装插件;
•依赖zookeeper进行元数据管理;

1 什么是kafka

Kafka是分布式发布-订阅消息系统,它最初是由LinkedIn公司开发的,之后成为Apache项⽬的⼀部分,Kafka是⼀个分布式,可划分的,冗余备份的持久性的⽇志服务,它主要⽤于处理流式数据。

2 为什么要使⽤ kafka,为什么要使⽤消息队列

缓冲和削峰:上游数据时有突发流量,下游可能扛不住,或者下游没有⾜够多的机器来保证冗余,kafka在中间可以起到⼀个缓冲的作⽤,把消息暂存在kafka中,下游服务就可以按照⾃⼰的节奏进⾏慢慢处理。

解耦和扩展性:项⽬开始的时候,并不能确定具体需求。消息队列可以作为⼀个接⼝层,解耦重要的业务流程。只需要遵守约定,针对数据编程即可获取扩展能⼒。

冗余:可以采⽤⼀对多的⽅式,⼀个⽣产者发布消息,可以被多个订阅topic的服务消费到,供多个毫⽆关联的业务使⽤。

健壮性:消息队列可以堆积请求,所以消费端业务即使短时间死掉,也不会影响主要业务的正常进⾏。

异步通信:很多时候,⽤户不想也不需要⽴即处理消息。消息队列提供了异步处理机制,允许⽤户把⼀个消息放⼊队列,但并不⽴即处理它。想向队列中放⼊多少消息就放多少,然后在需要的时候再去处理它们。

3.Kafka中的I SR、A R⼜代表什么?I SR的伸缩⼜指什么

ISR:In-Sync Replicas 副本同步队列

AR:Assigned Replicas 所有副本

ISR是由leader维护,follower从leader同步数据有⼀些延迟(包括延迟时间replica.lag.time.max.ms和延迟条数replica.lag.max.messages两个维度, 当前最新的版本0.10.x中只⽀持replica.lag.time.max.ms这个维度),任意⼀个超过阈值都会把follower剔除出ISR, 存⼊OSR(Outof-Sync Replicas)列表,新加⼊的follower也会先存放在OSR中。AR=ISR+OSR。

4.kaf ka中的b r oke r 是⼲什么的

broker 是消息的代理,Producers往Brokers⾥⾯的指定Topic中写消息,Consumers从Brokers⾥⾯拉取指定Topic的消息,然后进⾏业务处理,broker在中间起到⼀个代理保存消息的中转站。

5.kaf ka中的 zooke e p e r 起到什么作⽤,可以不⽤zooke e p e r么

zookeeper 是⼀个分布式的协调组件,早期版本的kafka⽤zk做meta信息存储,consumer的消费状态,group的管理以及 offset的值。考虑到zk本⾝的⼀些因素以及整个架构较⼤概率存在单点问题,新版本中逐渐弱化了zookeeper的作⽤。新的consumer使⽤了kafka内部的group coordination协议,也减少了对zookeeper的依赖,

但是broker依然依赖于ZK,zookeeper 在kafka中还⽤来选举controller 和 检测broker是否存活等等。

6.kaf ka f ollowe r如何与le ad e r同步数据

Kafka的复制机制既不是完全的同步复制,也不是单纯的异步复制。完全同步复制要求All Alive Follower都复制完,这条消息才会被认为commit,这种复制⽅式极⼤的影响了吞吐率。⽽异步复制⽅式下,Follower异步的从Leader复制数据,数据只要被Leader写⼊log就被认为已经commit,这种情况下,如果leader挂掉,会丢失数据,kafka使⽤ISR的⽅式很好的均衡了确保数据不丢失以及吞吐率。Follower可以批量的从Leader复制数据,⽽且Leader充分利⽤磁盘顺序读以及send file(zero copy)机制,这样极⼤的提⾼复制性能,内部批量写磁盘,⼤幅减少了Follower与Leader的消息量差。

7.什么情况下⼀个 b r oke r 会从 is r中踢出去

leader会维护⼀个与其基本保持同步的Replica列表,该列表称为ISR(in-sync Replica),每个Partition都会有⼀个ISR,⽽且是由leader动态维护 ,如果⼀个follower⽐⼀个leader落后太多,或者超过⼀定时间未发起数据复制请求,则leader将其重ISR中移除 。

8.kaf ka 为什么那么快

Cache Filesystem Cache PageCache缓存

顺序写 由于现代的操作系统提供了预读和写技术,磁盘的顺序写⼤多数情况下⽐随机写内存还要快。

Zero-copy 零拷技术减少拷贝次数

Batching of Messages 批量量处理。合并⼩的请求,然后以流的⽅式进⾏交互,直顶⽹络上限。

Pull 拉模式 使⽤拉模式进⾏消息的获取消费,与消费端处理能⼒相符。

9.kaf ka p r od uce r如何优化打⼊速度

增加线程

提⾼ batch.size

增加更多 producer 实例

增加 partition 数

设置 acks=-1 时,如果延迟增⼤:可以增⼤ num.replica.fetchers(follower 同步数据的线程数)来调解;

跨数据中⼼的传输:增加 socket 缓冲区设置以及 OS tcp 缓冲区设置。

10.kafka produce r 打数据,ack 为 0, 1, -1 的时候代表啥, 设置 -1 的时候,什么情况下,leader 会认为⼀条消息 commit了

1(默认) 数据发送到Kafka后,经过leader成功接收消息的的确认,就算是发送成功了。在这种情况下,如果leader宕机了,则会丢失数据。

0 ⽣产者将数据发送出去就不管了,不去等待任何返回。这种情况下数据传输效率最⾼,但是数据可靠性确是最低的。

-1 producer需要等待ISR中的所有follower都确认接收到数据后才算⼀次发送完成,可靠性最⾼。当ISR中所有Replica都向Leader发送ACK 时,leader才commit,这时候producer才能认为⼀个请求中的消息都commit了。

11.kafka uncle an 配置代表啥,会对 s p ar k s tr e am ing 消费有什么影响

unclean.leader.election.enable 为true的话,意味着⾮ISR集合的broker 也可以参与选举,这样有可能就会丢数据,spark streaming在消费过程中拿到的 end offset 会突然变⼩,导致 spark streaming job挂掉。如果unclean.leader.election.enable参数设置为true,就有可能发⽣数据丢失和数据不⼀致的情况,Kafka的可靠性就会降低;⽽如果unclean.leader.election.enable参数设置为false,Kafka的可⽤性就会降低。

12.如果le ad e r cr as h时,I SR为空怎么办

kafka在Broker端提供了⼀个配置参数:unclean.leader.election,这个参数有两个值:

true(默认):允许不同步副本成为leader,由于不同步副本的消息较为滞后,此时成为leader,可能会出现消息不⼀致的情况。

false:不允许不同步副本成为leader,此时如果发⽣ISR列表为空,会⼀直等待旧leader恢复,降低了可⽤性。

13.kafka的message格式是什么样的

⼀个Kafka的Message由⼀个固定长度的header和⼀个变长的消息体body组成

header部分由⼀个字节的magic(⽂件格式)和四个字节的CRC32(⽤于判断body消息体是否正常)构成。

当magic的值为1的时候,会在magic和crc32之间多⼀个字节的数据:attributes(保存⼀些相关属性,

⽐如是否压缩、压缩格式等等);如果magic的值为0,那么不存在attributes属性

body是由N个字节构成的⼀个消息体,包含了具体的key/value消息

14.kaf ka中cons um e r g r oup 是什么概念

同样是逻辑上的概念,是Kafka实现单播和⼴播两种消息模型的⼿段。同⼀个topic的数据,会⼴播给不同的group;同⼀个group中的worker,只有⼀个worker能拿到这个数据。换句话说,对于同⼀个topic,每个group都可以拿到同样的所有数据,但是数据进⼊group后只能被其中的⼀个worker消费。group内的worker可以使⽤多线程或多进程来实现,也可以将进程分散在多台机器上,worker的数量通常不超过partition的数量,且⼆者最好保持整数倍关系,因为Kafka在设计时假定了⼀个partition只能被⼀个worker消费(同⼀group内)。

15.K af ka中的消息是否会丢失和重复消费?

要确定Kafka的消息是否丢失或重复,从两个⽅⾯分析⼊⼿:消息发送和消息消费。

1、消息发送

Kafka消息发送有两种⽅式:同步(sync)和异步(async),默认是同步⽅式,可通过producer.type属性进⾏配置。Kafka通过配置request.required.acks属性来确认消息的⽣产:

0---表⽰不进⾏消息接收是否成功的确认;

1---表⽰当Leader接收成功时确认;

-1---表⽰Leader和Follower都接收成功时确认;

综上所述,有6种消息⽣产的情况,下⾯分情况来分析消息丢失的场景:

(1)acks=0,不和Kafka集群进⾏消息接收确认,则当⽹络异常、缓冲区满了等情况时,消息可能丢失;

(2)acks=1、同步模式下,只有Leader确认接收成功后但挂掉了,副本没有同步,数据可能丢失;

2、消息消费

Kafka消息消费有两个consumer接⼝,Low-level API和High-level API:

Low-level API:消费者⾃⼰维护offset等值,可以实现对Kafka的完全控制;

High-level API:封装了对parition和offset的管理,使⽤简单;

如果使⽤⾼级接⼝High-level API,可能存在⼀个问题就是当消息消费者从集群中把消息取出来、并提交了新的消息offset值后,还没来得及消费就挂掉了,那么下次再消费时之前没消费成功的消息就“诡异”的消失了;

解决办法:

针对消息丢失:同步模式下,确认机制设置为-1,即让消息写⼊Leader和Follower之后再确认消息发送成功;异步模式下,为防⽌缓冲区满,可以在配置⽂件设置不限制阻塞超时时间,当缓冲区满时让⽣产者⼀直处于阻塞状态;

针对消息重复:将消息的唯⼀标识保存到外部介质中,每次消费时判断是否处理过即可。

16.为什么K af ka不⽀持读写分离?

在 Kafka 中,⽣产者写⼊消息、消费者读取消息的操作都是与 leader 副本进⾏交互的,从 ⽽实现的是⼀种主写主读的⽣产消费模型。

Kafka 并不⽀持主写从读,因为主写从读有 2 个很明 显的缺点:

(1)数据⼀致性问题。数据从主节点转到从节点必然会有⼀个延时的时间窗⼝,这个时间 窗⼝会导致主从节点之间的数据不⼀致。某⼀时刻,在主节点和从节点中 A 数据的值都为 X, 之后将主节点中 A 的值修改为 Y,那么在这个变更通知到从节点之前,应⽤读取从节点中的 A 数据的值并不为最新的 Y,由此便产⽣了数据不⼀致的问题。

(2)延时问题。类似 Redis 这种组件,数据从写⼊主节点到同步⾄从节点中的过程需要经 历⽹络→主节点内存→⽹络→从节点内存这⼏个阶段,整个过程会耗费⼀定的时间。⽽在 Kafka 中,主从同步会⽐ Redis 更加耗时,它需要经历⽹络→主节点内存→主节点磁盘→⽹络→从节 点内存→从节点磁盘这⼏个阶段。对延时敏感的应⽤⽽⾔,主写从读的功能并不太适⽤。

17.K af ka中是怎么体现消息顺序性的?

kafka每个partition中的消息在写⼊时都是有序的,消费时,每个partition只能被每⼀个group中的⼀个消费者消费,保证了消费时也是有序的。

整个topic不保证有序。如果为了保证topic整个有序,那么将partition调整为1.

18.消费者提交消费位移时提交的是当前消费到的最新消息的of f s e t还是of f s e t+1?

offset+1

19.kaf ka如何实现延迟队列?

Kafka并没有使⽤JDK⾃带的Timer或者DelayQueue来实现延迟的功能,⽽是基于时间轮⾃定义了⼀个⽤于实现延迟功能的定时器(SystemTimer)。JDK的Timer和DelayQueue插⼊和删除操作的平均时间复杂度为O(nlog(n)),并不能满⾜Kafka的⾼性能要求,⽽基于时间轮可以将插⼊和删除操作的时间复杂度都降为O(1)。时间轮的应⽤并⾮Kafka独有,其应⽤场景还有很多,在Netty、Akka、Quartz、Zookeeper等组件中都存在时间轮的踪影。

底层使⽤数组实现,数组中的每个元素可以存放⼀个TimerTaskList对象。TimerTaskList是⼀个环形双向链表,在其中的链表项TimerTaskEntry中封装了真正的定时任务TimerTask.

Kafka中到底是怎么推进时间的呢?Kafka中的定时器借助了JDK中的DelayQueue来协助推进时间轮。具体做法是对于每个使⽤到的TimerTaskList都会加⼊到DelayQueue中。Kafka中的TimingWheel专门⽤来执⾏插⼊和删除TimerTaskEntry的操作,⽽DelayQueue专门负责时间推进的任务。再试想⼀下,DelayQueue中的第⼀个超时任务列表的expiration为200ms,第⼆个超时任务为840ms,这⾥获取DelayQueue的队头只需要O(1)的时间复杂度。如果采⽤每秒定时推进,那么获取到第⼀个超时的任务列表时执⾏的200次推进中有199次属

于“空推进”,⽽获取到第⼆个超时任务时有需要执⾏639次“空推进”,这样会⽆故空耗机器的性能资源,这⾥采⽤DelayQueue来辅助以少量空间换时间,从⽽做到了“精准推进”。Kafka中的定时器真可谓是“知⼈善⽤”,⽤TimingWheel做最擅长的任务添加和删除操作,⽽⽤DelayQueue做最擅长的时间推进⼯作,相辅相成。

1.Kafka的设计时什么样的呢?

Kafka将消息以topic为单位进行归纳

将向Kafka topic发布消息的程序成为producers.

将预订topics并消费消息的程序成为consumer.

Kafka以集群的方式运行,可以由一个或多个服务组成,每个服务叫做一个broker. producers通过网络将消息发送到Kafka集群,集群向消费者提供消息

2.数据传输的事物定义有哪三种?

数据传输的事务定义通常有以下三种级别:

(1)最多一次: 消息不会被重复发送,最多被传输一次,但也有可能一次不传输

(2)最少一次: 消息不会被漏发送,最少被传输一次,但也有可能被重复传输.

(3)精确的一次(Exactly once): 不会漏传输也不会重复传输,每个消息都传输被一次而且仅仅被传输一次,这是大家所期望的

3.Kafka判断一个节点是否还活着有那两个条件?

(1)节点必须可以维护和ZooKeeper的连接,Zookeeper通过心跳机制检查每个节点的连接

(2)如果节点是个follower,他必须能及时的同步leader的写操作,延时不能太久

4.producer是否直接将数据发送到broker的leader(主节点)?

producer直接将数据发送到broker的leader(主节点),不需要在多个节点进行分发,为了帮助producer做到这点,所有的Kafka节点都可以及时的告知:哪些节点是活动的,目标topic目标分区的leader在哪。这样producer就可以直接将消息发送到目的地了

5、Kafa consumer是否可以消费指定分区消息?

Kafa consumer消费消息时,向broker发出"fetch"请求去消费特定分区的消息,consumer 指定消息在日志中的偏移量(offset),就可以消费从这个位置开始的消息,customer拥有了offset的控制权,可以向后回滚去重新消费之前的消息,这是很有意义的

6、Kafka消息是采用Pull模式,还是Push模式?

Kafka最初考虑的问题是,customer应该从brokes拉取消息还是brokers将消息推送到consumer,也就是pull还push。在这方面,Kafka遵循了一种大部分消息系统共同的传统的设计:producer将消息推送到broker,consumer从broker拉取消息

一些消息系统比如Scribe和Apache Flume采用了push模式,将消息推送到下游的consumer。这样做有好处也有坏处:由broker决定消息推送的速率,对于不同消费速率的consumer就不太好处理了。消息系统都致力于让consumer以最大的速率最快速的消费消息,但不幸的是,push模式下,当broker推送的速率远大于consumer消费的速率时,consumer恐怕就要崩溃了。最终Kafka还是选取了传统的pull模式

Pull模式的另外一个好处是consumer可以自主决定是否批量的从broker拉取数据。Push 模式必须在不知道下游consumer消费能力和消费策略的情况下决定是立即推送每条消息还是缓存之后批量推送。如果为了避免consumer崩溃而采用较低的推送速率,将可能导致一次只推送较少的消息而造成浪费。Pull模式下,consumer就可以根据自己的消费能力去决

定这些策略

Pull有个缺点是,如果broker没有可供消费的消息,将导致consumer不断在循环中轮询,直到新消息到t达。为了避免这点,Kafka有个参数可以让consumer阻塞知道新消息到达(当然也可以阻塞知道消息的数量达到某个特定的量这样就可以批量发

7.Kafka存储在硬盘上的消息格式是什么?

消息由一个固定长度的头部和可变长度的字节数组组成。头部包含了一个版本号和CRC32校验码。

消息长度: 4 bytes (value: 1+4+n)

版本号: 1 byte

CRC校验码: 4 bytes

具体的消息: n bytes

8.Kafka高效文件存储设计特点:

(1).Kafka把topic中一个parition大文件分成多个小文件段,通过多个小文件段,就容易定期清除或删除已经消费完文件,减少磁盘占用。

(2).通过索引信息可以快速定位message和确定response的最大大小。

(3).通过index元数据全部映射到memory,可以避免segment file的IO磁盘操作。

(4).通过索引文件稀疏存储,可以大幅降低index文件元数据占用空间大小。

9.Kafka 与传统消息系统之间有三个关键区别

(1).Kafka 持久化日志,这些日志可以被重复读取和无限期保留

(2).Kafka 是一个分布式系统:它以集群的方式运行,可以灵活伸缩,在内部通过复制数据提升容错能力和高可用性

(3).Kafka 支持实时的流式处理

10.Kafka创建Topic时如何将分区放置到不同的Broker中

副本因子不能大于Broker 的个数;

第一个分区(编号为0)的第一个副本放置位置是随机从brokerList 选择的;

其他分区的第一个副本放置位置相对于第0个分区依次往后移。也就是如果我们有5个Broker,5个分区,假设第一个分区放在第四个Broker 上,那么第二个分区将会放在第五个Broker 上;第三个分区将会放在第一个Broker 上;第四个分区将会放在第二个Broker 上,依次类推;

剩余的副本相对于第一个副本放置位置其实是由nextReplicaShift 决定的,而这个数也是随机产生的

11.Kafka新建的分区会在哪个目录下创建

在启动Kafka 集群之前,我们需要配置好log.dirs 参数,其值是Kafka 数据的存放目录,这个参数可以配置多个目录,目录之间使用逗号分隔,通常这些目录是分布在不同的磁盘上用于提高读写性能。

当然我们也可以配置log.dir 参数,含义一样。只需要设置其中一个即可。

如果log.dirs 参数只配置了一个目录,那么分配到各个Broker 上的分区肯定只能在这个目录下创建文件夹用于存放数据。

但是如果log.dirs 参数配置了多个目录,那么Kafka 会在哪个文件夹中创建分区目录呢?答案是:Kafka 会在含有分区目录最少的文件夹中创建新的分区目录,分区目录名为Topic 名+分区ID。注意,是分区文件夹总数最少的目录,而不是磁盘使用量最少的目录!也就是说,如果你给log.dirs 参数新增了一个新的磁盘,新的分区目录肯定是先在这个新的磁盘上创建直到这个新的磁盘目录拥有的分区目录不是最少为止。

12.partition的数据如何保存到硬盘

topic中的多个partition以文件夹的形式保存到broker,每个分区序号从0递增,

且消息有序

Partition文件下有多个segment(xxx.index,xxx.log)

segment 文件里的大小和配置文件大小一致可以根据要求修改默认为1g

如果大小大于1g时,会滚动一个新的segment并且以上一个segment最后一条消息的偏移量命名

13.kafka的ack机制

request.required.acks有三个值0 1 -1

0:生产者不会等待broker的ack,这个延迟最低但是存储的保证最弱当server挂掉的时候就会丢数据

1:服务端会等待ack值leader副本确认接收到消息后发送ack但是如果leader挂掉后他不确保是否复制完成新leader也会导致数据丢失

-1:同样在1的基础上服务端会等所有的follower的副本受到数据后才会受到leader发出的ack,这样数据不会丢失

14.Kafka的消费者如何消费数据

消费者每次消费数据的时候,消费者都会记录消费的物理偏移量(offset)的位置

等到下次消费时,他会接着上次位置继续消费

15.消费者负载均衡策略

一个消费者组中的一个分片对应一个消费者成员,他能保证每个消费者成员都能访问,如果组中成员太多会有空闲的成员

16.数据有序

一个消费者组里它的内部是有序的

消费者组与消费者组之间是无序的

17.kafaka生产数据时数据的分组策略

生产者决定数据产生到集群的哪个partition中

每一条消息都是以(key,value)格式

Key是由生产者发送数据传入

所以生产者(key)决定了数据产生到集群的哪个partition

 

1.Kafka中的ISR(InSyncReplicate)、OSR(OutSyncReplicate)、AR(AllReplicate)代表什么?

ISR : 速率和leader相差低于10秒的follower的集合
OSR : 速率和leader相差大于10秒的follower
AR : 所有分区的follower
AR=ISR+OSR
2.Kafka中的HW、LEO、LSO、LW等分别代表什么

HW:High Watermark 高水位,取一个partition对应的ISR中最小的LEO作为HW,consumer最多只能消费到HW所在的位置上一条信息。
LEO:LogEndOffset 当前日志文件中下一条待写信息的offset
HW/LEO这两个都是指最后一条的下一条的位置而不是指最后一条的位置。
LSO:Last Stable Offset 对未完成的事务而言,LSO 的值等于事务中第一条消息的位置(firstUnstableOffset),对已完成的事务而言,它的值同 HW 相同
LW:Low Watermark 低水位, 代表 AR 集合中最小的 logStartOffset 值
3.Kafka中是怎么体现消息顺序性的?
每个分区内,每条消息都有offset,所以只能在同一分区内有序,但不同的分区无法做到消息顺序性;如果实在想顺序消费的话,可以要将消费组只弄一个消费者
4.“消费组中的消费者个数如果超过topic的分区,那么就会有消费者消费不到数据”这句话是否正确?
对的,超过分区数的消费者就不会再接收数据
5.有哪些情形会造成重复消费?或丢失信息?

先处理后提交offset,会造成重读消费
先提交offset后处理,会造成数据丢失
6.Kafka 分区的目的?
对于kafka集群来说,分区可以做到负载均衡,对于消费者来说,可以提高并发度,提高读取效率。
7.Kafka 的高可靠性是怎么实现的?

7.1 消息生成端可靠性保证(设置ack参数):
当ack=0时,producer不等待broker的ack,不管数据有没有写入成功,都不再重复发该数据
​ 当ack=1时,broker会等到leader写完数据后,就会向producer发送ack,但不会等follower同步数据,如果这时leader挂掉,producer会对新的leader发送新的数据,在old的leader中不同步的数据就会丢失
当ack=-1或者all时,broker会等到leader和isr中的所有follower都同步完数据,再向producer发送ack,有可能造成数据重复
7.2 消息消费端可靠性保证(设置ack参数)

9.topic的分区数可不可以减少?如果可以怎么减少?如果不可以,那又是为什么?

不可以,先有的分区数据难以处理
10.简述Kafka的日志目录结构?
每一个分区对应一个文件夹,命名为topic-0,topic-1,每个文件夹内有.index和.log文件
11.如何解决消费者速率低的问题?
增加分区数和消费者数
Kafka的那些设计让它有如此高的性能??
kafka是分布式的消息队列,对log文件进行了segment,并对segment建立了索引,(对于单节点)使用了顺序读写,速度可以达到600M/s,引用了zero拷贝,在os系统就完成了读写操作
13.kafka启动不起来的原因?
在关闭kafka时,先关了zookeeper,就会导致kafka下一次启动时,会报节点已存在的错误
只要把zookeeper中的zkdata/version-2的文件夹删除即可
14.聊一聊Kafka Controller的作用?
负责kafka集群的上下线工作,所有topic的副本分区分配和选举leader工作
15. Kafka中有那些地方需要选举?这些地方的选举策略又有哪些?
在ISR中需要选择,选择策略为先到先得
16.失效副本是指什么?有那些应对措施?

失效副本为速率比leader相差大于10秒的follower
将失效的follower先提出ISR
等速率接近leader10秒内,再加进ISR
17.Kafka消息是采用Pull模式,还是Push模式?

在producer阶段,是向broker用Push模式
在consumer阶段,是向broker用Pull模式
*在Pull模式下,consumer可以根据自身速率选择如何拉取数据,避免了低速率的consumer发生崩溃的问题 但缺点是,consumer要时不时的去询问broker是否有新数据,容易发生死循环,内存溢出。
Kafka创建Topic时如何将分区放置到不同的Broker中?
首先副本数不能超过broker数
第一分区是随机从Broker中选择一个,然后其他分区相对于0号分区依次向后移
第一个分区是从nextReplicaShift决定的,而这个数也是随机产生的
19.Kafka中的事务是怎么实现的?

producer事务是为了解决kafka跨分区跨会话问题,kafka不能跨分区跨会话的主要问题是每次启动的producer的PID都是系统随机给的
所以为了解决这个问题,我们就要手动给producer一个全局唯一的id,也就是transaction id 简称TID
我们将TID和PID进行绑定,在producer带着TID和PID第一次向broker注册时,broker就会记录TID,并生成一个新的组件transaction_state用来保存TID的事务状态信息。当producer重启后,就会带着TID和新的PID向broker发起请求,当发现TID一致时,producer就会获取之前的PID,将覆盖掉新的PID,并获取上一次的事务状态信息,从而继续上次工作
consumer事务相对于producer事务就弱一点,需要先确保consumer的消费和提交位置为一致且具有事务功能,才能保证数据的完整,不然会造成数据的丢失或重复

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

offset + 1

posted @ 2023-07-02 19:56  剑阁丶神灯  阅读(43)  评论(0编辑  收藏  举报