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

iovurdzv  于 2021-05-30  发布在  Hadoop
关注(0)|答案(1)|浏览(407)

我用的是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的问题,还是我如何打印它的问题?

b1zrtrql

b1zrtrql1#

我知道为什么了 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)

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

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

相关问题