简单总结Kafka相关问题


前言

遇到很多kafka相关问题,一看就会,一问就跪,在这里简单总结,不作深入探讨。


提示:以下是本篇文章正文内容,下面案例可供参考

一、kafka会不会丢失消息?

会!

kafka发送消息一般分三个步骤:

1、生产者发送消息

ack=1(默认),数据发送到kafka,经过leader成功接收消息的确认就算成功(吞吐量高)。

ack=0,生产者发送后不等待任何返回。

ack=-1,需要ISR(副本同步队列)中所有follewer都确认接收到数据才算一次发送。当ISR中所有Replica都向leader发送ack时,leader才commit(不会丢失消息,吞吐量较低)。

2、kafka broker存储数据

kafka为了得到更高的性能和吞吐量,将数据异步批量存储在磁盘,刷盘过程中,为提高性能,减少刷盘次数,采用批量刷盘的做法。

若在刷盘过程中,副本未完成同步时系统出现故障,会造成数据丢失。

3、消费者消费数据

自动提交offset,一定时间间隔将收到的消息进行commit,commit过程和消费消息的过程是异步的。如果消费过程未成功,但commit提交了,消息会丢失。

手动提交offset可保证“至少消费一次”,但随之可能出现重复消费情况。

消息丢失场景总结:

1、网络异常

2、客户端异常

3、缓冲区满(增加消费者,提高吞吐量)

4、副本异常

二、kafka如何解决重复消费问题

消费信息用唯一标识标记消费情况,一般由consumergroup+topic+partition+offset组成。

我在项目中的完成过程如下:

1、获取分布式锁

2、通过redis检查是否已经消费

3、消费

4、更新消费状态

5、释放锁

代码如下:

@Slf4j
public class AlarmMessagePushTask extends BaseWorkTask {

    /**
     * 计数器闭锁
     **/
    private CountDownLatch countDownLatch;

    /**
     * kafka 消费偏移量
     **/
    private Acknowledgment ack;

    /**
     * 报警信息
     **/
    private Alarm alarm;

    /**
     * 告警信息
     **/
    private AlarmDetail alarmDetail;

    /**
     * 设备坐标信息
     */
    private AlarmDeviceCoordinate alarmDeviceCoordinate;

    /**
     * 报警规则配置信息
     **/
    private RuleConfiguration ruleConfiguration;

    /**
     * 报警配置规则
     */
    private MessagePushConfigurationDto messagePushConfiguration;

    /**
     * 失败重试次数,默认为3次
     **/
    private Integer retriesCount = 3;

    /**
     * redis 操作模板
     **/
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 报警信息操作的 service
     **/
    private AlarmService alarmService;

    /**
     * 告警信息操作的 service
     **/
    private AlarmDetailService alarmDetailService;

    /**
     * 字典信息操作的 service
     **/
    private DicService dicService;

    /**
     * 处理告警设备坐标的 service
     */
    private AlarmDeviceCoordinateService alarmDeviceCoordinateService;

    /**
     * @param countDownLatch 计数器闭锁
     * @param ack            kafka 消费偏移量
     * @param ruleConfiguration 报警规则配置信息
     * @param messagePushConfiguration        统一消息推送配置信息
     */
    public AlarmMessagePushTask(@Validated(value = {ValidationGroup_Add.class}) MessagePushConfigurationDto messagePushConfiguration,
                                @Validated(value = {ValidationGroup_Add.class}) RuleConfiguration ruleConfiguration,
                                CountDownLatch countDownLatch, Acknowledgment ack) {
        this.countDownLatch = countDownLatch;
        this.ack = ack;
        this.ruleConfiguration = ruleConfiguration;
        this.messagePushConfiguration = messagePushConfiguration;

        this.alarmService = SpringBeanUtil.getBean(AlarmService.class);
        this.stringRedisTemplate = SpringBeanUtil.getBean(StringRedisTemplate.class);
        this.alarmDetailService = SpringBeanUtil.getBean(AlarmDetailService.class);
        this.dicService = SpringBeanUtil.getBean(DicService.class);
        this.alarmDeviceCoordinateService = SpringBeanUtil.getBean(AlarmDeviceCoordinateService.class);
    }

    /**
     * 工作任务线程
     */
    @Override
    public void run() {
        try {
            Assert.notNull(alarmService, "alarmService is not null");
            Assert.notNull(ruleConfiguration, "ruleConfiguration is not null");
            Assert.notNull(alarmDetailService, "alarmDetailService is not null");
            Assert.notNull(stringRedisTemp
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值