一、kafka 的消费模式
producer和consumer对于消息的交付可靠性保障
1 | kafka 的消费模式 |
kafka如何做到消息精确一次呢?机制:幂等性和事务
二、如何保证消息精确一次
1. 幂等性
1 | 在数学中,幂等的意思为:执行某个操作或函数能够执行多次,但每次得到的结果都是不变的。幂等最大的优势在于我们可以安全地重试任何幂等性操作,反正他们也不会破坏我们的系统状态。 |
producer和consumer对于消息的交付可靠性保障
1 | kafka 的消费模式 |
kafka如何做到消息精确一次呢?机制:幂等性和事务
1 | 在数学中,幂等的意思为:执行某个操作或函数能够执行多次,但每次得到的结果都是不变的。幂等最大的优势在于我们可以安全地重试任何幂等性操作,反正他们也不会破坏我们的系统状态。 |
生产者端一旦网络出现波动,那么消息就可能出现失序。应该考虑同步发送消息
max.in.flight.requests.per.connection = 1
。这样,kafka 发送端,一条消息发出后,响应必须满足 acks 设置的参数后,才会发送下一条消息。虽然在使用时,还是异步发送,但其实底层已经是一条接一条的发送了max.in.flight.requests.per.connection
,这个参数默认是5,意思是在被Broker阻止前,未通过acks确认的发送请求最大数,也就是在Broker处排队等待acks确认的Message数量。设置为1。让Broker处永远只有一条Message在排队,就可以严格控制顺序了。但是这样做会严重影响性能(接收Message的吞吐量)
分区策略
1 | 功能:决定生产者将消息发送到那个分区的算法 |
生产者压缩算法
1 | kafka中Producer端压缩、Broker端保持、Consumer端解压缩 |
在 kafka 文件存储中,同一个 topic 下有多个不同的 partition,每个 partition 为一个目录,partition 命名规则为 “topic名称+有序序号”,第一个 partition 序号从 0 开始,序号最大值为 partitions 数量减 1 。
当kafka 中有多 Broker 多 partition 的时候:如下,是一个 kafka 集群中,1 个 Topic 4 个 Broker,2 Replication,
当集群中新增 2 节点,partition 增加到 6 个时分布情况如下:
消息队列目前主要2种模式,分别为“点对点模式”和“发布/订阅模式”。
一个具体的消息只能由一个消费者消费。多个生产者可以向同一个消息队列发送消息;但是,一个消息在被一个消费者处理的时候,这个消息在队列上会被锁住或者被移除并且其他消费者无法处理该消息。需要额外注意的是,如果消费者处理一个消息失败了,消息系统一般会把这个消息放回队列,这样其他消费者可以继续处理。
单个消息可以被多个订阅者并发的获取和处理。一般来说,订阅有两种类型:
1 | kafka只对“已提交”的消息做有限度的持久化保证 |
kafka 丢消息会发生在 Broker、Producer、consumer 三种
Broker丢失消息是由于Kafka本身的原因造成的,kafka为了得到更高的性能和吞吐量,将数据异步批量的存储在磁盘中。消息的刷盘过程,为了提高性能,减少刷盘次数,kafka采用了批量刷盘的做法。即,按照一定的消息量,和时间间隔进行刷盘。这种机制也是由于linux操作系统决定的。将数据存储到linux操作系统种,会先存储到页缓存(Page cache)中,按照时间或者其他条件进行刷盘(从page cache到file),或者通过fsync命令强制刷盘。数据在page cache中时,如果系统挂掉,数据会丢失。
broker 写数据只写到 pageCache中,而 pageCache 位于内存,这部分数据断电后会丢失。pageCache 的数据会通过 Linux 的 flusher 程序进行刷盘。刷盘触发条件有:
重平衡过程通过消费者端的心跳线程通知到其他消费者实例
heartbear.interval.ms:设置了心跳的间隔时间,也控制重平衡通知的频率。如果想要消费者实例能迅速地得到通知,那可以设置一个非常小的值,这样消费者就能更快的感知到重平衡已经开启了
1 | 1. 发起 FindCoordinator 请求时。 |
消费者程序会创建3类TCP连接:
1 | 1. 确定协调者和获取集群元数据 |