我有两种情况,我有23 GB
分区parquet
数据并阅读columns
& caching
以后会提前发布一系列后续查询。
设置:
案例1 :
val paths = Array("s3://my/parquet/path", ...)
val parqFile = sqlContext.read.parquet(paths:_*)
parqFile.registerTempTable("productViewBase")
val dfMain = sqlContext.sql("select guid,email,eventKey,timestamp,pogId from productViewBase")
dfMain.cache.count
从SparkUI
开始,读取的输入数据为6.2 GB,缓存的对象为 15.1 GB 。
案例1 :
val paths = Array("s3://my/parquet/path", ...)
val parqFile = sqlContext.read.parquet(paths:_*)
parqFile.registerTempTable("productViewBase")
val dfMain = sqlContext.sql("select guid,email,eventKey,timestamp,pogId from productViewBase order by pogId")
dfMain.cache.count
从SparkUI
开始,读取的输入数据为6.2 GB,缓存的对象为 5.5 GB 。
对此行为的任何解释或代码引用?
答案 0 :(得分:2)
实际上相对简单。正如您可以在SQL指南中阅读的那样:
Spark SQL可以使用内存中的列式格式来缓存表格... Spark SQL将只扫描所需的列并自动调整压缩
有关排序柱状存储的好处是它可以很容易地压缩典型数据。当你排序时,你会得到类似记录的这些块,这些块可以使用RLE等非常简单的技术压缩在一起。
这是一个实际上在具有列式存储的数据库中经常使用的属性,因为它不仅在存储方面非常有效,而且在聚合方面也非常有效。
sql.execution.columnar.compression
包涵盖了Spark柱状压缩的不同方面,您可以看到RunLengthEncoding
确实是可用的压缩方案之一。
所以这里有两件作品:
Spark可以调整压缩method on the fly based on the statistics:
Spark SQL将根据数据统计信息自动为每列选择压缩编解码器。
排序可以将类似的记录聚集在一起,从而提高压缩效率。
如果列之间存在一些相关性(当不是这种情况时?),即使基于单个列的简单排序也会产生相对较大的影响并提高不同压缩方案的性能。