使用后台线程(消费者线程)使螺栓独立于传入元组进行操作的效率如何?

时间:2014-08-22 20:09:53

标签: java multithreading apache-storm

设计:KafkaSpout - > Bolt1 - > AggregatingBolt

详细说明:

我有一个聚合螺栓,在某个频率后将统计数据刷新到DB然后发送它们的ack信号。如果没有更多传入元组,则元组将超时。在这种情况下,有两种不利影响

  1. KafkaSpout& Bolt1可以重新处理这些元组并重新发送 - 不确认这一点。 - 将导致重复
  2. 由于重复而导致错误的统计信息。
  3. 我想过有一个由AggregatingBolt发起的后台线程。 Bolt将作为生产者和线程作为消费者,它将使得能够冲入DB&发送ack独立于传入的元组。

    所以,回到我的问题;), 解决方案的效率如何?或者我们还有其他更好的解决方案吗?

2 个答案:

答案 0 :(得分:0)

我认为您提出的解决方案已足够。你需要另一个线程,因为你的bolt的主要功能与接收元组有关,这意味着如果你只登录接收元组,你将不会定期登录,如你所说,当你没有收到元组和没有记录,你已经收到的元组会超时并导致重新发送和不正确的计数。

在你的螺栓中有一个间隔记录的第二个线程。当然,您必须对线程将共享的变量使用互斥锁,以确保不会发生争用。您还应该确保超时时间长于日志周期,否则在记录之前元组会超时。

答案 1 :(得分:0)

您是否使用Tick元组检查?它使螺栓能够以固定的间隔执行,使用它你不必在螺栓中定义自定义螺纹(为简单起见)。

查看这篇文章关于风暴和蜱元组的微批处理,也许它应该有所帮助:http://hortonworks.com/blog/apache-storm-design-pattern-micro-batching/

当然,这意味着您在刷新到DB之前将结果存储在内存中(JVM worker memory)。因此,如果您的工作人员停止或崩溃,您将丢失内存中当前缓冲区内的所有内容。不丢失这些数据的唯一解决方案是使用外部存储器缓冲区,例如redis。