Parquet数据存储格式的一大好处是它是列式的。如果我有一个包含数百列的“宽”数据集,但我的查询只触及其中的几列,那么可以只读取存储这几列的数据,而跳过其余的。
这个特性的工作原理大概是读取parque文件头部的一些元数据,这些元数据指示文件系统中每一列的位置。然后,读者可以在磁盘上查找以仅读取必要的列。
有人知道火花的默认拼花阅读器是否正确地在S3上实现了这种选择性搜索吗?我认为它得到了S3的支持,但是理论支持和正确利用这种支持的实现之间有很大的区别。
这需要被分解
FileSystem
seek()
read()
或readFully(位置、缓冲区、长度)
调用?是的火花. hadoop.fs.s3a.实验.finfo=随机
来触发随机访问。Hadoop 2.7和更早版本处理文件的激进seek()处理得很糟糕,因为它们总是启动GET偏移量文件结束,对下一个seek感到惊讶,不得不中止该连接,重新打开一个新的TCP/HTTPS 1.1连接(缓慢,CPU重),重复执行。随机IO操作在批量加载. csv.gz之类的东西时会受到伤害,但对于获得ORC/Parquetperf至关重要。
你没有得到Hadoop 2.7的hadoop-aws JAR的加速。如果你需要它,你需要更新hadoop*。jar和依赖项,或者根据Hadoop 2.8从头开始构建Spark
请注意,Hadoop 2.8还有一个不错的小功能:如果您在日志语句中调用S3A文件系统客户端上的toString()
,它会打印出所有文件系统IO统计信息,包括在查找中丢弃了多少数据,中止了TCP连接
2018-04-13警告:: 不要试图将Hadoop 2.8hadoop-aws
JAR与hadoop-2.7 JAR集的其余部分一起放在类路径上,并期望看到任何加速。您将看到的只是堆栈跟踪。您需要更新所有hadoop JAR及其传递依赖项。
免责声明:我没有一个明确的答案,也不想作为一个权威的来源,但是我花了一些时间在Spark 2.2的镶木地板支持上,我希望我的答案能帮助我们所有人更接近正确的答案。
S3上的Parquet是否避免从S3中提取未使用列的数据,只检索它需要的文件块,还是提取整个文件?
我使用我今天从大师那里构建的Spark 2.3.0-SNAPSHOT。
数据源格式由ParquetFileFormat处理,ParquetFileFormat是一个FileFormat。
如果我是正确的,则读取部分由buildReaderWellParttionValue方法处理(该方法覆盖FileFormat
的)。
当FileSourceScanExec物理运算符被请求用于所谓的输入RDD时,将独占使用buildReaderWellPartionValue
,这些输入RDD实际上是在执行WholeStageCodegenExec时生成内部行的单个RDD。
话虽如此,但我认为回顾buildReaderWellPartionValue
所做的事情可能会让我们更接近最终答案。
当你看到这条线时,你可以确信我们走在正确的轨道上。
//启用过滤器下推时尝试下推过滤器。
该代码路径取决于默认打开的火花. sql.parque.filterPushdown
Spark属性。
当设置为true时,启用Parquet过滤器下推优化。
这将我们引向parquet-hadoop的ParquetInputFormat. setFilterPredicate,如果定义了过滤器。
if (pushed.isDefined) {
ParquetInputFormat.setFilterPredicate(hadoopAttemptContext.getConfiguration, pushed.get)
}
稍后,当代码回退到parquet-mr时使用过滤器时,代码会变得更有趣(而不是使用所谓的矢量化parquet-mr解码阅读器)。这是我真正不理解的部分(除了我在代码中看到的)。
请注意,矢量化拼花解码阅读器由默认打开的park. sql.parque.enableVectorizedReader
Spark属性控制。
TIP:要知道if
表达式的哪一部分被使用,请为org. apache.park.sql.执行.datassource.parque.ParquetFileFormat
记录器启用DEBUG
日志级别。
为了查看所有下推过滤器,您可以打开org. apache.火花.sql.执行.FileSourceScanExec
日志级别的INFO
日志。您应该在日志中看到以下内容:
INFO Pushed Filters: [pushedDownFilters]
我真的希望,如果它不是一个明确的答案,它会有一点帮助,有人会从我停下来的地方开始,很快就会有一个。希望最后死去:)
火花的镶木地板阅读器就像任何其他输入格式一样,
>
没有任何输入格式对S3有任何特殊之处。输入格式可以从LocalFileSystem、Hdfs和S3读取,没有为此进行特殊优化。
ParquetInpuTFormat(取决于您询问的列)将有选择地为您读取列。
如果你想非常确定(尽管下推谓词在最新的火花版本中有效),手动选择列并编写转换和操作,而不是依赖于SQL