繁体   English   中英

用于更改源的 Spark Dataframe.cache() 行为

[英]Spark Dataframe.cache() behavior for changing source

我的用例:

  1. 从 cassandra 表创建数据框。
  2. 通过过滤列并修改该列的值来创建输出数据框。
  3. 将输出数据帧写入带有 TTL 集的 cassandra,因此所有修改的记录都会在短时间(2 秒)后删除
  4. 将输出数据帧返回给调用者,该调用者在一段时间后将其写入文件系统。 我只能向调用者返回一个数据帧,我没有进一步的控制权。 此外,我无法增加 TTL。

到时候,执行步骤4,输出数据帧为空。 这是因为,spark 会重新评估 action 上的数据帧,并且由于沿袭,cassandra 查询再次执行,现在不会产生任何记录。
为了避免这种情况,我在第 2 步之后添加了一个步骤:

2a) outputDataframe.cache()

这可确保在第 5 步中不会查询 cassandra,并且我的文件中也能获得所需的输出记录。 我对这种方法有以下疑问:

  1. 在 spark 找不到缓存数据(缓存查找失败)的情况下,是否有可能沿沿袭并运行 cassandra 查询? 如果是,在所有情况下避免这种情况的方法是什么?
  2. 我见过另一种缓存方式: df.rdd.cache() 这与在数据帧上调用cache()什么不同吗?

作为参考,我当前的代码如下所示:

//1
val dfOrig = spark
      .read
      .format("org.apache.spark.sql.cassandra")
      .options(Map("keyspace" -> "myks", "table" -> "mytable", "pushdown" -> "true"))
      .load()
//2
val df = dfOrig.filter("del_flag = 'N'").withColumn("del_flag", lit("Y"))
//3
df.write.format("org.apache.spark.sql.cassandra")
      .options(Map("keyspace" -> "myks", "table" -> "mytable", "spark.cassandra.output.ttl" -> "120"))
      .mode("append")
      .save()
//4
// <After quite some processing, mostly after the TTL, and in the calling code>
df.write.format("csv").save("some.csv") 

在 Spark 找不到缓存数据(缓存查找失败)的情况下,它是否有可能沿着谱系运行并运行 Cassandra 查询?

对的,这是可能的。 缓存数据可以被缓存清理器移除(主要在MEMORY_ONLY模式下),当相应的节点退役(崩溃、抢占、动态分配释放)时可能会丢失。 此外,其他选项(如推测执行)可能会影响缓存行为。

最后,数据可能不会首先被完全缓存。

如果是,在所有情况下避免这种情况的方法是什么?

如果您需要强大的一致性保证,请不要使用cache / persist ——它的设计没有考虑到像这样的用例。 而是将数据导出到持久、可靠的存储(如 HDFS)并从那里读取。

您还可以将checkpoint与 HDFS checkpointDir一起使用。

您可能会倾向于使用更可靠的缓存模式,例如MEMORY_AND_DISK_2 - 这可能会降低重新计算数据的可能性,但代价是

df.rdd.cache()。 这与在数据帧上调用 cache() 有什么不同吗?

它是不同的(主要区别是序列化策略),但在涉及此问题范围内感兴趣的属性时则不同。

重要

请注意,缓存行为可能不是您代码中的最大问题。 在复杂的管道中读取和附加到单个表可能会导致各种不受欢迎或未定义的行为,除非采取额外的步骤来确保读取器不会选择新写入的记录。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM