web-dev-qa-db-ja.com

Avroファイルに搭載されているスキーマを使用してSparkにAvrosをロードするにはどうすればよいですか?

ClouderaパーセルからSpark 0.9.0でCDH4.4を実行しています。

PigのAvroStorageUDFを介して作成されたAvroファイルがたくさんあります。 Avroファイルに搭載されている汎用レコードまたはスキーマを使用して、これらのファイルをSparkにロードしたいと思います。これまで私はこれを試しました:

import org.Apache.avro.mapred.AvroKey
import org.Apache.avro.mapreduce.AvroKeyInputFormat
import org.Apache.hadoop.io.NullWritable
import org.Apache.commons.lang.StringEscapeUtils.escapeCsv

import org.Apache.hadoop.fs.Path
import org.Apache.hadoop.fs.FileSystem
import org.Apache.hadoop.conf.Configuration
import Java.net.URI
import Java.io.BufferedInputStream
import Java.io.File
import org.Apache.avro.generic.{GenericDatumReader, GenericRecord}
import org.Apache.avro.specific.SpecificDatumReader
import org.Apache.avro.file.DataFileStream
import org.Apache.avro.io.DatumReader
import org.Apache.avro.file.DataFileReader
import org.Apache.avro.mapred.FsInput

val input = "hdfs://hivecluster2/securityx/web_proxy_mef/2014/05/29/22/part-m-00016.avro"
val inURI = new URI(input)
val inPath = new Path(inURI)

val fsInput = new FsInput(inPath, sc.hadoopConfiguration)
val reader =  new GenericDatumReader[GenericRecord]
val dataFileReader = DataFileReader.openReader(fsInput, reader)
val schemaString = dataFileReader.getSchema

val buf = scala.collection.mutable.ListBuffer.empty[GenericRecord]
while(dataFileReader.hasNext)  {
  buf += dataFileReader.next
}
sc.parallelize(buf)

これは1つのファイルで機能しますが、スケーリングできません-すべてのデータをローカルRAMにロードし、そこからsparkノードに分散します。

10
rjurney

私自身の質問に答えるには:

import org.Apache.spark.SparkContext
import org.Apache.spark.SparkContext._

import org.Apache.avro.generic.GenericRecord
import org.Apache.avro.mapred.AvroKey
import org.Apache.avro.mapred.AvroInputFormat
import org.Apache.avro.mapreduce.AvroKeyInputFormat
import org.Apache.hadoop.io.NullWritable
import org.Apache.commons.lang.StringEscapeUtils.escapeCsv

import org.Apache.hadoop.fs.FileSystem
import org.Apache.hadoop.fs.Path
import org.Apache.hadoop.conf.Configuration
import Java.io.BufferedInputStream
import org.Apache.avro.file.DataFileStream
import org.Apache.avro.io.DatumReader
import org.Apache.avro.file.DataFileReader
import org.Apache.avro.file.DataFileReader
import org.Apache.avro.generic.{GenericDatumReader, GenericRecord}
import org.Apache.avro.mapred.FsInput
import org.Apache.avro.Schema
import org.Apache.avro.Schema.Parser
import org.Apache.hadoop.mapred.JobConf
import Java.io.File
import Java.net.URI

// spark-Shell -usejavacp -classpath "*.jar"

val input = "hdfs://hivecluster2/securityx/web_proxy_mef/2014/05/29/22/part-m-00016.avro"

val jobConf= new JobConf(sc.hadoopConfiguration)
val rdd = sc.hadoopFile(
  input,
  classOf[org.Apache.avro.mapred.AvroInputFormat[GenericRecord]],
  classOf[org.Apache.avro.mapred.AvroWrapper[GenericRecord]],
  classOf[org.Apache.hadoop.io.NullWritable],
  10)
val f1 = rdd.first
val a = f1._1.datum
a.get("rawLog") // Access avro fields
9
rjurney

これは私のために働きます:

import org.Apache.avro.generic.GenericRecord
import org.Apache.avro.mapred.{AvroInputFormat, AvroWrapper}
import org.Apache.hadoop.io.NullWritable

...
val path = "hdfs:///path/to/your/avro/folder"
val avroRDD = sc.hadoopFile[AvroWrapper[GenericRecord], NullWritable, AvroInputFormat[GenericRecord]](path)
5
dexter