Apache storm 如何知道卡夫卡风暴中的重试次数

Apache storm 如何知道卡夫卡风暴中的重试次数,apache-storm,Apache Storm,我知道SpoutConfig有retryLimit来设置消息可以重新处理的次数 关于retryLimit,这是我在SpoutConfig.class中找到的消息: 指数回退重试设置。这些都是由 ExponentialBackoffMsgRetryManager,用于在中断后重试邮件 调用OutputCollector.fail 我想知道,当元组在我的代码中的任何给定螺栓中被处理时,是否有任何方法可以知道重试的确切次数 例如,如果我将retryLimit设置为5,并且第一次调用OutputColl

我知道SpoutConfig有retryLimit来设置消息可以重新处理的次数

关于retryLimit,这是我在SpoutConfig.class中找到的消息:

指数回退重试设置。这些都是由 ExponentialBackoffMsgRetryManager,用于在中断后重试邮件 调用OutputCollector.fail

我想知道,当元组在我的代码中的任何给定螺栓中被处理时,是否有任何方法可以知道重试的确切次数

例如,如果我将retryLimit设置为5,并且第一次调用OutputCollector.fail失败,而第二次重新处理时,我想知道这个元组已经失败了1次

我将非常感谢你在这方面的帮助


谢谢。

对此没有内置支持。用户从卡夫卡记录生成的元组仅取决于卡夫卡记录,而不取决于重播的数量

默认的RecordTranslator将发出主题、分区和偏移量作为元组的一部分,因此您可以使用它们来检查您的Bolt是否已看到元组,然后再假设您有某种状态存储。为什么螺栓需要知道元组失败了多少次

编辑: 我认为我们没有将失败计数作为一个选项添加到发出的元组中的原因之一是它不可靠。由于一个元组的失败次数只存在于喷口中的内存中,因此您可能会遇到元组失败、喷口崩溃以及故障计数超过0的元组的情况

即使我们在喷口中有一个持久状态存储,仍然会有失败元组未被标记为失败元组的情况,例如,如果喷口首先崩溃,之前发出的元组随后失败。重新启动的喷口无法识别先前发出的元组,因此不会将其标记为失败

在我看来,你实际上需要跟踪的是喷口是否不止一次发出一个元组,而不是喷口是否认为它以前失败过


您可能可以使用和onEmit来跟踪哪些偏移已发出多次。因为它是作为喷口的一部分运行的,所以在确认元组时清理状态应该非常简单。仍然有可能丢失失败的元组,因为onEmit是在喷口发出元组后运行的,因此如果喷口在发出元组后立即崩溃,您可能会错过失败。也许可以考虑一下,您是否可以先以某种方式围绕此需求进行设计。

据我所知,Storm不提供对此的内置支持

我尝试过以下提到的实现:

    public class AuditMessageWriter extends BaseBolt {

        private static final long serialVersionUID = 1L;
        Map<Object, Integer> failedTuple = new HashMap<>();

        public AuditMessageWriter() {

        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
            this.collector = collector;
            //any initialization if u want
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void execute(Tuple input) {
            try {

            //Write your processing logic
            collector.ack(input);
            } catch (Exception e2) {
            //In case of any exception save the tuple in failedTuple map with a count 1
            //Before adding the tuple in failedTuple map check the count and increase it and fail the tuple

            //if failure count reaches the limit (message reprocess limit) log that and remove from map and acknowledge the tuple
            log(input);
            ExceptionHandler.LogError(e2, "Message IO Exception");
            }

        }

        void log(Tuple input) {

            try {
                //Here u can pass result to dead queue or log that
//And ack the tuple 
            } catch (Exception e) {
                ExceptionHandler.LogError(e, "Exception while logging");
            }
        }

        @Override
        public void cleanup() {
            // To declare output fields.Not required in this alert.
        }

        @Override
        public void declareOutputFields(OutputFieldsDeclarer declarer) {
            // To declare output fields.Not required in this alert.
        }

        @Override
        public Map<String, Object> getComponentConfiguration() {
            return null;
        }

    }

斯蒂格,谢谢你的回复。在我的例子中,螺栓需要知道编号,因为业务部门希望在错误表中插入特殊处理,以将其重新处理为失败的元组。编辑的答案由于评论太多感谢您的回答Stig,我将尝试一下,看看会发生什么。