当前位置: 首页 > 知识库问答 >
问题:

在spark代码中多次引用DF时,是否每次都使用DAG创建数据帧(如果不使用persist)?

彭阳朔
2023-03-14

我在一次面试中面对这个问题,操作顺序如下。

读取csv文件并创建DF。DF=火花。读取()。格式(“csv”)。csv(“/路径/文件.csv”)

根据某些条件筛选数据。DF。过滤器(..)

执行计数操作。DF. count()

将数据保存在文件/Table中。DF. saveAsTable()

问题是有多少转换和操作,以及读取csv文件多少次以创建DF?

我很好奇想了解以下内容

一旦文件被读取,DF是否会保留在内存中,直到spark作业完成?如果DF没有在进一步的步骤中使用,即使它从内存中删除,我们也不介意。但是,如果它正在进一步的步骤中使用,它是否会保留在内存中,直到最后一次使用它的步骤?

每次触发每个操作时,是否都会读取文件并创建DF?为什么需要这样做?

我知道执行操作时,文件是只读的。

现在,当首先调用count()操作时,文件已被读入内存,并构建了DF。所以我希望它能留在记忆中。但是,为什么saveAsTable()操作会再次读取文件并使用DAG重新构建DF?

如果每次我们在代码中使用DF引用时都在重新评估DF(使用DAG),那么每次重建DF不是很耗时吗?如果我们每次都必须避免这个重建过程,并且如果我们开始保留DF,我们最终会不会占用所有内存并将一些数据溢出到磁盘并减慢火花应用程序的速度?

有人能解释一下发生了什么吗?

共有1个答案

闾丘卓
2023-03-14

在Spark DAG中,所有操作都分为多个“阶段”。所有阶段都由“洗牌”操作分开。

阶段中的操作在处理位于单个分区中的数据时被组合在一起。

因此,每当执行“操作”(在本例中为count()和saveAsTable())时,它都会触发数据的重新计算,直到上一个DF。也就是说,除非缓存了前一个DF。

val df = spark.read().format("csv").csv("/path/file.csv")

df = df.filter(....)  // you are over writing the df reference

// df.cache() // use this if filter and read is to be performed only once.

val cnt = df.count()  // action - triggers the filter and read operations 

df.saveAsTable()   //  action - triggers the filter and read operations 

关于您的问题:

如果每次我们在代码中使用DF引用时都要重新评估DF(使用DAG),那么每次重建DF不是很耗时吗?

  • 是的,这是一种浪费,这就是为什么如果DF被多次使用,建议缓存DF的原因

如果我们每次都必须避免这个重建过程,并且如果我们开始保留DF,我们最终会不会占用所有内存并将一些数据溢出到磁盘并减慢Spark应用程序的速度?

  • 我想你已经回答了,是的,记忆是有限的资源。这就是默认情况下不会持久化所有DFs的原因。但是,当您持久化时,除了其他选项外,还有多个选项,如MEMORY\u ONLY、MEMORY\u和磁盘。在此处检查详细信息
 类似资料:
  • 问题内容: 我有这个PDO数据库类 我尝试将代码分成不同的类,例如,我有一个连接到clsUserController的clsDBUser。我这样做是为了知道什么类使用什么数据库代码。我的clsDBUser类看起来像这样 我想知道这是否可行,还是我现在在每个类中创建一个新的数据库连接?因为通常在PHP4中(是的,我知道很旧),我无法识别我每次都必须建立一个新的数据库连接。 我需要改进吗,我需要如何改

  • 问题内容: 在我的应用程序中,我对用户的得分进行排名。但是,我仅每24小时计算一次我的排名。我的问题是我不知道在不打扰用户的情况下将计算代码放在哪里。 是否不可能在“后台”中每24小时调用一次代码?因为此刻,当第一个用户在24小时之后使用我的应用程序时,将调用计算代码,但是随后用户必须等待几分钟,直到计算结束。我每个用户的数据都保存在Firebase中。 提前致谢! 问题答案: 编辑2019年4月

  • 问题内容: 我希望能够使用现有的测试数据库来运行我的测试,而又不想让Django在每次运行测试时都创建和删除数据库。这可能吗? 问题答案: 有可能,这是一种方法: 1)定义自己的测试跑步者,看看这里如何。 2)为了让您的自定义测试运行器查看默认的测试运行器,您可以复制并粘贴代码,然后注释以下行:负责销毁测试数据库,我认为您应该尝试一下该行,但要注意的是像这样: 3)将set.py中的TEST_RU

  • 我第一次使用谷歌云环境,特别是谷歌应用程序引擎和数据存储,当我在本地运行时,一切都很好。我正在通过根据文档设置环境变量GOOGLE\u APPLICATION\u凭据来验证数据存储。但一旦我部署到应用程序引擎,请求总是超时,似乎GetAll方法永远不会返回。以下是我的应用程序代码: 应用程序引擎日志中的错误有以下两行: 顺便说一句,这在我的本地服务器上以闪电般的速度完成,并且我的数据存储中只有一条

  • 问题内容: 我想使用React在整个DOM中多次添加组件。这个小提琴显示了我要执行的操作,并且不会引发任何错误。这是代码: HTML: JS: 我已经看过这个问题了,恐怕通过上述操作,我将冒使React组件相互干扰的风险。该问题的答案建议使用服务器端渲染,这对我来说不是一个选择,因为我正在使用Django服务器端。 另一方面,也许我在做什么就可以了,因为我只安装了一个React库实例(而不是多个组

  • 我使用Eclipse数据库开发视角手动创建了一个模式和几个表。但是每当我试图从代码访问表时,我都会得到“架构不存在”错误。但是,如果我在使用这些表之前在程序中创建这些表,一切都会顺利。每次连接到数据库时都必须创建表吗?因为,我正在测试我的代码,我必须多次重启项目。