我想将Map [String,String]保存到磁盘,然后再读回为相同类型。我以某种方式找不到我的sparkContext的collectAsMap方法

时间:2018-08-31 17:32:39

标签: scala apache-spark

我正在使用Spark Scala,需要将Map[String, String]保存到磁盘上,以便其他Spark应用程序可以读取它。

(x,1),(y,2)...

要保存:

sc.parallelize(itemMap.toSeq).coalesce(1).saveAsTextFile(fileName)

我正在合并,因为数据只有450行。

但是要读回去,我无法将其转换回Map[String, String]

val myMap = sc.textFile(fileName).zipWithUniqueId().collect.toMap

数据来自

((x,1),0),((y,2),1)...

可能的解决方案是什么?

谢谢。

2 个答案:

答案 0 :(得分:0)

加载文本文件会导致RDD[String],因此您将不得不反序列化元组的字符串表示形式。

您可以更改保存操作,以在元组值1和元组值2之间添加定界符,或解析字符串(:v1, :v2)

val d = spark.sparkContext.textFile(fileName)

val myMap = d.map(s => {
    val parsedVals = s.substring(1, s.length-1).split(",")
    (parsedVals(0), parsedVals(1))
}).collect.toMap

或者,您可以更改保存操作以创建定界符(如逗号)并以这种方式解析结构:

itemMap.toSeq.map(kv => kv._1 + "," + kv._2).saveAsTextFile(fileName)
val myMap = spark.sparkContext.textFile("trash3.txt")
  .map(_.split(","))
  .map(d => (d(0), d(1)))
  .collect.toMap

答案 1 :(得分:0)

方法“ collectAsMap”存在于“ PairRDDFunctions”类中,意味着仅适用于具有两个值RDD [(K,V)]的RDD。

如果需要此函数调用,可以使用下面的代码进行组织。数据框用于以csv格式存储,避免了手工解析

Post

输出:

val originalMap = Map("x" -> 1, "y" -> 2)
// write
sparkContext.parallelize(originalMap.toSeq).coalesce(1).toDF("k", "v").write.csv(path)

// read
val restoredDF = spark.read.csv(path)
val restoredMap = restoredDF.rdd.map(r => (r.getString(0), r.getString(1))).collectAsMap()
println("restored map: " + restoredMap)