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

Apache spark 用于更改源的Spark Dataframe.cache()行为,apache-spark,dataframe,apache-spark-sql,spark-cassandra-connector,Apache Spark,Dataframe,Apache Spark Sql,Spark Cassandra Connector,我的用例: 从cassandra表创建数据帧 通过筛选列并修改该列的值来创建输出数据帧 使用TTL集将输出数据帧写入cassandra,以便在短时间(2s)后删除所有修改的记录 将输出数据帧返回给调用方,调用方在一段时间后将其写入文件系统。我只能向调用者返回一个数据帧,我没有进一步的控制权。而且,我不能增加TTL 在执行步骤4时,输出数据帧为空。这是因为spark重新计算操作上的数据帧,并且由于沿袭,再次执行cassandra查询,现在不会生成任何记录。 为了避免这种情况,我在步骤2之后添加了一

我的用例:

  • 从cassandra表创建数据帧
  • 通过筛选列并修改该列的值来创建输出数据帧
  • 使用TTL集将输出数据帧写入cassandra,以便在短时间(2s)后删除所有修改的记录
  • 将输出数据帧返回给调用方,调用方在一段时间后将其写入文件系统。我只能向调用者返回一个数据帧,我没有进一步的控制权。而且,我不能增加TTL
  • 在执行步骤4时,输出数据帧为空。这是因为spark重新计算操作上的数据帧,并且由于沿袭,再次执行cassandra查询,现在不会生成任何记录。
    为了避免这种情况,我在步骤2之后添加了一个步骤:

    2a)
    outputDataframe.cache()

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

  • 在spark找不到缓存数据(缓存查找失败)的情况下,它是否可能继续沿袭并运行cassandra查询?如果是,在所有情况下如何避免这种情况
  • 我已经看到了另一种缓存方式:
    df.rdd.cache()
    。这与在数据帧上调用
    cache()
    有什么不同吗
  • 作为参考,我当前的代码如下所示:

    //1
    val dfOrig=火花
    阅读
    .format(“org.apache.spark.sql.cassandra”)
    .选项(映射(“键空间”->“myks”,“表”->“mytable”,“下推”->“true”))
    .load()
    //2
    val df=dfOrig.filter(“del_标志='N')。带列(“del_标志”,亮起(“Y”))
    //3
    format(“org.apache.spark.sql.cassandra”)
    .options(映射(“键空间”->“myks”,“表”->“mytable”,“spark.cassandra.output.ttl”->“120”))
    .mode(“追加”)
    .save()
    //4
    // 
    df.write.format(“csv”).save(“some.csv”)
    
    在Spark找不到缓存数据(缓存查找失败)的情况下,它是否可能继续沿袭并运行Cassandra查询

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

    最后,数据可能首先没有完全缓存

    如果是,在所有情况下如何避免这种情况

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

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

    您可能会尝试使用更可靠的缓存模式,如
    内存和磁盘\u 2
    ——这可能会降低重新计算数据的可能性,但代价是

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

    它是不同的(主要的区别是序列化策略),但当涉及到在这个问题范围内感兴趣的属性时就不一样了

    重要


    请注意,缓存行为可能不是代码中最大的问题。在复杂的管道中,从单个表中读取和附加数据可能会导致各种不需要的或未定义的行为,除非采取其他步骤以确保读取器不会选择新写入的记录。

    谢谢。如果缓存/持久化失败,作业是否可能失败?我记得读过AOME,其中有一种方法可以在层次结构的某个点上打破rdd谱系。如果存在,这是一种选择吗?我不知道这种选择。总的来说,缓存只是一个暗示,而不是一个承诺,所以我没有太多的意义去实现它。