Apache Storm:tileClean Bolt发送Tuple后下游Bolt无法接收问题咨询
排查Apache Storm拓扑中Bolt无法接收数据的问题
嘿,我来帮你梳理一下这个问题!从你贴出的代码来看,流定义和拓扑连接的逻辑框架是对的,但有几个关键细节需要你逐一排查:
1. 先确认窗口Bolt是否触发了执行
你的tileClean Bolt是窗口类型的(因为execute方法的参数是TupleWindow),这意味着它的执行依赖于窗口的触发条件。你需要先检查:
- 定义
tileCleanBolt时,是否配置了正确的窗口策略?比如滚动窗口的大小、滑动窗口的时间间隔是否符合你的预期? - 上游
assembly发送的Tuple数量是否满足窗口触发的要求?比如如果窗口大小设为10,但只收到了5个Tuple,窗口就不会触发,execute方法根本不会运行,自然不会向下游emit数据。
你可以先看日志里有没有打印logger.debug("clean"),如果没有,那窗口未触发就是核心问题。
2. 验证下游Bolt的输入字段声明
虽然tileClean已经正确声明了每个流的输出字段,但下游的OneBolt、TwoBolt等必须在declareInputFields方法中匹配对应的字段。比如OneBolt的代码应该类似:
@Override public void declareInputFields(OutputFieldsDeclarer declarer) { declarer.declare(new Fields(BoltConstant.EMIT_LOGOBJ)); }
如果下游Bolt的输入字段和tileClean输出的字段不匹配,会导致Tuple无法被正确接收或处理。
3. 检查日志级别,确认下游是否真的没收到数据
有时候不是没收到数据,而是下游Bolt的日志级别设置过高(比如只显示INFO及以上),导致debug日志没打印出来。你可以在下游Bolt的execute方法开头加一行:
logger.info("Received tuple from tileClean!");
然后查看日志是否有输出,以此确认是否真的没有接收到数据。
4. 确认emit的Values是否有效
你emit的是new Values(nal),要检查nal是否为null或者空值?如果nal是null,下游Bolt虽然能收到Tuple,但如果处理逻辑依赖nal的内容,可能会看起来像是没收到数据。你可以在tileClean里加日志打印nal的内容,确认它是有效的。
小优化建议
你现在为每个下游Bolt单独创建了一个流,其实Storm支持将同一个Tuple发送给多个Bolt,不需要创建多个流。这样可以简化代码,也避免流名称拼写错误的问题:
// 修改tileClean的declareOutputFields,只声明一个共享流 @Override public void declareOutputFields(OutputFieldsDeclarer declarer) { declarer.declareStream("shared_stream", new Fields(BoltConstant.EMIT_LOGOBJ)); } // 在execute里只需要emit一次到这个共享流 this._collector.emit("shared_stream", input, new Values(nal)); // 拓扑配置中所有下游Bolt都订阅这个共享流 builder.setBolt("OneBolt", OneBolt, 1).shuffleGrouping("tileClean", "shared_stream"); builder.setBolt("TwoBolt", TwoBolt, 1).shuffleGrouping("tileClean", "shared_stream"); builder.setBolt("ThreeBolt", ThreeBolt, 1).shuffleGrouping("tileClean", "shared_stream"); builder.setBolt("FourBolt", FourBolt, 1).shuffleGrouping("tileClean", "shared_stream"); builder.setBolt("FiveBolt", FiveBolt, 1).shuffleGrouping("tileClean", "shared_stream");
内容的提问来源于stack exchange,提问作者user5933728
相关产品推荐
相关产品推荐

