首页 文章

如何更新RDD?

提问于
浏览
19

我们正在开发Spark框架,其中我们将历史数据移动到RDD集合中 .

基本上,RDD是我们进行操作的不可变的只读数据集 . 基于此,我们已将历史数据移至RDD,并在此类RDD上进行过滤/映射等计算 .

现在有一个用例,RDD中的数据子集得到更新,我们必须重新计算这些值 .

HistoricalData采用RDD的形式 . 我根据请求范围创建另一个RDD,并在ScopeCollection中保存该RDD的引用

到目前为止,我已经能够想到以下方法 -

Approach1: broadcast the change:

  • 对于每个更改请求,我的服务器获取特定于范围的RDD并生成作业

  • 在工作中,在该RDD上应用 Map 阶段 -

2.A.对于RDD中的每个节点,对广播进行查找并创建一个现在更新的新值,从而创建一个新的RDD
2.B.现在我在step2.a上再次对这个新的RDD进行所有计算 . 像乘法,减少等
2.C.我将此RDDs引用保存在我的ScopeCollection中

Approach2: create an RDD for the updates

  • 对于每个更改请求,我的服务器获取特定于范围的RDD并生成作业

  • 在每个RDD上,使用具有更改的新RDD进行连接

  • 现在我在步骤2再次对这个新的RDD进行所有计算,如乘法,减少等

Approach 3:

我曾想过创建流RDD,我不断更新相同的RDD并进行重新计算 . 但据我所知,它可以从Flume或Kafka获取流 . 而在我的情况下,值是基于用户交互在应用程序本身中生成的 . 因此,我无法在上下文中看到流RDD的任何集成点 .

关于哪种方法更好或任何其他适合此方案的方法的任何建议 .

TIA!

2 回答

  • 1

    这里介绍的用例与Spark Streaming非常匹配 . 另外两个选项带有一个问题:“你如何提交重新计算RDD?”

    Spark Streaming提供了一个框架,可以根据传入的数据流不断向Spark提交工作,并以RDD格式保存该数据 . Kafka和Flume只是两种可能的Stream源 .

    您可以使用与SocketInputDStream的Socket通信,使用FileInputDStream读取目录中的文件,或者甚至使用带有QueueInputDStream的共享队列 . 如果这些选项都不适合您的应用程序,您可以编写自己的InputDStream .

    在此用例中,使用Spark Streaming,您将读取基础RDD并使用传入的dstream逐步转换现有数据并保持不断变化的内存状态 . dstream.transform 将允许您将基本RDD与在给定批处理间隔期间收集的数据相结合,而 updateStateByKey 操作可以帮助您构建由键处理的内存中状态 . 有关详细信息,请参阅documentation .

    如果没有关于应用程序的更多细节,很难使用Spark Streaming来达到代码级别 . 我建议你探索这条道路并为任何特定主题提出新问题 .

  • 7

    我建议看看IndexedRDD implementation,它提供了键值对的可更新RDD . 这可能会给你一些见解 .

    这个想法基于密钥的知识,允许您使用已创建的RDD的相同密钥压缩更新的数据块 . 在更新期间,可以过滤掉以前版本的数据 .

    有历史数据,我会说你必须有一个事件的身份 .

    关于流和消费,可以使用TCP端口 . 这样,驱动程序可能会打开一个TCP连接,期望从那里读取并发送更新 .

相关问题