消息发送方式 想清楚Kafka发送的消息是否丢失,需要先了解Kafka消息的发送方式。 Kafka消息发送分同步(sync)、异步(async)两种方式 默认是使用同步方式,可通过producer.type属性进行配置; Kafka保证消息被安全生产,有三个选项分别是0,1,-1 通过request.required.acks属性进行配置: 0代表:不进行消息接收是否成功的确认(默认值); 1代表:当Leader副本接收成功后,返回接收成功确认信息; -1代表:当Leader和Follower副本都接收成功后,返回接收成功确认信息;
消息丢失的场景 网络异常 acks设置为0时,不和Kafka集群进行消息接受确认,当网络发生异常等情况时,存在消息丢失的可能; 客户端异常 异步发送时,消息并没有直接发送至Kafka集群,而是在Client端按一定规则缓存并批量发送。在这期间,如果客户端发生死机等情况,都会导致消息的丢失; 缓冲区满了 异步发送时,Client端缓存的消息超出了缓冲池的大小,也存在消息丢失的可能; Leader副本异常 acks设置为1时,Leader副本接收成功,Kafka集群就返回成功确认信息,而Follower副本可能还在同步。这时Leader副本突然出现异常,新Leader副本(原Follower副本)未能和其保持一致,就会出现消息丢失的情况; 以上就是消息丢失的几种情况,在日常应用中,我们需要结合自身的应用场景来选择不同的配置。 想要更高的吞吐量就设置:异步、ack=0;想要不丢失消息数据就选:同步、ack=-1策略
消息的完整性和系统的吞吐量是互斥的,为了确保消息不丢失就必然会损失系统的吞吐量 调优broker参数防止消息丢失 producer: 1、ack设置-1 2、设置副本同步成功的最小同步个数为副本数-1 3、加大重试次数 4、同步发送 5、对于单条数据过大,要设置可接收的单条数据的大小 6、对于异步发送,通过回调函数来感知丢消息 7、配置不允许非ISR集合中的副本当leader 8、客户端缓冲区满了也可能会丢消息;或者异步情况下消息在客户端缓冲区还未发送,客户端就宕机 9、block.on.buffer.full = true consumer: 1、enable.auto.commit=false 关闭自动提交位移
同一分区消息乱序:
假设a,b两条消息,a先发送后由于发送失败重试,这时顺序就会在b的消息后面,可以设置max.in.flight.requests.per.connection=1来避免 max.in.flight.requests.per.connection:限制客户端在单个连接上能够发送的未响应请求的个数。设置此值是1表示kafka broker在响应请求之前client不能再向同一个broker发送请求,但吞吐量会下降