面试宝典--Kafka篇

1、什么是Kafka?有什么作用?

 kafka很像是一个消息队列或者企业级消息分发系统。当然它不同于一般的消息队列系统,他的并发处理能力很强大,同时,通过分布式架构可以很灵活的增加处理能力。

2、Kafka的基本架构图

在这里插入图片描述

2.1 Broker

kafka集群包含一个或多个服务器,每个服务器被称为Broker,broker端不维护数据的消费状态,提升了性能。直接使用磁盘进行存储,线性读写,速度快:避免了数据在JVM内存和系统内存之间的复制,减少了性能的消耗,比如创建对象和垃圾回收。

2.2 Producer

负责发布消息到kafka集群的某个topic中的某个partition下的leaders中;

2.3 Consumer

消息消费者,向kafka broker读取消息的客户端,consumer从broker拉取pull数据并进行处理。

2.4 Topic

每条发布到kafka集群的消息都有一个类别,这个类别被称为Topic。(物理上不同topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上,但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处)

2.5 partition

partition是物理上的概念,每个Topic包含一个或多个Partition.

2.6 Consumer Group

定义:即消费者组是kafka提供的可扩展且具有容错性的消费者机制。
原理:在kafka中,消费者组是一个由多个消费者实例构成的组。多个实例共同订阅若干个主题,实现共同消费。同一个组下的每个实例都配置有相同的组ID,被分配订阅不同的分区。当某个实例挂掉的时候,其他实例会自动承担起它负责消费的分区。

2.7 Topic & Partition

Topic在逻辑上可以被认为是一个queue,每个消费都必须指定它的Topic,可以简单理解为必须指明把这条消息放进那个queue里。为了使得kafka的吞吐率可以线性提高,物理上把topic分成一个或多个Partition,每个Partition在物理上对应一个文件夹,该文件夹下存储这个Partition的所有消息和索引文件。

2.8 Zookeeper

目前,kafka适用zookeeper存放集群元数据、成员管理、Controller选举,以及其他一些管理类任务。之后kafka的更高版本不再完全依赖于Zookeeper。
存放元数据:是指主题分区的所有数据都保存在Zookeeper中;
成员管理:是指Broker节点的注册、注销以及属性变更等等;
Controller选举:是指选举集群Controller;而其他管理类任务指主题删除、参数配置等。

3、适用场景

3.1 消息处理

对于一些常规的消息系统,kafka是个不错的选择;partitions/replication和容错,可以使kafka具有良好的扩展性和性能优势,不过到目前为止,我们应该很清楚认识到;kafka只能适用作为“常规”的消息系统,在一定程度上,尚未确保消息的发送与接收绝对可靠(比如消息重发,消息发送丢失等)

3.2 网站活性跟踪

kafka可以作为“网站活性跟踪”的最佳工具;可以将网页/用户操作信息发送到kafka中,并实时监控,或者离线统计分析等。

3.3 日志收集中心

kafka的特性决定它非常适合作为“日志收集中心”,application可以将操作日志“批量”“异步”的发送到kafka集群中,而不是保存在本地或者DB中;kafka可以批量提交消息/压缩消息等,这对producer端而言,几乎感觉不到性能的开支,此时consumer端可以使hadoop等其他系统优化的存储和分析系统。

4、解释下kafka中位移offset的作用

kafka中,每个主题分区下的每条消息都被赋予了一个唯一的ID数值,用于标识它在分区中的为止。这个ID数值,就被称为位移,或者叫偏移量。一旦消息被写入到分区日志,它的位移值不能被修改。

5、阐述下kafka中的领导者副本(Leader Replica)和追随者副本 (Follower Replica)的区别

kafka副本当前分为领导者副本和追随者副本。只有leader副本才能对外提供写服务,相应Clients端的请求。Follower副本只是采用拉(Pull)的方式,被动的同步leader副本中的数据,并且在Leader副本所在的Broker宕机后,随时准备应聘leader副本。

6、LEO、AR、ISR、HW 都表示什么含义?

6.1 LEO: Log End Offset

日志末端位移值或者末端偏移量,表示日志下一条待插入消息的位移值。举个例子,如果日志有10条消息,位移值从0开始,那么第10条消息的位移值就是9。此时LEO=10;

6.2 AR:Assigned Replicas

AR 是主题被创建后,分区创建时被分配的副本集合,副本个 数由副本因子决定。

6.3 ISR:in-Sync replicas

kafka中特别重要的概念,指的是AR中那些与leader保持同步的副本集合。在AR中的副本可能不在ISR中,但Leader副本天然就包含在ISR中。关于ISR,还有一个常见的面试题目是如何判断副本是否应该属于ISR.目前的判断依据是:Follower副本的LEO落后Leader LEO的时间,是否超过了Broker端参数replica.lag.time.max.ms值。如果超过了,副本就会被从ISR中移除。

7、Java Consumer 为什么采用单线程来获取消息?

Java Consumer是双线程设计,一个线程是用户主线程,负责获取消息;另一个线程是心跳线程,负责向Kafka汇报消费者的存活情况,将心跳单独放入专属的线程,能够有效的规避因消息处理速度慢而被视为下线的假死情况。另外一个可能的好处是,可以简化代码的开发。多线程交互的代码是非常容易出错的。

8、consumer是推还是拉?

Kafka遵循了一种大部分消息系统的传统设计: producer将消息推送到broker, consumer从broker拉取消息。
push模式,将消息推送到下游的consumer这样做有好处也有坏处:由broker 决定消息推送的速率,对于不同消费速率的consumer就不太好处理了。消息系统 都致力于让consumer以最大的速率最快速的消费消息,但不幸的是,push模式 下,当broker推送的速率远大于consumer消费的速率时,consumer恐怕就要崩 溃了。最终Kafka还是选取了传统的pull模式。
Pull模式的另外一个好处是consumer可以自主决定是否批量的从broker拉取数 据。Push模式必须在不知道下遊consumer消费能力和消费策略的情况下决定是 立即推送每条消息还是缓存之后批量推送。如果为了避免consumer崩溃而釆用较 低的推送速率,将可能导致一次只推送较少的消息而造成浪费。Pull模式下, consumer就可以根据自己的消费能力去决定这些策略。

9、数据传输的事务定义有哪三种?

● 最多一次:消息不会被重复发送,最多被传输一次,但也有可能一次不传输
● 最少一次:消息不会被漏发送,最少被传输一次,但也有可能被重复传输.
● 精确的一次(Exactly once):不会漏传输也不会重复传输,每个消息都传输被 —次而且仅仅被传输一次,这是大家所期望的。

10、判断一个节点是否还存活着有那两个条件?

● 节点必须可以维护和Zookerper的链接,zookerper通过心跳机制检查每个节点的连接
● 如果节点是个follower,他必须能及时的同步leader的写操作,延时不能太久

11、讲一kafka的ack的三种机制

requestrequired.acks 有三个值 0 1 -l(all)

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

12、Kafka的高可用机制是什么?

● 多副本冗余的高可用机制
● producers 、Broker、consumer都会拥有多个
● 分区选举机制、消息确认机制

13、kafka吞吐量为何如此高?

13.1 顺序读写

Kafka是将消息记录持久化到本地磁盘中的,有的人会认为磁盘读写性能差,可能 会对Kafka性能如何保证提岀质疑。实际上不管是内存还是磁盘,快或慢关键在于 寻址的方式,磁盘分为顺序读写与随机读写,内存也一样分为顺序读写与随机读 写。基于磁盘的随机读写确实很慢,但磁盘的顺序读写性能却很高,一般而言要高 岀磁盘随机读写三个数量级,一些情况下磁盘顺序读写性能甚至要高于内存随机读 写。
在这里插入图片描述

磁盘的顺序读写是磁盘使用模式中最有规律的,并且操作系统也对这种模式做了大 量优化,Kafka就是使用了磁盘顺序读写来提升的性能。Kafka的message是不断 追加到本地磁盘文件末尾的,而不是随机的写入,这使得Kafka写入吞吐量得到了 显著提升。
上图就展示了 Kafka是如何写入数据的,每一个Partition其实都是一个文件,收 到消息后Kafka会把数据插入到文件末尾(虚框部分)。
这种方法有一个缺陷一一没有办法删除数据,所以Kafka是不会删除数据的, 它会把所有的数据都保留下来,每个消费者(Consumer)对每个Topic都有一个 offset用来表示读取到了第几条数据。

13.2 零拷贝

零拷贝就是一种避免CPU将数据从一块存储拷贝到另外一块存储的技术。
linux操作系统“零拷贝”机制使用了 send句e方法,允许操作系统将数据从 Page Cache直接发送到网络,只需要最后一步的copy操作将数据复制到NIC缓冲 区,这样避免重新复制数据。示意图如下:

通过这种“零拷贝”的机制,Page Cache结合sendfile方法,Kafka消费端的性 能也大幅提升。这也是为什么有时候消费端在不断消费数据时,我们并没有看到磁 盘io比较高,此刻正是操作系统缓存在提供数据。

13.3 分区分段+索引

Kafka的message是按topic分类存储的,topic中的数据又是按照一个一个的 partition即分区存储到不同broker节点。每个partition对应了操作系统上的一个 文件夹,partition实际上又是按照segment分段存储的。这也非常符合分布式系 统分区分桶的设计思想。
通过这种分区分段的设计,Kafka的message消息实际上是分布式存储在一 个一个小的segment中的,每次文件操作也是直接操作的segment。为了进一步 的查询优化,Kafka又默认为分段后的数据文件建立了索引文件,就是文件系统上 的.index文件。这种分区分段+索引的设计,不仅提升了数据读取的效率,同时也 提高了数据操作的并行度。

13.4 批量读写

Kafka数据读写也是批量的而不是单条的。
在向Kafka写入数据时,可以启用批次写入,这样可以避免在网络上频繁传输 单个消息带来的延迟和带宽开销。假设网络带宽为1OMB/S,—次性传输1OMB的 消息比传输1KB的消息1OOOO万次显然要快得多。

13.5 批量压缩

如果每个消息都压缩,但是压缩率相对很低,所以Kafka使用了批量压缩,即 将多个消息一起压缩而不是单个消息压缩
Kafka允许使用递归的消息集合,批量的消息可以通过压缩的形式传输并且在 日志中也可以保持压缩格式,直到被消费者解压缩
Kafka支持多种压缩协议,包括Gzip和Snappy压缩协议
Kafka把所有的消息都变成一个批量的文件,并且进行合理的批量压缩,减少 网络I。损耗,通过mmap提高I/O速度,写入数据的时候由于单个Partion是末 尾添加所以速度最优;读取数据的时候配合sendfile直接暴力输岀。

14、kafka如何记录消费者的位置

如果是根据kafka默认的api来消费,即【org.apache.kafka.clients.consumer.KafkaConsumer】,我们会配置参数【bootstrap.servers】来消费。而其消费者的offset会更新到一个kafka自带的topic【__consumer_offsets】下面,查看当前group的消费进度,则要依靠kafka自带的工具【kafka-consumer-offset-checker】,例如:

[root@localhost data]# kafka-consumer-offset-checker --zookeeper localhost :2181/kafka --group test-consumer-group  --topic stable-test
[2017-08-22 19:24:24,222] WARN WARNING: ConsumerOffsetChecker is deprecated and will be dropped in releases following 0.9.0. Use ConsumerGroupCommand instead. (kafka.tools.ConsumerOffsetChecker$)
Group           Topic                          Pid Offset          logSize         Lag             Owner
test-consumer-group stable-test                    0   601808          601808          0               none
test-consumer-group stable-test                    1   602826          602828          2               none
test-consumer-group stable-test                    2   602136          602136          0               none

上面结果的说明:
● Group : 消费者组
● Topic : topic的名字
● Pid : partition的ID
● Offset : kafka消费者在对应分区上已经消费的消息数【位置】
● logSize : 已经写到该分区的消息数【位置】
● Lag : 还有多少消息未读取(Lag = logSize - Offset)
● Owner : 分区创建在哪个broker

offset更新的方式,不区分是用的哪种api,大致分为两类:

  1. 自动提交,设置enable.auto.commit=true,更新的频率根据参数【auto.commit.interval.ms】来定。这种方式也被称为【at most once】,fetch到消息后就可以更新offset,无论是否消费成功。
  2. 手动提交,设置enable.auto.commit=false,这种方式称为【at least once】。fetch到消息后,等消费完成再调用方法【consumer.commitSync()】,手动更新offset;如果消费失败,则offset也不会更新,此条消息会被重复消费一次。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿小许

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值