spark从入门到放弃三十一:Spark Sql (4)数据源Parquet

xiaoxiao2021-02-28  4

文章地址:http://www.haha174.top/article/details/253452 项目源码:https://github.com/haha174/spark.git 1.简介

parquet 是面向分析型业务的列示存储格式. 列式存储比行式存储有哪些优势呢 1.可以跳过不符合条件的数据,只读取需要的数据,降低IO的数量。 2.压缩编码格式可以降低磁盘空间。由于同一列的数据类型是一样的,可以使用更高效的压缩编码进一步节省孔家 3.只要读取需要的列,支持向量运算能够获取更好的扫描性能。

2.加载数据

查询用户数据中的用户姓名 下面给出java 示例

public class ParquetLoadData { public static void main(String[] args) { SparkConf conf=new SparkConf().setAppName("ParquetLoadData"); JavaSparkContext sc=new JavaSparkContext(conf); SQLContext sqlContext=new SQLContext(sc); DataFrameReader reader=sqlContext.read(); Dataset ds= reader.json("hdfs://hadoop:8020/data/users.parquet"); ds.show(); ds.registerTempTable("users"); Dataset userName=sqlContext.sql("select name from users"); //对查询出来的dataSet 进行操作,处理打印 List<String> userNameRDD=userName.javaRDD().map(new Function<Row,String>() { public String call(Row o) throws Exception { return "name:"+o.getString(0); } }).collect(); for(String usernmae:userNameRDD){ System.out.println(usernmae); } } }

下面给出scala 示例

object ParquetLoadData { def main(args: Array[String]): Unit = { val conf = new SparkConf().setAppName("ParquetLoadData") val sc = new SparkContext(conf) val sqlContext = new SQLContext(sc) val reader = sqlContext.read val ds = reader.json("hdfs://hadoop:8020/data/users.parquet") ds.show() ds.registerTempTable("users") val userName = sqlContext.sql("select name from users") //对查询出来的dataSet 进行操作,处理打印 val userNameRDD = userName.javaRDD.map(line=>"name:"+line.getString(0)).collect import scala.collection.JavaConversions._ for (usernmae <- userNameRDD) { println(usernmae) } } }

3.自动分区推断

表分区是一种非常常见的优化方式,比如hive中就提供了表分区的特性,在一个分区表中,不同分区的数据通常存在不同的目录,分区列的值通常包含在分区目录名中。sparkSql中的parquet 支持自动更具目录名推断出分区信息。 如果将tableName 传入到SqlContext.read.parquet 或者SqlContext.read.load() 那么spark 会根据目录结构自动推断出分区信息。 此外 分区的数据类型也是自动被推断出来的。目前Spark Sql 仅支持自动推断出数字类型和字符类型,有时用户也许不希望SparkSql 自动判断分区列的数据类型,此时只需要设置一个配置即可,spark.sql.sources.partitionColumnTypeInference.enabled.默认为true,即自动推断分区类型,设置为false,不会推断。

下面给出java 示例:

public class ParquetDiscovery { public static void main(String[] args) { SparkConf conf=new SparkConf().setAppName("ParquetDiscovery"); JavaSparkContext sc=new JavaSparkContext(conf); SQLContext sqlContext=new SQLContext(sc); DataFrameReader reader=sqlContext.read(); Dataset ds= reader.json("hdfs://hadoop:8020/data/gender=male/country=us/users.parquet"); ds.printSchema(); ds.show(); sc.close(); } }

下面给出scala 示例:

object ParquetDiscovery { def main(args: Array[String]): Unit = { val conf = new SparkConf().setAppName("ParquetDiscovery") val sc = new SparkContext(conf) val sqlContext = new SQLContext(sc) val reader = sqlContext.read val ds = reader.json("hdfs://hadoop:8020/data/gender=male/country=us/users.parquet") ds.printSchema() ds.show() } }

4.合并元数据

parquet 支持合并元数据,用户可以在一开始的时候就定于一个简单的元数据,然后随着业务的发展逐渐的往元数据中添加更多的列,这种情况下用户,可能会创建多个partition 文件,有着不同但却互相兼容的元数据.parquet自动判断这种情况,并且进行多个文件的元数据合并。 因为合并元数据是一个比较耗时的操作大多情况下不太需要,所以默认是关闭的 可以通过如下的方式打开。 1.读取Parquet 将数据源选项,mergeSchema 设置为true. 2.使用SQlContext.setconf()将spark.sql.parquet.mergeSchema参数设置为true 下面给出scala 示例:

object ParquetMergeScaema { def main(args: Array[String]): Unit = { val conf = new SparkConf().setAppName("ParquetMergeScaema") val sc = new SparkContext(conf) val sqlContext = new SQLContext(sc) val reader = sqlContext.read //创建一个dataSet 作为学生信息 import sqlContext.implicits._ val studentWithNameAndAge=Array(("leo",20),("jack","25")).toSeq val studentWithNameAndAgeDF=sc.parallelize(studentWithNameAndAge,2).toDF("name","age"); studentWithNameAndAgeDF.write.save("hdfs://hadoop:8020/data/ParquetMergeScaemaTest1"); //再创建一个 val studentWithNameAndId=Array(("leo",20),("jack","25")).toSeq val studentWithNameAndIdDF=sc.parallelize(studentWithNameAndId,2).toDF("name","Id"); studentWithNameAndIdDF.write.save("hdfs://hadoop:8020/data/ParquetMergeScaemaTest2.json"); //合并两个dataset val student=sqlContext.read.option("mergeSchema","true").parquet("hdfs://hadoop:8020/data/ParquetMergeScaemaResult") student.printSchema() student.show() } }

欢迎关注,更多福利

转载请注明原文地址: https://www.6miu.com/read-2050166.html

最新回复(0)