合并元数据

如同ProtocolBuffer,Avro,Thrift一样,Parquet也是支持元数据合并的。用户可以在一开始就定义一个简单的元数据,然后随着业务需要,逐渐往元数据中添加更多的列。在这种情况下,用户可能会创建多个Parquet文件,有着多个不同的但是却互相兼容的元数据。Parquet数据源支持自动推断出这种情况,并且进行多个Parquet文件的元数据的合并。因为元数据合并是一种相对耗时的操作,而且在大多数情况下不是一种必要的特性,从Spark 1.5.0版本开始,默认是关闭Parquet文件的自动合并元数据的特性的。可以通过以下两种方式开启Parquet数据源的自动合并元数据的特性:

  1. 读取Parquet文件时,将数据源的选项,mergeSchema,设置为true
  2. 使用SQLContext.setConf()方法,将spark.sql.parquet.mergeSchema参数设置为true

案例:合并学生的基本信息,和成绩信息的元数据
scala版本:

package cn.spark.study.sql


import org.apache.spark.SparkConf;
import org.apache.spark.SparkContext;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.SQLContext;
import org.apache.spark.sql.SaveMode


object ParquetMergeSchema {
  def main(args: Array[String])
  {
    val conf = new SparkConf()
      .setAppName("ParquetMergeSchema")
    val sc = new SparkContext(conf);
    val sqlContext = new SQLContext(sc);
    
    import sqlContext.implicits._
    // 创建一个DataFrame, 作为学生的基本信息,并写入一个parquet文件中
    val studentsWithNameAge = Array(("leo", 23), ("jack", 25)).toSeq
    val studentsWithNameAgeDF = sc.parallelize(studentsWithNameAge, 2).toDF("name", "age")
    studentsWithNameAgeDF.save("hdfs://spark1:9000/spark-study/students", "parquet", SaveMode.Append)
      
    // 创建第二个DataFrame,作为学生的成绩信息,并写入一个parquet文件中
    val studentsWithNameGrade = Array(("marry", "A"), ("tom", "B")).toSeq
    val studentsWithNameGradeDF = sc.parallelize(studentsWithNameGrade, 2).toDF("name", "grade")
    studentsWithNameGradeDF.save("hdfs://spark1:9000/spark-study/students", "parquet", SaveMode.Append)
    
    // 首先, 第一个DataFrame和第二个DataFrame的元数据肯定是不一样的吧
    // 一个是包含了name和age两个列,一个是包含了name和grade两个列
    // 所以,这里期望的是,读取出来的表数据,自动合关两个文件的元数据,出现三个列,name、age、grade
    
    // 用mergeSchema的方式,读取students表中的数据,进行元数据的合关
    val studentsDF = sqlContext.read.option("mergeSchema", "true").parquet("hdfs://spark1:9000/spark-study/students")
    studentsDF.printSchema()
    studentsDF.show()
  }
}

文章最后,给大家推荐一些受欢迎的技术博客链接

  1. Hadoop相关技术博客链接
  2. Spark 核心技术链接
  3. JAVA相关的深度技术博客链接
  4. 超全干货--Flink思维导图,花了3周左右编写、校对
  5. 深入JAVA 的JVM核心原理解决线上各种故障【附案例】
  6. 请谈谈你对volatile的理解?--最近小李子与面试官的一场“硬核较量”
  7. 聊聊RPC通信,经常被问到的一道面试题。源码+笔记,包懂