Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 在SparkSQL中使用Avro模式和拼花格式进行读/写_Apache Spark_Apache Spark Sql_Avro_Parquet - Fatal编程技术网

Apache spark 在SparkSQL中使用Avro模式和拼花格式进行读/写

Apache spark 在SparkSQL中使用Avro模式和拼花格式进行读/写,apache-spark,apache-spark-sql,avro,parquet,Apache Spark,Apache Spark Sql,Avro,Parquet,我正在尝试从SparkSQL编写和读取拼花文件。出于模式演变的原因,我希望在写入和读取时使用Avro模式 我的理解是,这可以在Spark之外(或在Spark内手动),使用例如AvroParquetWriter和Avro的通用API。但是,我希望使用SparkSQL的write()和read()方法(与DataFrameWriter和DataFrameReader一起工作),并且与SparkSQL集成良好(我将编写和读取Dataset的) 我一辈子都不知道该怎么做,我想知道这是否可能。SparkS

我正在尝试从SparkSQL编写和读取拼花文件。出于模式演变的原因,我希望在写入和读取时使用Avro模式

我的理解是,这可以在Spark之外(或在Spark内手动),使用例如AvroParquetWriter和Avro的通用API。但是,我希望使用SparkSQL的write()和read()方法(与DataFrameWriter和DataFrameReader一起工作),并且与SparkSQL集成良好(我将编写和读取Dataset的)

我一辈子都不知道该怎么做,我想知道这是否可能。SparkSQL parquet格式似乎支持的唯一选项是“压缩”和“合并模式”——即,没有用于指定替代模式格式或替代模式的选项。换句话说,似乎无法使用使用SparkSQL API使用Avro模式读取/写入拼花地板文件。但也许我只是错过了什么

为了澄清,我还了解到,这基本上只是在写入时将Avro模式添加到拼花元数据中,并在读取时再添加一个翻译层(拼花格式->Avro模式->SparkSQL内部格式),但特别允许我为缺少的列添加默认值(Avro模式支持,但拼花地板模式不支持)


另外,我并不是在寻找一种将Avro转换为Parquet或将Parquet转换为Avro的方法(而是一种将它们一起使用的方法),我也不是在寻找一种在SparkSQL中读/写普通Avro的方法(您可以使用databricks/spark Avro来实现).

我正在做类似的事情。我使用avro模式写入拼花地板文件,但是,不要将其作为avro读取。但是相同的技术也应该适用于读取。我不确定这是否是最好的方法,但无论如何,它是这样的: 我有AvroData.avsc,它有avro模式

KafkaUtils.createDirectStream[String,Array[Byte],StringDecoder,DefaultDecoder,Tuple2[String, Array[Byte]]](ssc, kafkaProps, fromOffsets, messageHandler)


kafkaArr.foreachRDD  { (rdd,time) 
       => { val schema =  SchemaConverters.toSqlType(AvroData.getClassSchema).dataType.asInstanceOf[StructType] val ardd = rdd.mapPartitions{itr =>
              itr.map { r =>
try {
                    val cr = avroToListWithAudit(r._2, offsetSaved, loadDate, timeNow.toString)
                    Row.fromSeq(cr.toArray)
    } catch{
      case e:Exception => LogHandler.log.error("Exception while converting to Avro" + e.printStackTrace())
      System.exit(-1)
      Row(0)  //This is just to allow compiler to accept. On exception, the application will exit before this point
} 
} 
}


  public static List avroToListWithAudit(byte[] kfkBytes, String kfkOffset, String loaddate, String loadtime ) throws IOException {
        AvroData av = getAvroData(kfkBytes);
        av.setLoaddate(loaddate);
        av.setLoadtime(loadtime);
        av.setKafkaOffset(kfkOffset);
        return avroToList(av);
    }



 public static List avroToList(AvroData a) throws UnsupportedEncodingException{
        List<Object> l = new ArrayList<>();
        for (Schema.Field f : a.getSchema().getFields()) {
            String field = f.name().toString();
            Object value = a.get(f.name());
            if (value == null) {
                //System.out.println("Adding null");
                l.add(""); 
            }
            else {
                switch (f.schema().getType().getName()){
                    case "union"://System.out.println("Adding union");
                        l.add(value.toString());
                        break;

                    default:l.add(value);
                        break;
                }

            }
        }
        return l;
    }

希望它能有所帮助

Hi Sunita,谢谢你的回复——我不完全明白你在这里做什么,但看起来你在读Avro,也许是在从中构造内存对象。我在寻找一种方法,在Avro中编写拼花文件,并在拼花文件中包含Avro模式,使用SparkSQL,例如
df.write.parquet(“my_output_location”)
你在这方面有什么进展吗?@pcejrowski没有,我已经开始做其他事情,但当时我无法找到一种使用SparkSQL的现成方法。我想这是可能的(通过一些工作)我很好奇,通过编写一个定制的数据源,比如他们在@JasonEvans做什么,sqoop为什么会在拼花地板中转储avsc模式data@anmolkoul我不太熟悉sqoop,但如果它确实将avro模式放在拼花文件中,这正是我在上面的问题中所指的——放一个avro模式在拼花地板文件中(虽然不是使用sqoop而是使用SparkSQL)
public static AvroData getAvroData (bytes)
{
AvroData av = AvroData.newBuilder().build();
        try {
            av.setAttr(String.valueOf("xyz"));
        .....
    }
   }