一、Kafka的一些基本概念
生产者向topic发送消息,消息顺序存储在kafka的日志文件当中。消费者从最后一条消息的下一条或者最开始那一条进行消费。
二、单播消息、多播消息
单播消息:一个消费组中只有一个消费者能得到topic中的消息。
多播消息:不同的消费组订阅同一个topic,那么【每一个消费组】中都能【有且仅有一个】消费者得到消息
三、主题和分区
1.topic主题在kafka中是一个逻辑概念。kafka通过topic将消息进行分类。
2.如果topic对应日志文件中的数量过多,kafka提出了分区的概念:partition
分区的好处?
1.解决统一存储文件过大的问题
2.加大读写的吞吐量
kafka的默认分区是干啥的?
kafka有五十个默认分区(_consumer_offsets-xxxx),存储消费者消费某个主题的偏移量。
- 消息提交到哪个分区? hash(consumerGroupId)% _consumer_offsets主题的分区数
- 提交了什么数据? key是consumerGroupId + topic+分区号。 value是offset
四、副本
1.有了kafka集群才有了副本的概念。
2.副本相当于是分区的备份。
由上图可见:
1.topic有两个分区:my-replicated-topic _0. my-replicated-topic _1
2.my-replicated-topic _0在每个borker上都有,只不过在broker2上才是leader,读写都在broker2上
3.my-replicated-topic _1在每个borker上都有,只不过在broker0上才是leader,读写都在broker0上
五、集群消费
1.topic中一个分区的消息只能 被一个消费组中的一个消费者消费 比如:Partition0的消息只能被GroupA中的 Consumer1或Consumer2消费 或者 GroupB中的 Consumer3、 Consumer4、 Consumer5、 Consumer6其中之一消费。 目的是为了保证消费的顺序性。但是总的partition消费的顺序得不到保证
2.Group中的消费者 不能大于 topic中的分区,否则多余的消费者消费不到
六、同步、异步发送消息
同步:如果发送者发送完消息没有收到ack,生产者会阻塞,阻塞三秒,然后进行重试 ,重试三次。
ack有三种配置:
- ack=0: Kafka-ckuster 不需要任何broker收到消息,就立即返回ack给生产者,最容易丢消息但是效率是最高的
- ack=1(默认):多副本之间的leader已经收到消息,并将消息写入到本地的log当中,才返回ack给生产者,性能和安全性是最均衡的
- ack=-1/all :min.insyncc.replicas=1 则表示需要一个leader和一个follower同步完成之后,才会返回ack给生产者。
异步:生产者发送完消息之后就可以进行后面的业务逻辑,broker收到消息后会异步调用生产者提供的callback方法
七、消息发送缓冲区
- kafka会默认创建一个存放消息的缓冲区,生产者发送消息先发到缓冲区里。默认大小为32MB
- kafka本地线程会去缓冲区里拉取16KB的数据,发送到broker
- 如果拉取不到16k的数据,间隔10ms也会将已经拉到的数据发送到broker
八、 消费者offset的自动提交和手动提交
- 自动提交:消费者poll下来消息以后就会自动提交offset
- 手动提交:
- 同步提交:消费者消费完消息后调用同步提交的方法,当集群返回ack前一直阻塞,返回ack表示提交成功,执行之后的逻辑。
- 异步提交:消费者消费完消息后,不需要等待集群的ack,直接执行后面的逻辑。可以设置一个回调方法,供集群调用。
九、 长轮询poll消息
- 默认情况下。消费者一次会poll 500条消息。
- 代码中设置了长轮询的时间是1000毫秒
- 如果一次poll到了五百条,则直接执行for循环
- 如果这一次没有poll到500条,且时间在一秒之内,那么则直接执行for循环
- 如果多次都没有poll到500条,且一秒时间到了,那么直接执行for循环
- 如果 两次poll的时间间隔超过30s,集群会认为该消费者的消费能力过弱,将其踢出消费组,触发rebalance机制,rebalance机制会造成性能开销。