在Redis上写入的三叉戟或Storm拓扑

我有一个拓扑问题.我试着解释工作流程……
我有一个源每2分钟发出大约500k元组,这些元组必须由一个喷口读取,并像一个对象一样繁琐地处理(我认为是三叉戟中的批处理).
之后,一个bolt / function /还有什么?…必须附加一个时间戳并将元组保存到Redis中.

我尝试使用一个函数实现Trident拓扑,该函数使用Jedis对象(Redis库for Java)将所有元组保存到Redis中,但是当我部署时,我会在此对象上收到NotSerializable异常.

我的问题是.如何实现一个在Redis上写这批元组的函数?在网上阅读我找不到任何从函数写入Redis的示例或在Trident中使用State对象的任何示例(可能我必须使用它…)

我的简单拓扑:

TridentTopology topology = new TridentTopology();
topology.newStream("myStream", new mySpout()).each(new Fields("field1", "field2"), new myFunction("redis_ip", "6379"));

提前致谢

最佳答案
(由于与Redis相关的具体问题似乎在其他评论中得到解决,因此一般回复州)

当我们记住Storm从分布式(或“分区”)数据源(通过Storm“spouts”)读取时,Storm中的DB更新概念变得更加清晰,并行处理许多节点上的数据流,可选地对这些数据执行计算数据流(称为“聚合”)并将结果保存到分布式数据存储(称为“状态”).聚合是一个非常宽泛的术语,仅仅意味着“计算内容”:例如,计算流上的最小值在Storm中看作是先前已知最小值的聚合,其中当前在集群的某个节点中处理了新值.

考虑到聚合和分区的概念,我们可以看看Storm中的两个主要原语,它们允许在一个状态中保存一些东西:partitionPersist和persistentAggregate,第一个在每个集群节点的级别运行而不与其他分区感觉有点像通过DAO与DB通信,而第二个涉及“重新分区”元组(即通过集群重新分配它们,通常沿着某些组逻辑),进行一些计算(“聚合”) )在读取/保存到DB之前,感觉有点像和HashMap而不是DB(在这种情况下Storm将数据库称为“MapState”,或者如果地图中只有一个键,则称为“快照”).

要记住的另一件事是,只有通过一次处理每个元组才能实现Storm的一次语义:这太脆弱了,因为在我们的拓扑中定义了每个元组可能有多个读/写操作,我们要避免出于可伸缩性原因的两阶段提交,并且在大规模,网络分区变得更有可能.相反,Storm通常会继续重播元组,直到他确定它们已经完全成功处理至少一次.这与状态更新的重要关系是Storm给我们原始(OpaqueMap)允许幂等状态更新,以便这些重放不会破坏先前存储的数据.例如,如果我们总结数字[1,2,3,4,5],那么保存在DB中的结果将始终为15,即使它们在“sum”操作中被重放和处理多次,因为有些暂时失败. OpaqueMap对用于在DB中保存数据的格式有轻微影响.请注意,只有当我们告诉Storm这样做时,才会出现那些重放和不透明逻辑,但我们通常会这样做.

如果你有兴趣阅读更多,我在这里发表了2篇关于这个主题的博客文章.

http://svendvanderveken.wordpress.com/2013/07/30/scalable-real-time-state-update-with-storm/

http://svendvanderveken.wordpress.com/2014/02/05/error-handling-in-storm-trident-topologies/

最后一件事:正如上面重播的内容所示,Storm本质上是一种非常异步的机制:我们通常有一些数据生成器在排队系统(例如Kafka或0MQ)中发布事件,而Storm则从那里读取.因此,在问题中建议的风暴内分配时间戳可能会或可能不会产生预期效果:此时间戳将反映“最近成功处理时间”,而不是数据提取时间,当然它不会相同在重播元组的情况下.

转载注明原文:在Redis上写入的三叉戟或Storm拓扑 - 代码日志