kafka的消息保证语义有以下三种,使用过程中需要根据业务场景来选择,kafka默认提供的是第二种
1、at most once:消息有可能丢失,但保证不会重复
2、at least once:消息不会丢失,但消息有可能重复传递
3、exactly once:每条消息只会传递一次
at most once
拉取消息后马上提交offset,在处理拉取消息的时候如果出现失败或者程序宕机,会造成部分消息丢失
at least once
拉取消息后,在处理完所有消息的时候再提交offset,如果在处理消息的过程中出现宕机,在消费程序重启后会重复拉取上次的消息,可能导致重复消费。自动提交offset模式下,每次consumer进行poll操作都会提交上次的offset,所以需要确保在下次的poll之前处理完所有的消息,不然就有可能出现消息的丢失,满足这种条件的时候就满足了at least once 语义
exactly once
消息实现精确的一次消费,如果要实现exactly once语义,可以使用以下三种思路:
1、将消息和offset取出后存入关系型数据库,将消息处理和offset提交放在一个事物里面处理
2、消息中有唯一的主键标识的时候,在消费端可以根据主键进行去重,实现exactly once
3、Kafka 0.11 版本开始引入了事务支持,可以支持exactly once
总结:
1、对于可允许消息丢失的场景,如日志和监控数据,为了提高性能,可选择第一种或者第二种
2、对于需要精确消费一次的场景,建议通过业务处理的幂等性解决