暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

由kafka重复消费问题引发的思考

晨起临风 2021-07-28
2380

线上遇到了kafka重复消费的问题,只有一个原因offset提交的时候失败了。


一、 kafka的使用方式及问题处理

大多数情况下都如下方式使用kafka,一般指定好topic、group_id、bootstrap_servers。对于其他参数一般用不到,也很少关心。

    from kafka import KafkaConsumer


    consumer = KafkaConsumer(
    'my_topic',
    group_id= 'group2',
    bootstrap_servers= ['localhost:9092'],
    auto_offset_reset='earliest', # 当offset不存在时从哪儿开始消费,earlist从最老的消息开始,latest(默认)从最新的消息开始
    # enable_auto_commit=False, # 不自动提交偏移量
    auto_commit_interval_ms = 5000, # 自动提交时间间隔,默认5秒
    max_poll_records = 100, # 调用poll 方法批量获取数据量,默认500
    max_poll_interval_ms = 1000, # 批量拉取数据的时间间隔,如果超过这个时间没有拉取数据,则认为这个消费者已过期,会将当前分区分配给其他的消费者
    session_timeout_ms = 10000, # 消费者过期时间,默认10秒,当服务器在这个时间内没有收到消费者的心跳包,会认为当前会话已过期
    heartbeat_interval_ms = 3000, # 消费者发送心跳包的时间间隔
    request_timeout_ms = 305000, # 客户端请求超时时间
                        connections_max_idle_ms = 300000# 连接最大空闲时间,超过此时间自动关闭连接,默认540秒
    ) # 非线程安全,如果由多个消费者,最好不要使用多线程消费,而是多进程


    # ds = consumer.poll() # 批量获取数据


    for message in consumer:
    print ("%s:%d:%d: key=%s value=%s" % (message.topic, message.partition,
    message.offset, message.key,
    message.value))


    offset: 在parition(分区)内的每条消息都有一个有序的id号,这个id号被称为偏移(offset),它可以唯一确定每条消息在parition(分区)内的位置。即offset表示partiion的第多少message


    重复消费可能的原因:

    1、设置 auto_offset_reset = 'earlist' , 会导致任务每次启动时都会从最老的数据开始消费,常见场景为补数据的情况。

    2、offset提交失败,设置auto_commit_interval_ms 过大,程序异常或其他原因导致程序立刻退出,offset没有提交,任务重启时会重复消费一部分数据。


    对策:

    修改为手动提交偏移量,分为以下两种情况处理:

    1、重复消费(最少一次消费语义实现):消费数据处理业务完成后进行offset提交,可以保证数据最少一次消费,因为在提交offset的过程中可能出现提交失败的情况,导致数据重复消费


    2、丢失数据(最多一次消费语义实现):在消费数据业务处理前进行offset提交,可以保证最多一次消费,在后续数据业务处理程序出现故障,将导致数据丢失


    二、扩展思考

    对于数据库、消息队列、缓存、文件读写、网络访问等这些都可以抽象为资源,而且这些资源使用比较昂贵,在使用这些资源时要节约资源,要注意以下几点。

    1、资源的有效期,以及超时时间。

    2、使用连接池,限制最大连接数。

    3、确保资源在单位时间内的使用次数在合理范围内,如果超出合理范围,需要看一下处理逻辑和使用方式是否有问题。


    参考文档:

    KafkaConsumer — kafka-python 2.0.2-dev documentation

    文章转载自晨起临风,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论