我有一个java spring应用程序,它基于创建拓扑结构的DTO将拓扑提交到风暴(1.1.2)雨云。
除了非常大的窗户外,这非常有效。我正在用几个不同的滑动和翻滚窗口对其进行测试。除了每15分钟前进一次的24小时滑动窗口外,没有人给我任何问题。该拓扑将从Kafka接收到约250条消息/秒,并使用一个简单的时间戳提取器(延迟时间为3秒)将其窗口化(与我正在测试的所有其他拓扑一样)。
我已经极大地考虑了工作程序和内存余量以尝试解决此问题,但是我的默认配置是1个工作程序,堆大小为2048mb。我还尝试减少了影响最小的延迟。
我认为窗口大小可能过大,并且工作程序内存不足,这会延迟心跳或Zookeeper连接检入,进而导致Nimbus杀死工作程序。
发生的情况是经常发生的(前进约11个窗口),Nimbus日志报告该拓扑的执行程序“未激活”,并且该拓扑的工作日志显示KeeperException
,拓扑可以在其中运行” t与Zookeeper或带有嵌套java.lang.ExceptionInInitializerError:null
的{{1}}通信。
为拓扑分配新工作线程时,我正在做的聚合丢失了。我认为发生这种情况是因为该窗口至少容纳250 * 60 * 15 * 11(messagesPerSecond * secondsPerMinute * 15mins * windowAdvancesBeforeCrash)消息,每个消息大约84个字节。要完成整个窗口,最终将得到250 * 60 * 15 * 97条消息(messagesPerSecond * secondsPerMinute * 15mins * 15minIncrementsIn24HoursPlusAnExpiredWindow)。如果我的数学正确的话,这大约是1.8gbs,所以我觉得工作人员的记忆应该覆盖了窗口或至少超过11个窗口提前值。
我可以略微增加内存,但增加不多。我还可以减少内存/工作者的数量并增加工作者/拓扑的数量,但是我想知道是否缺少某些东西?我是否可以增加工作人员的心跳时间,以使执行者有更多时间在被杀死之前进行检入,否则会由于某种原因而变坏?如果我更改了心跳,则它将出现在拓扑的Config映射中。谢谢!
答案 0 :(得分:1)
这是由于工作人员内存不足而引起的。从查看Storm代码开始。看起来Storm像元组(它是一个相当大的对象)一样在窗口中保留了每条消息。消息量很高,并且有24小时的窗口,因此内存很大。
我通过使用一个初步的固定螺栓来解决此问题,该螺栓将在最初的1分钟窗口内对所有元组进行存储,这大大降低了主窗口上的负载,因为它现在每分钟接收一个元组。存储桶窗口不会耗尽内存,因为它的窗口中一次只有一分钟的元组。