Java 有一个后台线程(使用者线程)让bolt独立于传入的元组执行操作,效率有多高?

Java 有一个后台线程(使用者线程)让bolt独立于传入的元组执行操作,效率有多高?,java,multithreading,apache-storm,Java,Multithreading,Apache Storm,设计:KafkaSpout-->螺栓1-->聚合螺栓 详情: 我有一个聚合螺栓,在特定频率后将统计数据刷新到DB,然后发送它们的ack信号。如果没有更多的传入元组,则元组将超时。在这种情况下,有两种不利影响 KafkaSpout&Bolt1可能会重新处理这些元组并重新发送--对此不予确认。-会导致口是心非 由于口是心非,统计数据不正确 我曾想过有一个由AggregatingBolt发起的背景线程。螺栓将充当生产者,线程充当消费者,它将允许刷新到DB中&独立于传入元组发送ack 那么,回到我的问题

设计:KafkaSpout-->螺栓1-->聚合螺栓

详情:

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

  • KafkaSpout&Bolt1可能会重新处理这些元组并重新发送--对此不予确认。-会导致口是心非
  • 由于口是心非,统计数据不正确
  • 我曾想过有一个由AggregatingBolt发起的背景线程。螺栓将充当生产者,线程充当消费者,它将允许刷新到DB中&独立于传入元组发送ack

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

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


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

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

    查看这篇关于使用storm和tick元组进行微批处理的文章,也许它会有所帮助:


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

    是的,我已经将实现移动到了Tick tuples,代码看起来非常干净和有序!!但工人崩溃的问题仍然存在,因为我没有使用Redis。唯一的原因是缓冲区数据和此类事件的卡夫卡偏移量之间的不一致。在工作进程崩溃时,缓冲区数据不会丢失,但是kafka偏移量不会提交,这将导致从kafka队列中重放一批元组,从而破坏数据缓冲的目的。