kafka学习26问笔记

1. Kafka 是什么?

Kafka 是⼀种⾼吞吐量、分布式、基于发布 / 订阅的消息系统,最初由 LinkedIn 公司开
发,使⽤ Scala 语⾔编写,⽬前是 Apache 的开源项⽬。 broker Kafka 服务器,负责消息
存储和转发 topic :消息类别, Kafka 按照 topic 来分类消息 partition topic 的分区,⼀
topic 可以包含多个 partition topic 消息保存在各个 partition offffset :消息在⽇志
中的位置,可以理解是消息在 partition 上的偏移量,也是代表该消息的唯⼀序号
Producer :消息⽣产者 Consumer :消息消费者 Consumer Group :消费者分组,每个
Consumer 必须属于⼀个 groupZookeeper :保存着集群 broker topic partition
meta 数据;另外,还负责 broker 故障发现, partition leader 选举,负载均衡等功能

 

2. Kafka 的设计时什么样的呢
Kafka 将消息以 topic 为单位进⾏归纳 将向 Kafka topic 发布消息的程序成为 producers.
将预订 topics 并消费消息的程序成为 consumer. Kafka 以集群的⽅式运⾏,可以由⼀个或 多个服务组成,每个服务叫做⼀个 broker. producers 通过⽹络将消息发送到 Kafka 集群,
集群向消费者提供消息。
3. 为什么要使⽤ kafka ,为什么要使⽤消息队列 ?
缓冲和削峰 :上游数据时有突发流量,下游可能扛不住,或者下游没有⾜够多的机器来保
证冗余, kafka 在中间可以起到⼀个缓冲的作⽤,把消息暂存在 kafka 中,下游服务就可以
按照⾃⼰的节奏进⾏慢慢处理。
解耦和扩展性 :项⽬开始的时候,并不能确定具体需求。消息队列可以作为⼀个接⼝层,
解耦重要的业务流程。只需要遵守约定,针对数据编程即可获取扩展能⼒。 冗余 :可以采
⽤⼀对多的⽅式,⼀个⽣产者发布消息,可以被多个订阅 topic 的服务消费到,供多个毫⽆
关联的业务使⽤。 健壮性 :消息队列可以堆积请求,所以消费端业务即使短时间死掉,也
不会影响主要业务的正常进⾏。 异步通信 :很多时候,⽤户不想也不需要⽴即处理消息。
消息队列提供了异步处理机制,允许⽤户把⼀个消息放⼊队列,但并不⽴即处理它。想向
队列中放⼊多少消息就放多少,然后在需要的时候再去处理它们。
4. 数据传输的事物定义有哪三种?
数据传输的事务定义通常有以下三种级别:( 1 )最多⼀次 : 消息不会被重复发送,最多
被传输⼀次,但也有可能⼀次不传输 ( 2 )最少⼀次 : 消息不会被漏发送,最少被传输⼀
次,但也有可能被重复传输 . 3 )精确的⼀次( Exactly once : 不会漏传输也不会重复
传输 , 每个消息都传输被⼀次⽽且仅仅被传输⼀次,这是⼤家所期望的
5. Kafka 判断⼀个节点是否还活着有那两个条件?
1 )节点必须可以维护和 ZooKeeper 的连接, Zookeeper 通过⼼跳机制检查每个节点
的连接 ( 2 )如果节点是个 follower, 他必须能及时的同步 leader 的写操作,延时不能太久
6. Kafka 中的 ISR AR ⼜代表什么? ISR 的伸缩⼜指什么 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
7. Kafka 中的 broker 是⼲什么的
broker 是消息的代理, Producers Brokers ⾥⾯的指定 Topic 中写消息, Consumers
Brokers ⾥⾯拉取指定 Topic 的消息,然后进⾏业务处理, broker 在中间起到⼀个代理保存
消息的中转站。
8. producer 是否直接将数据发送到 broker leader( 主节点 )
producer 直接将数据发送到 broker leader( 主节点 ) ,不需要在多个节点进⾏分发,为
了帮助 producer 做到这点,所有的 Kafka 节点都可以及时的告知 : 哪些节点是活动的,⽬
topic ⽬标分区的 leader 在哪。这样 producer 就可以直接将消息发送到⽬的地了
9. 什么情况下⼀个 broker 会从 isr 中踢出去
leader 会维护⼀个与其基本保持同步的 Replica 列表,该列表称为 ISR(in-sync Replica) ,每个
Partition 都会有⼀个 ISR ,⽽且是由 leader 动态维护 ,如果⼀个 follower ⽐⼀个 leader
后太多,或者超过⼀定时间未发起数据复制请求,则 leader 将其重 ISR 中移除 。
10. Kafa consumer 是否可以消费指定分区消息?
Kafka consumer 消费消息时,向 broker 发出 "fetch" 请求去消费特定分区的消息,
consumer 指定消息在⽇志中的偏移量( offset ),就可以消费从这个位置开始的消息, customer 拥有了 offset 的控制权,可以向后回滚去重新消费之前的消息,这是很有意义
11. 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 阻塞知道新消息到
达(当然也可以阻塞知道消息的数量达到某个特定的量这样就可以批量发)
12. Kafka 存储在硬盘上的消息格式是什么?
消息由⼀个固定⻓度的头部和可变⻓度的字节数组组成。头部包含了⼀个版本号和 CRC32
校验码。
1. 消息⻓度 : 4 bytes (value: 1+4+n) 2. 版本号 : 1 byte 3CRC
3. 校验码 : 4 bytes
4. 具体的消息 : n bytes
13. Kafka ⾼效⽂件存储设计特点:
(1).Kafka topic 中⼀个 parition ⼤⽂件分成多个⼩⽂件段,通过多个⼩⽂件段,就容易
定期清除或删除已经消费完⽂件,减少磁盘占⽤。
(2). 通过索引信息可以快速定位 message 和确定 response 的最⼤⼤⼩。
(3). 通过 index 元数据全部映射到 memory ,可以避免 segment file IO 磁盘操作。
(4). 通过索引⽂件稀疏存储,可以⼤幅降低 index ⽂件元数据占⽤空间⼤⼩。
14. Kafka 与传统消息系统之间有三个关键区别
(1).Kafka 持久化⽇志,这些⽇志可以被重复读取和⽆限期保留 (2).Kafka 是⼀个分布式系
统:它以集群的⽅式运⾏,可以灵活伸缩,在内部通过复制数据提升容错能⼒和⾼可⽤性
(3).Kafka ⽀持实时的流式处理
15. Kafka 创建 Topic 时如何将分区放置到不同的 Broker
(1) . 副本因⼦不能⼤于 Broker 的个数; (2) . 第⼀个分区(编号为 0 )的第⼀个副本放置位
置是随机从 brokerList 选择的; (3) . 其他分区的第⼀个副本放置位置相对于第 0 个分区依
次往后移。也就是如果我们有 5 Broker 5 个分区,假设第⼀个分区放在第四个
Broker 上,那么第⼆个分区将会放在第五个 Broker 上;第三个分区将会放在第⼀个
Broker 上;第四个分区将会放在第⼆个 Broker 上,依次类推; (4) . 剩余的副本相对于第⼀
个副本放置位置其实是由 nextReplicaShift 决定的,⽽这个数也是随机产⽣的。
16. Kafka 新建的分区会在哪个⽬录下创建 在启动 Kafka 集群之前,我们需要配置好 log.dirs 参数,其值是 Kafka 数据的存放⽬录,
这个参数可以配置多个⽬录,⽬录之间使⽤逗号分隔,通常这些⽬录是分布在不同的磁盘
上⽤于提⾼读写性能。当然我们也可以配置 log.dir 参数,含义⼀样。只需要设置其中⼀
个即可。如果 log.dirs 参数只配置了⼀个⽬录,那么分配到各个 Broker 上的分区肯定只
能在这个⽬录下创建⽂件夹⽤于存放数据。但是如果 log.dirs 参数配置了多个⽬录,那么
Kafka 会在哪个⽂件夹中创建分区⽬录呢?答案是: Kafka 会在含有分区⽬录最少的⽂件夹
中创建新的分区⽬录,分区⽬录名为 Topic + 分区 ID 。注意,是分区⽂件夹总数最少的
⽬录,⽽不是磁盘使⽤量最少的⽬录!也就是说,如果你给 log.dirs 参数新增了⼀个新的
磁盘,新的分区⽬录肯定是先在这个新的磁盘上创建直到这个新的磁盘⽬录拥有的分区⽬
录不是最少为⽌。
17. partition 的数据如何保存到硬盘
topic 中的多个 partition 以⽂件夹的形式保存到 broker ,每个分区序号从 0 递增,且消
息有序 Partition ⽂件下有多个 segment xxx.index xxx.log segment ⽂件⾥的 ⼤⼩
和配置⽂件⼤⼩⼀致可以根据要求修改 默认为 1g 如果⼤⼩⼤于 1g 时,会滚动⼀个新的
segment 并且以上⼀个 segment 最后⼀条消息的偏移量命名
18. 讲讲 kafka 维护消费状态跟踪的⽅法
⼤部分消息系统在 broker 端的维护消息被消费的记录:⼀个消息被分发到 consumer
broker 就⻢上进⾏标记或者等待 customer 的通知后进⾏标记。这样也可以在消息在消费
后⽴⻢就删除以减少空间占⽤。但是这样会不会有什么问题呢?如果⼀条消息发送出去之
后就⽴即被标记为消费过的, ⼀旦 consumer 处理消息时失败了(⽐如程序崩溃)消息就
丢失了。为了解决这个问题, 很多消息系统提供了另外⼀个个功能:当消息被发送出去之
后仅仅被标记为已发送状态,当接到 consumer 已经消费成功的通知后才标记为已被消费 的状态。这虽然解决了消息丢失的问题,但产⽣了新问题,⾸先如果 consumer 处理消息
成功了但是向 broker 发送响应时失败了,这条消息将被消费两次。第⼆个问题时, broker
必须维护每条消息的状态,并且每次都要先锁住消息然后更改状态然后释放锁。这样麻烦
⼜来了,且不说要维护⼤量的状态数据,⽐如如果消息发送出去但没有收到消费成功的通
知,这条消息将⼀直处于被锁定的状态, Kafka 采⽤了不同的策略。 Topic 被分成了若⼲分
区,每个分区在同⼀时间只被⼀个 consumer 消费。这意味着每个分区被消费的消息在⽇
志中的位置仅仅是⼀个简单的整数: offffset 。这样就很容易标记每个分区消费状态就很容易
了,仅仅需要⼀个整数⽽已。这样消费状态的跟踪就很简单了。这带来了另外⼀个好处:
consumer 可以把 offffset 调成⼀个较⽼的值,去重新消费⽼的消息。这对传统的消息系统
来说看起来有些不可思议,但确实是⾮常有⽤的,谁规定了⼀条消息只能被消费⼀次呢?
19. Kafka ack 机制
request.required.acks 有三个值 0 1 -1 0: ⽣产者不会等待 broker ack ,这个延迟最低但
是存储的保证最弱当 server 挂掉的时候就会丢数据 1 :服务端会等待 ack leader 副本
确认接收到消息后发送 ack 但是如果 leader 挂掉后他不确保是否复制完成新 leader 也会
导致数据丢失 -1 :同样在 1 的基础上 服务端会等所有的 follower 的副本受到数据后才
会受到 leader 发出的 ack ,这样数据不会丢失
20. Kafka 的消费者如何消费数据
消费者每次消费数据的时候,消费者都会记录消费的物理偏移量( offset )的位置等到下
次消费时,他会接着上次位置继续消费
21. 消费者负载均衡策略
⼀个消费者组中的⼀个分⽚对应⼀个消费者成员,他能保证每个消费者成员都能访问,如
果组中成员太多会有空闲的成员
22. 数据有序
⼀个消费者组⾥它的内部是有序的 消费者组与消费者组之间是⽆序的
23. Kafka ⽣产数据时数据的分组策略
⽣产者决定数据产⽣到集群的哪个 partition 中 每⼀条消息都是以( key value )格式
Key 是由⽣产者发送数据传⼊ 所以⽣产者( key )决定了数据产⽣到集群的哪个 partition
24. Kafka 中的消息是否会丢失和重复消费?
要确定 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 之后再确认消息发送成
功;异步模式下,为防⽌缓冲区满,可以在配置⽂件设置不限制阻塞超时时间,当缓冲区
满时让⽣产者⼀直处于阻塞状态;针对消息重复:将消息的唯⼀标识保存到外部介质中,
每次消费时判断是否处理过即可。
25. Kafka 中是怎么体现消息顺序性的?
kafka 每个 partition 中的消息在写⼊时都是有序的,消费时,每个 partition 只能被每⼀个
group 中的⼀个消费者消费,保证了消费时也是有序的。整个 topic 不保证有序。如果为了
保证 topic 整个有序,那么将 partition 调整为 1.
26. kafka 如何实现延迟队列?
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 做最擅⻓的时间推进⼯作,相辅相成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值