Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache storm 为什么Trident在这个最小的示例中不调用ack()或fail()?_Apache Storm_Trident - Fatal编程技术网

Apache storm 为什么Trident在这个最小的示例中不调用ack()或fail()?

Apache storm 为什么Trident在这个最小的示例中不调用ack()或fail()?,apache-storm,trident,Apache Storm,Trident,我试着用三叉戟制作一个小例子。我们的目标是观察元组在发生故障时是如何重放的。下面是拓扑定义 Random rand = new Random(); Config config = new Config(); config.setDebug(true); config.setNumWorkers(1); TridentTopology topology = new TridentTopology();

我试着用三叉戟制作一个小例子。我们的目标是观察元组在发生故障时是如何重放的。下面是拓扑定义

        Random rand = new Random();

        Config config = new Config();
        config.setDebug(true);
        config.setNumWorkers(1);

        TridentTopology topology = new TridentTopology();

        topology.newStream("spout", new RandomIntegerSpout())
                .map((MapFunction) tridentTuple -> {
                    if ((tridentTuple.getLongByField("msgid") % 50 == 0) &&
                            (rand.nextInt(2) == 1)) {
                        System.out.println(String.format("Failed to process tuple %d", tridentTuple.getLongByField("msgid")));
                        throw new ReportedFailedException("Divisible by 50");
                    }
                    return new Values(tridentTuple.toArray());
                })
                .peek((Consumer) tridentTuple -> System.out.println(tridentTuple.getValues()));
我使用storm starter中的
RandomIntegerSpout
,它扩展了
BaseRichSpoot
,只生成随机数。然后,我应用一个
MapFunction
,它只是每隔50个元组抽取一个随机数,然后随机使元组失败

问题是,我没有得到任何
ack
s或
fail
s

我玩了一下喷口,在调试模式下运行它,尝试了相同的示例输出,用标准风暴螺栓进行了尝试。锚定工作正常,只是没有被三叉戟召唤

我在1.2.3版和2.0.0版中用LocalCluster和StormSubmitter重现了这个问题

下面是Storm UI的屏幕截图: 与map ack和fail元组对应的螺栓如预期的那样失败,但这永远不会传播回喷口

我认为三叉戟mastercoord可能会期望某种状态下的持久性来实现拓扑结构的完成,但是用某种persistentAggregate替换peek并没有帮助。我还排除了
map
中的一个bug,方法是对
每个
执行相同的操作


通过检查发现代码几乎微不足道,我可能误解了Trident/Storm的一些基本内容。如果批量完成,我期望trident调用喷口的和
ack
方法是错误的吗?我意识到在
IBatchSpout
中没有
fail
方法。Trident如何处理批次的重放???

Trident Spoots不会在单个元组级别确认或失败元组。相反,元组作为一个批进行确认

三叉戟喷口通常看起来像

其思想是Trident将管理批次元组的ACK/FAILES跟踪,然后如果批次失败,它将要求喷口重复批次,如果没有,它根本不会

请注意,这与标准雨水口有何不同。对于普通的喷口,框架基本上会告诉喷口“嘿,发射一些东西。你发射什么取决于你自己”,然后使用
ack
fail
方法告诉喷口是否应该再次发射特定的元组

使用Trident时,喷口被告知“嘿,(重新)发出批次号x”,然后由喷口知道该批次中有哪些元组。使用此模型,不需要
fail
方法。一些三叉戟喷口将有一个
ack/succeed
方法,允许喷口放弃与特定进行中批次相关的任何状态

对于包装的
IRichSpouts
,有一些将它们包装到Trident API中。基本上,包装器调用
nextTuple
,直到拥有完整的批处理,然后将ID存储在缓存中。如果要求包装器重新提交一批,它将在喷口上调用
fail
。否则,一旦批处理成功,它将调用
ack

我认为你在Storm UI中没有看到与此相关的任何内容的原因是,
IRichBolt
实际上没有在那里表示出来。相反,它是被包装的,因此
ack/fail
调用在
spoot-spoot
组件内部的“引擎盖下”发生。如果您想确定是否正在调用ack/fail,请尝试在
IRichSpout
ack/fail
方法中添加一些日志记录

M emitPartitionBatch(TransactionAttempt tx, TridentCollector collector, PartitionT partition, M lastPartitionMeta);