我在Scala中使用Spark。我想让Spark使用计算值而不是计算逻辑来持久化数据帧。
本质上,给定一个数据帧df
,我正在寻找一个Spark命令或一系列命令,它们等效于以下操作:
val schema = df.schema
val data = df.collect()
val newDf = sparkSession.createDataFrame(sparkSession.sqlContext.sparkContext.parallelize(data), schema)
newDf.persist()
在我的情况下,给我df1和df2,然后我必须基于以前的数据迭代创建越来越多的新数据帧。代码大致如下:
val metrics2 = doMetrics(df2)
val df3 = myCreationLogic(df1, df2, metrics2)
df3.persist()
val metrics3 = doMetrics(df3)
val df4 = myCreationLogic(df2, df3, metrics3)
df4.persist()
val metrics4 = doMetrics(df4)
...
我无法同时生成df3,df4等。 metrics3中有一些值,这些值将确定创建df4的确切逻辑。本质上,df4是df2和df3的结合,并进行了一些计算以填充字段。如果我没有在上面的代码中调用df.persist()
,而是为每个新数据帧执行了第一段代码,那么我的性能将提高10倍以上。
我的理解是,即使我的视图持久化,Spark也会在每次需要使用它时重新计算基于其表创建的视图(在这里我说的是“表”是指基于Spark外部数据创建的数据帧)和“视图”表示通过对其他数据框执行Spark SQL创建的数据框。如果旧的数据框可能会发生变化,而我希望新的数据框能够反映这些变化,这将很有帮助。就目前而言,旧的数据框不会改变,我需要根据这些视图继续创建新的数据框。我可以坚持选择调用collect()
然后每次都创建一个新的数据帧,但是我认为必须有一种更好的方法可以直接在Spark中进行操作。我也希望使用Spark命令可以使速度进一步提高。