10 Apache Kafka补充
Posted IT BOY
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10 Apache Kafka补充相关的知识,希望对你有一定的参考价值。
APACHE KAFKA补充
目录
(3) pull和push,Kafka支持哪种类型,为什么这么设计?
(5) Kafka中的ISR、AR又代表什么?ISR的伸缩又指什么
(6) kafka中的 zookeeper 起到什么作用,可以不用zookeeper么
(7) kafka follower如何与leader同步数据
(10) kafka producer 消息确认机制是什么?
(11) kafka unclean 配置代表啥,会对 spark streaming 消费有什么影响
(14) kafka中consumer group 是什么概念
(18) 消费者提交消费位移时提交的是当前消费到的最新消息的offset还是offset+1?
(23) Kafka有哪些索引类型?消息怎么通过索引进行检索?
(24) Kafka的稀疏索引间隔是由什么决定的?为什么不用B+树?
(25) Kafka的日志文件过大时,可以通过哪些方式释放磁盘空间?
PT1 KAFKA面试
(1) 什么是kafka?
Kafka是分布式发布-订阅消息系统,它最初是由LinkedIn公司开发的,之后成为Apache项目的一部分,Kafka是一个分布式,可划分的,冗余备份的持久性的日志服务,它主要用于处理流式数据。
(2) 为什么要使用 kafka
-
缓冲和削峰:上游数据时有突发流量,下游可能扛不住,或者下游没有足够多的机器来保证冗余,kafka在中间可以起到一个缓冲的作用,把消息暂存在kafka中,下游服务就可以按照自己的节奏进行慢慢处理。
-
解耦和扩展性:项目开始的时候,并不能确定具体需求。消息队列可以作为一个接口层,解耦重要的业务流程。只需要遵守约定,针对数据编程即可获取扩展能力。
-
消息广播:可以采用一对多的方式,一个生产者发布消息,可以被多个订阅topic的服务消费到,供多个毫无关联的业务使用。
-
健壮性:消息队列可以堆积请求,所以消费端业务即使短时间死掉,也不会影响主要业务的正常进行。
-
异步通信:很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。
(3) pull和push,Kafka支持哪种类型,为什么这么设计?
和RabbitMQ不同的是,Kafka只支持pull模式。原因是为了防止push模式下,消息生产速度和消费速度不匹配时,大量的消息堆积在Consumer端导致的服务不可用。
(4) kafka 为什么那么快
-
Cache Filesystem Cache PageCache缓存
-
顺序写 由于现代的操作系统提供了预读和写技术,磁盘的顺序写大多数情况下比随机写内存还要快。
-
Zero-copy 零拷技术减少拷贝次数
-
Batching of Messages 批量处理。合并小的请求,然后以流的方式进行交互,直顶网络上限。
-
Pull 拉模式 使用拉模式进行消息的获取消费,与消费端处理能力相符。
(5) Kafka中的ISR、AR又代表什么?ISR的伸缩又指什么
AR:Assigned Replicas 所有副本
ISR:In-Sync 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。
(6) kafka中的 zookeeper 起到什么作用,可以不用zookeeper么
zookeeper 是一个分布式的协调组件,早期版本的kafka用zk做meta信息存储,consumer的消费状态,group的管理以及 offset的值。考虑到zk本身的一些因素以及整个架构较大概率存在单点问题,新版本中逐渐弱化了zookeeper的作用。新的consumer使用了kafka内部的group coordination协议,也减少了对zookeeper的依赖,
但是broker依然依赖于ZK,zookeeper 在kafka中还用来选举controller 和 检测broker是否存活等等。
(7) kafka follower如何与leader同步数据
Kafka的复制机制既不是完全的同步复制,也不是单纯的异步复制。完全同步复制要求All Alive Follower都复制完,这条消息才会被认为commit,这种复制方式极大的影响了吞吐率。而异步复制方式下,Follower异步的从Leader复制数据,数据只要被Leader写入log就被认为已经commit,这种情况下,如果leader挂掉,会丢失数据,kafka使用ISR的方式很好的均衡了确保数据不丢失以及吞吐率。Follower可以批量的从Leader复制数据,而且Leader充分利用磁盘顺序读以及send file(zero copy)机制,这样极大的提高复制性能,内部批量写磁盘,大幅减少了Follower与Leader的消息量差。
(8) 什么情况下一个 broker 会从 isr中踢出去
leader会维护一个与其基本保持同步的Replica列表,该列表称为ISR(in-sync Replica),每个Partition都会有一个ISR,而且是由leader动态维护 ,如果一个follower比一个leader落后太多,或者超过一定时间(一般30秒)未发起数据复制请求,则leader将其重ISR中移除 。
(9) kafka producer如何优化消息发送速度
-
增加线程
-
提高 batch.size
-
增加更多 producer 实例
-
增加 partition 数
-
设置 acks=-1 时,如果延迟增大:可以增大 num.replica.fetchers(follower 同步数据的线程数)来调解;
-
跨数据中心的传输:增加 socket 缓冲区设置以及 OS tcp 缓冲区设置。
(10) kafka producer 消息确认机制是什么?
-
1(默认) 数据发送到Kafka后,经过leader成功接收消息的的确认,就算是发送成功了。在这种情况下,如果leader宕机了,则会丢失数据。
-
0 生产者将数据发送出去就不管了,不去等待任何返回。这种情况下数据传输效率最高,但是数据可靠性确是最低的。
-
-1 producer需要等待ISR中的所有follower都确认接收到数据后才算一次发送完成,可靠性最高。当ISR中所有Replica都向Leader发送ACK时,leader才commit,这时候producer才能认为一个请求中的消息都commit了。
(11) kafka unclean 配置代表啥,会对 spark streaming 消费有什么影响
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) 如果leader crash时,ISR为空怎么办
kafka在Broker端提供了一个配置参数:unclean.leader.election,这个参数有两个值:
-
true(默认):允许不同步副本成为leader,由于不同步副本的消息较为滞后,此时成为leader,可能会出现消息不一致的情况。
-
false:不允许不同步副本成为leader,此时如果发生ISR列表为空,会一直等待旧leader恢复,降低了可用性。
(14) kafka中consumer group 是什么概念
同样是逻辑上的概念,是Kafka实现单播和广播两种消息模型的手段。同一个topic的数据,会广播给不同的group;同一个group中的worker,只有一个worker能拿到这个数据。
换句话说,对于同一个topic,每个group都可以拿到同样的所有数据,但是数据进入group后只能被其中的一个worker消费。group内的worker可以使用多线程或多进程来实现,也可以将进程分散在多台机器上,worker的数量通常不超过partition的数量,且二者最好保持整数倍关系,因为Kafka在设计时假定了一个partition只能被一个worker消费(同一group内)。
(15) 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之后再确认消息发送成功;异步模式下,为防止缓冲区满,可以在配置文件设置不限制阻塞超时时间,当缓冲区满时让生产者一直处于阻塞状态;、
针对消息重复:将消息的唯一标识保存到外部介质中,每次消费时判断是否处理过即可。
(16) 为什么Kafka不支持读写分离?
在 Kafka 中,生产者写入消息、消费者读取消息的操作都是与 leader 副本进行交互的,从而实现的是一种主写主读的生产消费模型。
Kafka 并不支持主写从读,因为主写从读有 2 个很明显的缺点:
-
1、数据一致性问题。数据从主节点转到从节点必然会有一个延时的时间窗口,这个时间 窗口会导致主从节点之间的数据不一致。某一时刻,在主节点和从节点中 A 数据的值都为 X, 之后将主节点中 A 的值修改为 Y,那么在这个变更通知到从节点之前,应用读取从节点中的 A 数据的值并不为最新的 Y,由此便产生了数据不一致的问题。
-
2、延时问题。类似 Redis 这种组件,数据从写入主节点到同步至从节点中的过程需要经 历网络→主节点内存→网络→从节点内存这几个阶段,整个过程会耗费一定的时间。而在 Kafka 中,主从同步会比 Redis 更加耗时,它需要经历网络→主节点内存→主节点磁盘→网络→从节 点内存→从节点磁盘这几个阶段。对延时敏感的应用而言,主写从读的功能并不太适用。
(17) Kafka中是怎么体现消息顺序性的?
kafka每个partition中的消息在写入时都是有序的,消费时,每个partition只能被每一个group中的一个消费者消费,保证了消费时也是有序的。
整个topic不保证有序。如果为了保证topic整个有序,那么将partition调整为1。
(18) 消费者提交消费位移时提交的是当前消费到的最新消息的offset还是offset+1?
offset+1
(19) 分区Partition的作用是什么?
当Topic压力比较大的时候,会有和单体应用同样的问题:
-
在高并发时性能下降非常快。所有客户端都要连到同一个Topic进行消息收发,必然会给Topic带来很大压力,性能会大大下降。
-
很难扩展。如果Topic处理能力或者存储能力不足,需要扩展时,只能垂直升级硬件,无法横向扩展。
Kafka通过Partition(分区)来解决这个问题,一个Topic可以被划分成多个分区,每个分区可以对外单独提供消息服务能力,这也是分片思想的落地。Partition类似于mysql的分库分表,为了达到横向扩展和负载均衡的目的。
一个Topic的不同Partition可以分布在同一个Broker,也可以通过搭建Broker集群部署在不同Broker(横向扩展)。
同一批消息在同一个Partition中能够保证顺序性,Kafka中的消息被消费后不会删除,通过Offset来记录消费位置,消息是被顺序追加到Partition中。
每个Topic在创建时默认至少有一个分区。
(20) 分区数和副本数是怎么设置的?
./kafka-topics.sh --create --zookeeper ip:2181 --replication-factor 1 --partitions 1 --topic mypartition
partitions就是指定分区数,replication-factor是指定副本数。
(21) 生产者发送消息如何选择分区?
1、显示指定partition;
2、自定义分区器,指定分区算法,根据发送信息计算分区;
3、使用Kafka默认分区器,基于对key的hash,然后对partition数区域获取位置;
4、使用Kafka轮训分区器,基于一个自增变量,然后对partition数区域获取位置,达到一种轮训的效果;
(22) Kafka消息的主要物理存储文件有哪些?
Kafka以Topic的partition为单位,通过日志文件的形式存储持久化数据。为了防止日志文件过大引起的效率问题,Kafka对文件进行分段,称为Segment。
Segment数据文件分为3个,.log、.index、*.timeindex,这三个文件是成套出现的。
除了Segment的3个数据文件外,leader-epoch-checkpoint文件用于记录每一任Leader上任时开始写入消息的offset。
(23) Kafka有哪些索引类型?消息怎么通过索引进行检索?
Kafka索引分为两种:*.index为根据偏移量记录的索引,*.timeindex为根据时间戳记录的索引。
*.index为稀疏索引,并不是每条消息都有索引记录,索引名称包含了当前索引文件开始的offset。在检索时根据offset先找到文件,然后再文件中找到稀疏索引的区间(二分法),在轮训区间内的消息获取数据。
*.timeindex是记录了时间戳和Offset对应关系,根据时间戳可以找到对应的Offset。
(24) Kafka的稀疏索引间隔是由什么决定的?为什么不用B+树?
稀疏索引间隔是由消息的大小控制的,默认是4KB,由参数log.index.interval.bytes控制。只要写入消息超过4KB,偏移量索引和时间索引都会插入新纪录。
(25) Kafka的日志文件过大时,可以通过哪些方式释放磁盘空间?
Kafka支持两种数据清理策略:直接删除或者压缩文件。
Kafka有负责删除文件定时任务,默认5分钟运行一次。通过参数配置可以删除/压缩的时间段。
(26) Kafka副本Leader是怎么选举的?
首先Broker负责竞选Controller,看谁能够在ZK上先创建/controller节点。
Controller选举出来后负责副本的选举,默认的选举策略非常简单,序号最小且在ISR中成为Leader。如果ISR为空,则要看参数书否允许在OSR中竞选,如果允许则从OSR中选Leader,可能会存在数据丢失。如果不予许从OSR竞选,则等待Leader恢复。
(27) Kafka副本的主从同步机制是什么?
-
Follower节点向Leader节点发送一个fetch请求,Leader根据当前Follower的LEO发送需要同步的数据,然后更新当前Follower的LEO。
-
Follower接收数据,完成消息写入,并更新自身LEO。
-
Leader更新HW(维护的ISR中最小LEO)。
(28) Kafka的Offset是怎么维护的?
1、Offset存储
早起Kafka将offset维护在zk中,但是读写频率高,性能损耗太大。后来是将它维护在一个特殊的Topic中,名为__consumer_offsets,默认有50个分区,每个默认默认1个replica。
__consumer_offsets主要负责存储两种对象:
-
GroupMetadata:保存了消费者组中各个消费者信息(每个消费者都有编号)。
-
OffsetAndMetadata:保存了消费者组和各个partition的Offset数据
2、Offset更新
Consumer消费之后,通过自动/手动发送消费确认给Broker后,Offset会被更新。
PT2 参考资料
在整理Kafka学习笔记过程中,参考了以下大佬的资料。
kafka源码解析之一kafka诞生的背景_wl044090432的博客-CSDN博客_kafka源码解析
kafka-producer参数详解_鸭鸭的博客-CSDN博客_kafkaproducer参数
以上是关于10 Apache Kafka补充的主要内容,如果未能解决你的问题,请参考以下文章