Spark Dataset选择性重新计算

时间:2017-10-19 11:19:44

标签: apache-spark spark-dataframe apache-spark-dataset

我知道Spark知道如何分配在新节点上完成的工作,例如在另一个节点发生故障时启动该节点。

我想知道是否可以在其他用例中使用它。

假设我有一个转化和行动树。当其中一个数据集/数据框更新时会发生什么(例如,导入了新文件)。在这种情况下,我想只重复那些受此影响并与此更改相关联的转换和操作。其他不相关的转换和操作应该从缓存中使用,因为它们没有受到影响。

现在,如果我只有少数这些数据帧,转换和操作,我可以手动完成。但我有几十个或更多这样的DF和动作,我试图理解,如果spark在框架中内置了可以帮助我的东西。

以下是我的代码示例:

val carLines = spark
  .read
  .option("header", "true")
  .schema(carLineSchema)
  .csv("src/test/resources/cars")

val ageMappingFunction: Int => String = (age: Int) => if (age > 80) "old" else "young"
//
val _age = udf.register("_age", ageMappingFunction)

val personLines = spark
  .read
  .option("header", "true")
  .schema(personLineSchema)
  .csv("src/test/resources/persons")
  .withColumn("_age", _age($"age"))

val accidentsLines = spark
  .read
  .option("header", "true")
  .schema(accidentLineSchema)
  .csv("src/test/resources/accidents")

val carOwners = personLines
  .withColumnRenamed("id", "driver_id")
  .join(carLines, Seq("driver_id"), "left")
  .withColumnRenamed("id", "car_id")
  .withColumnRenamed("car_make", "car_maker")
  .withColumnRenamed("driver_id", "id")

现在进行一些转换:

 val accidentsWithDrivers = accidentsLines
  .join(personLines.withColumnRenamed("id", "driver_id"), "driver_id")

 val accidentsPerDriverID = accidentsWithDrivers
  .groupBy("driver_id")
  .agg(Map(
    "name" -> "count"
  ))
  .withColumnRenamed("count(name)", "accident_count")
  .withColumnRenamed("driver_id", "id")

 val finalTable = carOwners
  .join(numberOfCarsPerDriver, Seq("id", "name", "age", "_age"))
  .join(accidentsPerDriverID, "id")

然后我做了一些动作(为简单起见,我将使用'show'):

carOwners.show(true)
numberOfCarsPerDriver.show(true)
finalTable.show(true)

所以 - 我要问的是,如果accidentsLines发生了变化,而不是carLinespersonLines。我们可以使用carOwnerscarLines的缓存值进行personLines转换吗?

其他词语: 我可以以某种方式使用RDD #cache()api在不同的驱动程序运行之间存活,假设我想将它保留在spark集群中的内存中吗?

1 个答案:

答案 0 :(得分:1)

原来我需要使用job-server或使用Apache Ignite的IgniteRDD支持:

//WRITE
val igniteContext = new IgniteContext(spark.sparkContext, "ignite-config.xml", true)
val schema = dataframe.schema
val rdd = dataframe.rdd
igniteContext.ignite().getOrCreateCache("ignite-cache").put("schema", schema)
igniteContext.fromCache(name).saveValues(rdd)

//READ
 val schema = igniteContext.ignite()
    .getOrCreateCache[String, StructType]("ignite-cache")
    .get("schema")
    .asInstanceOf[StructType]

  val igniteRdd: IgniteRDD[String, Row] = igniteContext.fromCache(name)
  val rdd = igniteRdd.map(a => a._2)
  val dataframe = spark.createDataFrame(rdd, schema)