jstorm kafkaspout未能实现fail机制重发功能

本文探讨了ZookeeperKafka消费offset更新机制的问题,指出offset更新延迟的原因在于pendingOffsets的同步机制,并提出了使用ConcurrentSkipListSet替代treeset以解决offset更新延迟问题的解决方案。
摘要由CSDN通过智能技术生成

问题的发现是zookeeper kafka的消费offset很久没有更新,通过打日志发现

lastoffset其实是从发送的保存了所有发送的offset的pendingOffsets(源码里只是个treeset,阿里实现了ack,fail的异步,居然没用ConcurrentSkipListSet)中获取的,而该pendingOffsets删除数据,是ack后才调用的;如果某个offset的数据fail了,那么此时调用的是另外一个treeset集合,而且只是简单的remove,问题是都没塞数据,就直接remvoe了;如下面两张图:

解决方法:

把原先的treeset替换为ConcurrentSkipListSet,

fail方法:

 public void fail(KafkaMessageId fail) {
        failedOffsets.add(fail);
        pendingOffsets.remove(fail.getOffset());
    }

在PartitionConsumer的emmit方法第一行添加如下代码行:

 if (!failedOffsets.isEmpty()) {
            fillFailMessage();
        }
 private void fillFailMessage() {

        ByteBufferMessageSet msgs;
        try {
            if (failedOffsets.isEmpty()) {
                return;
            }
            KafkaMessageId kafkaMessageId = failedOffsets.pollFirst();
            msgs = consumer.fetchMessages(kafkaMessageId.getPartition(), kafkaMessageId.getOffset());
            List<Long> failedOffset = failedOffsets.stream().mapToLong(KafkaMessageId::getOffset).boxed().collect
                    (Collectors.toList());
            for (MessageAndOffset msg : msgs) {
                if (failedOffset.contains(msg.offset())) {
                    LOG.info("failToSend data is parition   :" + partition + "  , offset : " + msg.offset()
                            +"failedOffsets size : "+failedOffset.size());
                    pendingOffsets.add(kafkaMessageId.getOffset());
                    emittingMessages.add(msg);
                    failedOffsets.removeIf(k->{
                  return k.getOffset() == msg.offset();
                    });
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            LOG.error(e.getMessage(), e);
        }
    }

这里你可以自己决定是否过滤已经发送的。到此结束

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值