一. 概论
Presto对ORC和Parquet格式存储的Hive表的处理很为友好,Presto访问这两种格式表时进行了大量的优化,以致得到很为优越的性能。 Presto在读取文件上和Spark等其他数据处理引擎组件最为与众不同是Presto读取ORC/Parquet格式表并没有采用传统的MR方式,而是采用了自己读取和切分和转换文件的方式。这样很容易实现自己控制多worker多并发读取,多pipeline同时加工,也能很容易进行列裁剪分区裁剪等读取优化,可以有效避免读取数据成为数据处理的性能瓶颈。
本文主要介绍了在Presto读取Parquet文件的流程以及介绍在Presto中是如何一步步将Parquet文件组装成自己数据加工处理的数据结构Page的。
二. Presto读取Parquet文件的总体流程
三. Presto处理Parquet文件的代码走读
ParquetPageSource
getNextPage
blocks[fieldId] = new LazyBlock(batchSize, new ParquetBlockLoader(field.get()));
ParquetBlockLoader::load
parquetReader.readBlock(field)
columnChunk = readPrimitive((PrimitiveField) field) //对于以下嵌套的数据格式处理过程会更加复杂
columnReader.readPrimitive(field);
readNextPage();
valuesReader = readPageV1((DataPageV1) page); //这里利用了Parquet的接口读取Parquet的原生数据
readValues(...);
readValue(blockBuilder, type)
根据列的类型选择对应的BinaryColumnReader/BinaryColumnReader/DoubleColumnReader/FloatColumnReader将parquet类型转换成presto类型的适配器,以string类型的适配器BinaryColumnReader为例:
BinaryColumnReader.readValue
type.writeSlice(blockBuilder, value)
CharType::writeSlice
blockBuilder.writeBytes //至此,数据已经从parquet读出来并且转成成了presto类型,并且填充到了block了
return new Page(batchSize, blocks) // Page此刻已经组装完成,presto会将其add到下游的Operation进行处理