https://blog.csdn.net/qq_28900249/article/details/90346599
1、为什么要使用 kafka,为什么要使用消息队列
缓冲和削峰 解耦和扩展性 冗余 健壮性 异步通信
2、Kafka的acks参数对消息持久化的影响
往kafka写数据的时候,就可以来设置这个acks参数。然后这个参数实际上有三种常见的值可以设置,分别是:0、1 和 all(等价于-1)。
API对应ProducerConfig.ACKS_CONFIG
第一种选择是把acks参数设置为0,意思就是我的KafkaProducer在客户端,只要把消息发送出去,不管那条数据有没有在哪怕Partition Leader上落到磁盘,我就不管他了,直接就认为这个消息发送成功了。
如果你采用这种设置的话,那么你必须注意的一点是,可能你发送出去的消息还在半路。结果呢,Partition Leader所在Broker就直接挂了,然后结果你的客户端还认为消息发送成功了,此时就会导致这条消息就丢失了。
第二种选择是设置 acks = 1,意思就是说只要Partition Leader接收到消息而且写入本地磁盘了,就认为成功了,不管他其他的Follower有没有同步过去这条消息了。
这种设置其实是kafka默认的设置,大家请注意,划重点!这是默认的设置
也就是说,默认情况下,你要是不管acks这个参数,只要Partition Leader写成功就算成功。
但是这里有一个问题,万一Partition Leader刚刚接收到消息,Follower还没来得及同步过去,结果Leader所在的broker宕机了,此时也会导致这条消息丢失,因为人家客户端已经认为发送成功了。
最后一种情况,就是设置acks=all(或者-1),这个意思就是说,Partition Leader接收到消息之后,还必须要求ISR列表里跟Leader保持同步的那些Follower都要把消息同步过去,才能认为这条消息是写入成功了。
如果说Partition Leader刚接收到了消息,但是结果Follower没有收到消息,此时Leader宕机了,那么客户端会感知到这个消息没发送成功,他会重试再次发送消息过去。
此时可能Partition 2的Follower变成Leader了,此时ISR列表里只有最新的这个Follower转变成的Leader了,那么只要这个新的Leader接收消息就算成功了。
3、kafka幂等性
解决发送消息重复的问题
4、kafka的分区与消费者关系
分区(partition)
kafka中的topic可以细分为不同的partition,一个topic可以将消息存放在不同的partion中。
leader和follower
每个partition可以设置一个leader和多个follower。kafka的消息没有设置读写分离,每个消息发送时,都是发送至对应的partition的leader-partition,follower-partition主要是为了备份数据而存在,当leader-partition出现故障时,数据已经完全同步的follower-partition也会切换成leader-partition。
AR和ISR
AR:分区中所有的副本统称为AR。
ISR:所有与leader节点保持同步的副本(包括leader节点)组成的节点,生产者首先将消息发送给leader副本,然后follower从leader中同步消息。
ISR是AR的子集。
数据的存储
在partion中,一个topic中的数据存放在不同的partion中,一个分区的内容会存储成一个log文件,为了防止log过大,引入了日志分段,根据一定规则将log切分为多个logSegment,相当于一个巨型文件被切分成了很多不同的文件。log和logSegment关系如下:
Log在物理上只以文件夹的形式存储,日志文件在磁盘的存储如下:
消费者(consumer)
分组(group)
消费者从partion中消费数据,consumer有group的概念,每个group可以消费完整的一份topic中的数据。
消费者分区分配
RangeAssignor 分配策略(kafka默认的分区策略)
kafka中,consumer消费数据时,consumer消费partition中的数据和consumer与partition的相对数量有关。
1、partition大于consumer
当partition大于consumer时,一个consumer可能同时消费多个partition中的数据
2、partition小于consumer
当partition小于consumer时,每个consumer会去消费一个partition中的数据。多出来的consumer则是处于空闲状态
3、partition等于consumer
当partition的数量等于consumer时,每个consumer消费一个partition中的数据。
除了这种分区分配策略之外,还有RoundRobinAssignor以及StickyAssignor分区分配策略,当然,也可以自定义分区分配策略。