消息:批次
主题和分区
优势:
多生产者多消费者
基于磁盘的数据存储(可以配置删除机制),activeMQ\rabbitMQ需要去额外配置持久化
高伸缩 (主题——》分区)
高性能(支持集群,不同分区可以放到不同节点)
生产者发送数据的方式:
- 发送并忘记
- 同步发送
- 异步发送
自定义序列化器、自定义分区器
ACK机制:
- -1:
- 0:只管发送
- 1:只负责发送到首领
- ALL:要负责发送到首领,并且同步到冗余分片中
kafka如何保证消息顺序?
解决方案:
操作:
topic不可以分片
max.in.flight.requests.per.connections=1
原理:这样的话生产者尝试发送一批消息的时候,就不会有其他的消息发送给broker
弊端:严重影响吞吐
消费者组:
需求:消费者业务比较复杂,为了消费速率,可以使用消费群组
原则:
- 一个主题的一个分区只能被一个消费者消费(指的是一个消费者组内的消费者)
- 先来后到,
消费者配置:
分片分配策略:连续分配;轮训分配
消费者自动(或手动)确认offset,类似mysql的commit
ActiveMQ 、RabbitMQ、RocketMQ、kafka区别?
activeMQ:支持事务,没有生产大规模使用场景,官方维护少
RabbitMQ:erlang语言开发,性能好,高并发,学习成本高
以上吞吐量在万级
kafka:高性能,高可用,生产有大规模使用场景,吞吐在百万级
rocketMQ:阿里开发,java开发,高可用,高可靠(消息0丢失),社区活跃度一般,支持语言少,吞吐量单机10万
面试题
consumer是推还是拉?
答案:pull
push和pull各有优缺点。
首先push的话,对于不同消费速率的消费者,生产者很难决定push的频率,如果推送频率过高,会导致消费者崩溃,如果推送频率太低,会导致消息延迟性升高,以及消费者资源浪费的问题。
所以kafka采用pull的方式,对于消费者来说,可以根据自身的服务器性能来配置pull的速率,以及是否批量从broker拉取数据,这样的模式能够更好的与生产者配合,从而提高消息的吞吐,提升资源的利用率
kafka如何维护消息的消费状态?
kafka可以对消息进行分区存储,同一时间一个分区只能对应一个消费者。每个消费者维护了自身的offset,即消费位置,这样对于服务端来说,就可以很方便的记录消费者的消费位置。如果消费者希望重新消费消息,只需要指定offset就可以。
kafka主从同步
leader负责读写消息,follower负责阻塞以等待同步新的消息。
ISR(In-Sync Replicas)能够和 leader 保持同步的 follower + leader本身 组成的集合。
Kafka是一定会保证leader接收到的消息完全同步给ISR中的所有副本。
ISR的核心就是 动态调整
在eplica.lag.time.max.ms时间内,只要follower有追赶上leader一次,那么该follower就存在于ISR中,不然就剔除,直到该follower追赶上leader才重新加入到ISR
同时,kafka还有一个ack机制,生产 者可以设置ack值,0代表只管发送,不管成功与否;-1代表发送并且等待所有follower同步成功才算推送成功;1代表只要成功写入leader就算推送成功,默认为1,这种方案。
kafka的key有什么用?
生产者在发送消息的时候,如果没有指定partition,那么会对key进行散列算法,然后放入对应的partition中,所以,相同的key会放到同一个partition,同时也可以保证相同key的消息是有序的,因为在一个分片中的消息必然是有序的。
kafka如何保证消息幂等?kafka如何保证消息不丢失?
kafka支持三种消息投递语义:最多一次、最少一次、有且仅有一次。最多一次可能会导致消息丢失,但可以保证消息不会重复;最少一次可以保证消息不会丢失,但是可能重复;有且仅有一次,消息不丢失不重复。
我们需要消费幂等性,我们不怕数据重复,可以在消费端做消息重复性校验,比如redis 中set集合;mysql中唯一索引
其次保证消息顺序,生产消息的时候设置key,那么相同key就会放在一个分片,分片内消息是有序的,这个kafka可以保证,多线程消费消息的时候,我们可以把相同key的消息放入一个队列中,然后一个线程读取一个队列,从而达到对于同一个key的消息是有序消费的
kafka应用场景?
异步处理
应用解耦
流量削峰:秒杀任务
日志处理
消息通讯