一、Parquet简介
1、what
Parquet是面向分析型业务的列式存储格式,由Twitter和Cloudera合作开发
2、why
列式存储和行式存储相比的优势:
- 可以跳过不符合条件的数据,只读取需要的数据,降低IO数据量
- 压缩源码可以降低磁盘存储空间。
由于同一列的数据类型是一样的,可以使用更高效的压缩编码(比如Run Length Encoding 和 Delta Encoding)进一步节约存储空间 - 只读取需要的列,进行向量运算,能够获取更好的扫描性能
二、Parquet使用
- Java版
/**
* Parquet数据源---使用编程方式加载数据
*/
public class ParquetLoadData {
public static void main(String[] args) {
SparkConf conf = new SparkConf().setAppName("ParquetLoadData").setMaster("local");
JavaSparkContext sc = new JavaSparkContext(conf);
SQLContext sqlContext = new SQLContext(sc);
//读取Parquet文件中的数据,创建一个DataFrame
Dataset<Row> usersDF = sqlContext.read().parquet("./student.parquet");
//将DataFrame注册为临时表,然后使用SQL查询需要的数据
usersDF.registerTempTable("students");
Dataset<Row> userNamesDF = sqlContext.sql("select name from users");
List<String> userNames = userNamesDF.javaRDD().map(new Function<Row, String>() {
@Override
public String call(Row row) throws Exception {
return "Name: " + row.getString(0);
}
}).collect();
for (String userName:userNames) {
System.out.println(userName);
}
}
}
- scala版
object ParquetLoadData_scala {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("Accumulator_scala").setMaster("local")
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)
val usersDF = sqlContext.read.parquet("./student.parquet")
usersDF.registerTempTable("students");
val userNamesDF = sqlContext.sql("select name from users")
userNamesDF.rdd.map(row => "Name: " + row(0))
.collect().foreach(userName => println(userName))
}
}