【问题标题】:Trident or Storm topology that writes on Redis在 Redis 上写入的 Trident 或 Storm 拓扑
【发布时间】:2014-02-24 09:54:40
【问题描述】:

我的拓扑有问题。我试图解释工作流程...... 我有一个每 2 分钟发出约 500k 元组的源,这些元组必须由 spout 读取并像单个对象一样处理一次(我认为是 trident 中的一批)。 之后,螺栓/函数/还有什么?...必须附加时间戳并将元组保存到 Redis 中。

我尝试使用一个函数来实现一个 Trident 拓扑,该函数使用 Jedis 对象(Java 的 Redis 库)将所有元组保存到 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"));

提前致谢

【问题讨论】:

  • 您的意思是,您正在尝试序列化 Jedis 实例?你不能那样做,你应该使用一个特殊的单例模式和 JedisPool (Jedis 真的不推荐,如果你失去连接,它会永远丢失,池解决了这个问题)。
  • 好的,通过池我解决了 Jedis 序列化的问题,但我无法理解如何使用 trident 实现这样的拓扑(真正的问题是缺乏文档和类似示例)。今天我更改了基本 Storm 拓扑类型(没有 Trident)的拓扑,它运行良好,但不能保证像单个(以某种方式排序)批处理一样处理所有元组......
  • 无论如何感谢您的提示,我一步一步开始看到解决方案! :-P

标签: redis apache-storm trident


【解决方案1】:

(一般回复状态,因为与 Redis 相关的具体问题似乎在其他 cmets 中已解决)

当我们牢记 Storm 从分布式(或“分区”)数据源(通过 Storm“spout”)读取数据、并行处理多个节点上的数据流、可选地执行对这些数据流(称为“聚合”)进行计算并将结果保存到分布式数据存储(称为“状态”)。聚合是一个非常广泛的术语,仅表示“计算东西”:例如,在 Storm 中计算流上的最小值被视为先前已知的最小值与当前在集群的某个节点中处理的新值的聚合。

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

要记住的另一件事是,Storm 的 exactly once 语义不是通过只处理每个元组一次来实现的:这太脆弱了,因为每个元组可能有多个读/写操作在我们的拓扑中定义的元组,出于可扩展性的原因,我们希望避免两阶段提交,并且在大规模下,网络分区变得更有可能。相反,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 从那里。因此,按照问题中的建议从风暴中分配时间戳可能会或可能不会产生预期的效果:此时间戳将反映“最新的成功处理时间”,而不是数据摄取时间,当然它不会相同在重放元组的情况下。

【讨论】:

  • 感谢您的详细解释,我尝试在您的文章中阅读更多内容。
【解决方案2】:

你有没有为 redis 尝试过 trident-state。 github上有一个代码已经做到了: https://github.com/kstyrc/trident-redis.

如果这回答了你的问题,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-16
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 2019-08-04
    • 1970-01-01
    • 2019-05-24
    • 1970-01-01
    相关资源
    最近更新 更多