Storm Spouts是否只使用调用Spout.nextTuple的线程发出输出?

时间:2014-02-10 22:28:18

标签: multithreading apache-storm

ISpout.nextTuple() javadoc指定在同一个帖子上调用nextTuple()ack(...)fail(...)

但是,之前提供调用emit(...)的实际收集器作为open(..., collector)上的参数。

问题是看到一些新数据的后台线程是否必须始终将nextTuple()的数据入队以使其出队和发出。如果后台线程立即发出数据会发生什么?这支持了吗?如果允许,在nextTuple()中实施“短时间睡眠”的推荐方法是什么?

2 个答案:

答案 0 :(得分:3)

在同一个线程上调用nextTuple()/ack()/fail()方法的隐含意义,在机器'A'上运行的任务(后台Java线程),发出元组是同一个任务,在'A'运行根据处理的成功/失败(由在'B'或'C'运行的Bolt处理)调用ack()/ fail(),拓扑中的元组。

只要messageId不为null并且Bolt任务在execute()方法中调用ack(tuple),Storm框架就会跟踪拓扑中的元组遍历并调用元组的ack()/ fail()拥有任务。

以下是回答问题之前后台任务线程如何工作的简要介绍。后台任务线程具有用于发出的元组的内存结构/缓冲区以及用于状态/挂起元组等的少数其他内存中结构。当Spout / Bolt开始发送数据并且此缓冲区被释放为时,缓冲区变满。并且在处理元组时,即在调用ack()/ fail()之后。本质上,后台线程在缓冲区空闲时调用nextTuple(),后台线程在缓冲区满时停止调用nextTuple()。简单来说,在open()/nextTuple()/close()中的emit()方法填充后台线程缓冲区,ack()/fail()释放缓冲区。

通过上述说明,后台线程不知道新的/传入数据。由nextTuple()中的逻辑决定从源(Twitter / JMS提供者/ ESB / AMQP兼容服务器/ RDBMS)读取数据并发出数据。因此,根据后台线程的缓冲区大小,Storm会调用nextTuple(),如上所述。

对于其他问题,如果需要,可以短时间睡觉。请注意,nextTuple()不需要发出值,它可以返回任何内容。

答案 1 :(得分:1)

我的理解是,除非Storm通过调用nextTuple()方法请求,否则不应发出数据。因此,您的后台线程必须将新数据排入队列,以便在请求时将其发出。只有在调用方法时没有要发出的元组时,你的nextTuple()方法才会短暂睡眠。