spark.RDD take(n)返回元素n的数组,n次

时间:2014-08-14 14:45:30

标签: json scala hadoop apache-spark

我使用https://github.com/alexholmes/json-mapreduce中的代码将多行json文件读入RDD。

var data = sc.newAPIHadoopFile( 
    filepath, 
    classOf[MultiLineJsonInputFormat], 
    classOf[LongWritable], 
    classOf[Text], 
    conf)

我打印出前n个元素以检查它是否正常工作。

data.take(n).foreach { p => 
  val (line, json) = p
  println
  println(new JSONObject(json.toString).toString(4))
}

但是,当我尝试查看数据时,从take返回的数组似乎不正确。

而不是返回表单数组

[ data[0], data[1], ... data[n] ] 

形式为

[ data[n], data[n], ... data[n] ]

这是我创建的RDD的问题,还是我试图打印它的问题?

1 个答案:

答案 0 :(得分:2)

我弄清楚为什么take返回一个重复值的数组。

如API所述:

Note: Because Hadoop's RecordReader class re-uses the same Writable object 
for each record, directly caching the returned RDD will create many 
references to the same object. If you plan to directly cache Hadoop 
writable objects, you should first copy them using a map function.

因此,在我的情况下,它重用了相同的LongWritable和Text对象。例如,如果我这样做:

val foo = data.take(5)
foo.map( r => System.identityHashCode(r._1) )

输出结果为:

Array[Int] = Array(1805824193, 1805824193, 1805824193, 1805824193, 1805824193)

因此,为了防止它这样做,我只是将重用的对象映射到它们各自的值:

val data = sc.newAPIHadoopFile(
    filepath,
    classOf[MultiLineJsonInputFormat],
    classOf[LongWritable],
    classOf[Text],
    conf ).map(p => (p._1.get, p._2.toString))