怎么保证顺序消费?
同一个生产者发送到同一分区的消息,先发送的比后发送的offset要小。同一生产者发送到不同分区的消息,消息顺序无法保证。
怎么解决这个问题?
给一个topic只设置一个分区
相同key会发给一个分区
怎么保证幂等性?
生产者:如果发生网络抖动等导致ack返回超时,可以通过producer Id + sequence Number,每个producer在初始化时都会有唯一的pid,对每个生产者发送到分区中的消息都会对应一个从0递增的sequence Number,这样分区接收到消息的时候就能判断sequenceNumber是否重复
消费者:比如设置了手动提交offset,消息已经拉取消费了但是还没提交就挂了,可能会导致重复拉取同一段消息。用redis分布式锁或者根据业务判断该消息是否被消费过
kafka消息丢失?
生产者:
Ack = 0,表示不需要等待任何broker回复,可能会在发送到broker或者fl同步的时候丢消息
Ack = 1,表示等待master回复,可能发送到ld还没来得及同步到follwer,master就挂了,导致消息丢失
Ack = -1,等ld和isr中的fl都收到消息,才发送ack
消费者:
设置的自动提交offset,消息拉取了,但是没消费完,就提交了offset,但是消费者宕机了;
另外在ld选举的时候,zk中会维护isr(已同步ld数据)和osr(未同步ld数据)中选举,配置设置为true的时候,如果isr没有数据就会从osr选举
解决:
-
配置ack为-1或者all
-
不允许选举isr以外的副本作为ld
-
可以设置最小同步数量>1,如果不满足则生产者端会抛异常
-
减少broker的刷盘间隔
线上消息积压怎么解决?
-
生产者发送消息过快,消费者消费慢 -> 如果需要紧急处理,可以把修改消费端程序,让它将收到的消息快速转发到其他topic,然后启动多个消费者同时消费新主题的不同分区
-
消息数据格式变动,导致一直消费不成功,也可能导致消息积压,可以转发到死信队列
不同消息队列的优缺点?
rabbitmq:erlang语言,性能好,支持高并发,不利于二次开发
kafka:java实现,高性能高可用,适用于大数据量场景,单机吞吐量百万,缺点单机容量有限
rocketmq:java实现,方便二次开发,高可用高可靠,单机吞吐量十万
kafka高性能高吞吐的原因?
-
磁盘的顺序读写(随机读写的话会多次寻址和旋转),而且会预读一些放在内存中
-
零拷贝:传统是先读取磁盘空间到内核缓冲区,然后到用户缓冲区,再到socket发送缓冲区;零拷贝是直接从内核缓冲区到socket发送缓冲区,避免了内核态和用户态的切换
-
分区分段:每一个分区都是很多个segment文件,针对这些文件有索引,可以快速查找
-
批量压缩,批量读写:比如发送消息的时候是异步发送,当发送一条消息时不会直接发送给broker,而是会先缓存起来,然后批量发送,减少io
-
页缓存:在缓存中操作数据,比在磁盘操作更快
zk的作用?
老版本中,broker会在zookeeper上注册,创建唯一临时节点,并定时发送心跳到zk,如果心跳断开则剔除。接待拿下存储了topic和分区相关信息,维护了消费者组和分区的注册关系以及offset
新版本中可以不使用zookeeper,使用kraft组件,offset由消费者自己维护
kafka副本数据一致性?
hw:分区的ld和fl共同持有的消息,消费者只能消费hw之前的值
leo:每个分区节点已经存在的消息数
从节点出现故障时,把故障节点剔除isr,如果故障恢复了,会将hw之后的消息删除,然后重新从主节点中同步现在的数据
主节点出现故障:选取出来主节点之后,其他从节点会把大于hw值的消息丢掉,然后重新从主节点同步数据
Kafka的rebalance机制?
比如你要向消费者组中新增一个消费者,需要把消费者和对应的topic分区进行匹配,就会产生rebalance,场景主要有:
-
消费者组的成员个数发生变化
-
group订阅的topic个数发生变化
-
group订阅的topic分区数发生变化
ld所在的broker就是一个协调者,通过心跳机制监控消费者组中consumer的存活,返回通知消费者进行balance,选举出新的ld consumer ,ldconsumer从协调者获取所有的consumer,将分配信息发给协调者,协调者再通过心跳机制下发给consumer
读写会进行阻塞,所以要尽量避免rebalance
消费者分区分配策略?
Range 范围分区(默认):比如一人领走几个
轮询:给你一个给你一个再转一圈
sticky:粘性
使用这个消费者组中使用最多的分配策略
分区和消费者组的对应关系?
一个消费者组相当于是一个订阅者,可以订阅主题,然后这些消费者共同消费主题下的分区。当消费者小于分区数时,一个消费者可以消费多个分区;当消费者大于分区数时,可能有消费者空闲(一个分区只能被同一消费者组里的一个消费者消费)
kafka的高可用机制?
集群机制:一个kafka集群由多个broker组成,即使某一个broker宕机也不会影响其他的broker
分区备份机制:一个分区可能会存在多个副本,这些副本存储在不同的broker上。如果ld的副本宕机,就会从isr中的follower中选举出一个新的ld,因为isr是同步复制数据,准确性较高;如果没有可用的isr,就会从osr中选举
kafka的数据清理机制?
kafka的topic数据存储在分区上,分区如果文件过大会分段存储,并且有对应的索引文件和日志文件,这样做能减少单个文件的大小,方便查找数据和日志清理
kafka清理数据有两种策略:第一是根据消息的保留时间,默认超过7天清理;第二是根据存储数据的大小,超过一定阈值就会删除最久的消息(默认关闭)。
如有问题,欢迎指正!