Kafka面试宝典

Kafka特性

  1. 高吞吐 ,低延迟
  2. 可扩展性
  3. 持久性 ,可靠性
  4. 容错性
  5. 高并发

Kafka使用场景

异步处理 ,日常解耦 ,削峰 ,提速 ,广播

例: 消息队列 ,网站活动 ,监控指标 ,日志集合 ,流处理 ,事件采集 ,日志提交

kafka选择Pull模式还是Push模式

produce将消息推送到replication副本(push),consumer从replication副本拉取消息(pull)

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

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

pull模式有个缺点: 如果broker没有可供消费消息 ,将倒置consumer不断在循环中轮询 ,直到新消息到达 ,为了避免这单 ,kafka有个参数可以让consumer阻塞直到消息到达(当然也可以阻塞直到消息的数量达到特定的量就可以批量发送)

kafka与传统消息系统之间有三个关键区别

  1. kafka持久化日志 ,这些日志可以被重复读取和无限期保留
  2. kafka是一个分布式消息系统: 它以集群方式运行 ,可以灵活伸缩 ,在内部通过赋值数据提升容错能力和高可用性
  3. kafka支持实时流处理

kafka怎么实现消息顺序性

kafka每个partition中的消息在写入的时候都是有序的 ,每个partition只能被一个消费者组的消费者消费 ,同时保证了消费的时候是有序的

整个topic不保证有序 ,如果想保证全局有序 ,可以把partition的数量设置为1 ,但是分区越少吞吐量越小 ,设置为1个分区 ,是把kafka当消息队列使用

kafka生产者客户端使用几个线程 分别是什么

2个线程 ,分别是主线程和sender线程

主线程创建消息 ,然后通过分区器 ,序列化器 ,拦截器作用之后缓存到recordaccumulator中 .

Sender线程负责将recordAccumulator中的消息发送到kafka

kafka中的分区器 ,序列化器 ,拦截器 它们之间的顺序

分区器: 根据键值确定消息应该处于那个分区 ,默认使用轮询分区 ,可以自行实现分区器接口和自定分区逻辑

序列化器: 键序列化器和值序列化器 ,将键和值都转换为二进制 ,还有反序列化起 ,将二进制转换为指定类型

拦截器: 两个方法doSend()方法会在序列化之前完成onAcknowledgenment()方法在消息确认或失败时调用   可以添加多个拦截器

调用顺序: 拦截器 -> 序列化器 -> 分区器

消费者组中的个数大于分区数 会出现消费不到的场景吗

分情况

可以通过自定义分区策略 ,可以将一个consumer指定消费所有的partition

如果不指定consumer的分区 ,就会出现消费者消费不到数据

因为一个分区partition为了确保顺序性 ,只能有一个消费者

那些场景会造成重复消费

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

那些场景会造成消息遗漏消费

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

kafka consumer是非线程安全的 ,怎么实现多线程消费

  1. 在每个线程中创建一个kafkaconsumer ,每个线程的consumer都不是一个对象 ,就不会存在线程安全
  2. 单线程创建kafka consumer ,要不直接把它搞成单例都可以 ,多个处理线程处理消息(难点在于考虑消息顺序性 ,offset的提交方式)

kafka如何实现高吞吐

  1. 顺序读写
  2. 零拷贝
  3. 文件分段
  4. 批量发送
  5. 数据压缩

kafka的ack机制

0: 生产者不会等待leader的回应 ,直接生产下一条消息 ,安全性最弱 ,容易丢失数据

1: leader收到其中一个follower的消息 ,producer收到leader的消息 ,才能生产下一条消息 ,安全系数 一般

-1: leader收到所有的follower的消息 ,producer收到leader的消息 ,生产下一条消息 ,安全系数较高

kafka consumer是否可以消费指定分区的消息

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

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

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

kafka判断一个节点是否还活着有哪些条件

  1. 节点必须可以维护和Zookeeper的连接  ,zookeeper通过心跳机制检查每个节点的连接
  2. 如果结点是follower ,它必须能及时的同步leader的写操作 ,不能延迟太久

优先副本是什么 有什么特殊作用

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

当你使用kafka-topic.sh创建或者删除topic ,kafka背后执行什么逻辑

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

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

说明什么是Apache Kafka

Apache Kafka是由Apache开发的一种发布订阅消息系统 它是一个分布式的 ,分区的和重复的日志服务

什么是传统的消息传递方法

传统的消息传递方法包括两种:

排队: 在队列中 ,一组用户可以从服务器中读取消息 ,每条消息都发送给其中一个人

发布-订阅: 在这个模型中 消息被广播给所有的用户

Kafka想对传统的消息传递方法有什么优势

高性能  单一的kafka代理可以处理成千上万的客户端 ,每秒处理数兆字节的读写操作 ,kafka性能远超传统的ActiveMQ ,RabbitMQ等 ,而kafka支持Batch操作

可扩展  kakfa集群可以透明的扩展 ,增加新的服务器集群

容错性  kafka的每个partition数据都会复制到几台服务器 ,当某个Broker失效 ,Zookeeper将通知生产者和消费者从而使用其他的Broker

kafka的术语解析

topic  主题 ,可以理解为一个队列

partition  分区 ,为了实现扩展性 ,一个非常大的topic可以分到多个broker(服务器)上 ,一个topic可以有多个partition ,partition中的每条消息都会分配一个有序的id(offset) .kafka只保证按一个partition中的顺序传送给consumer ,不保证一个topic的整体(多个partition间)有序

offset  偏移量 ,kafka的存储文件都是按照offset.kafka来命名 ,用offset做名字的好处是方便查找 .例如你想找位于2049的位置 ,只要找到2048.kafka的文件即可 .当然the first offset就是0000000000.kafka

broker  一台kafka服务器就是一个broker ,一个集群由多个broker组成 ,一个broker可以容乃多个topic

producer 消息生产者 向kafka broker发消息的客户端

consumer  消息消费者 向kafka broker取消息的客户端

consumer group  消费者组 这是kafka用来实现一个topic消息的广播(发给所有的consumer)和单播(发给任意一个consumer)的手段 一个topic可以有多个CG ,topoic的消息会复制(不是真的复制 是概念上的)到所有的CG ,但每个partition只会把消息发给该CG中的一个consumer 如果要实现广播 只要每个conusmer都有一个独立的CG就可以啦 要实现单播的话要所有的consumer都处于一个CG中 ,用CG还可以将consumer进行自由的分组 ,而不需要多次发送消息到不同的topic

kafka服务器能接收到的最大信息是多少

kafka服务器可以接收到的消息最大是1000000字节

kafka数据丢失问题 如果避免

1)数据丢失:

acks = 0 生产者不会等待leader的回应 ,直接生产下一条消息 ,安全性最弱 ,容易丢失数据

acks = 1 leader收到其中一个follower的消息 ,producer收到leader的消息 ,才能生产下一条消息 ,(如果leader挂掉 仍会造成数据丢失)

acks = -1 leader收到所有的follower的消息 ,producer收到leader的消息 ,生产下一条消息 ,安全系数较高

2)brocker如何保证不丢失:

acks=all : 所有副本都写入成功并确认

retries = 一个合理值。(重试次数)

min.insync.replicas=2  消息至少要被写入到这么多副本才算成功。

unclean.leader.election.enable=false 关闭unclean leader选举,即不允许非ISR中的副本被选举为leader,以避免数据丢失。

3)Consumer如何保证不丢失

如果在消息处理完成前就提交了offset,那么就有可能造成数据的丢失。

enable.auto.commit=false 关闭自动提交offset

处理完数据之后手动提交。

kafka如何保证kafka的消息有序

kafka只能保证一个分区有序 如果想保证整体有序 那就只设置一个分区 这是吧kafka当做消息队列来使用

为什么去使用Kafka

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

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

冗余: 可以采用一对多的方式, 一个生产者发布消息, 可以被多个订阅topic的服务消费到, 供多个毫无关联的业务使用.

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

异步通信: 很多时候, 用户不想也不需要立即处理消息. 消息队列提供了异步处理机制, 允许用户把一个消息放入队列, 但并不立即处理它. 想向队列中放入多少消息就放入多少消息, 然后再需要的时候再去进行处理.

kafka的过期数据处理

日志清理保存的策略只有delete和compact两种

1. log.cleanup.policy = delete 启动删除策略

2. log.cleanup.policy = compact 启动压缩策略

kafka支持传输

kaka对消息体默认大小为单条最大值为1M,生产中我们的消息体常常会大于这个值. 这时我们可以对kafka进行以下配置

replica.fetch.max.bytes = 12582912

message.max.bytes = 11534336

kaka顺序读写的好处

kakfa的producer生产数据, 要写入log文件中, 写的过程是追加到文件的末尾, 为顺序写. 官网有数据表名, 同样的磁盘, 顺序写速度是600M

/s, 而随机写的速度只有100k/s. 这与磁盘的机械结构有关, 顺序写之所以快, 是因为省去了大量的磁头寻址时间.

kafka的幂等性

producer的幂等性指的是当发送同一条信息, 数据在server端只会被持久化一次, 数据不丢失不重复.但是这里的幂等性是条件的: 

1. 只能producer在单个会话内不丢失不重复, 如果producer出现意外挂掉再重启是无法保证的

2. 幂等性不能跨多个partiton, 只能保证单个partition内的幂等性.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值