ISpout.nextTuple()
javadoc指定在同一个帖子上调用nextTuple()
,ack(...)
和fail(...)
。
但是,之前提供调用emit(...)
的实际收集器作为open(..., collector)
上的参数。
问题是看到一些新数据的后台线程是否必须始终将nextTuple()的数据入队以使其出队和发出。如果后台线程立即发出数据会发生什么?这支持了吗?如果允许,在nextTuple()
中实施“短时间睡眠”的推荐方法是什么?
答案 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()方法才会短暂睡眠。