37 个版本
0.17.2 | 2023年4月13日 |
---|---|
0.17.1 | 2022年12月12日 |
0.17.0 | 2022年11月30日 |
0.14.2 | 2022年7月26日 |
0.1.0 | 2021年7月20日 |
#118 在 解析器实现
19,836 每月下载量
用于 31 个crate(6 个直接使用)
440KB
11K SLoC
Parquet2
这是一个以性能、并行性和安全性为重点,对官方parquet
crate的重写。
查看指南了解如何使用此crate读取parquet。
与parquet
相比,五个主要的不同之处在于
- 它使用
#![forbid(unsafe_code)]
- 将并行性委托给下游
- 将读取(I/O密集型)与计算(CPU密集型)解耦
- 它更快(读取到arrow格式时快10-20倍)
- 支持异步读写。
- 它已与pyarrow和(py)spark 3集成测试
总体思想是提供读取压缩的parquet页面的能力,以及将它们解压缩到喜欢的内存格式的工具包。
这允许此crate的迭代器执行最小的CPU工作,从而最大化吞吐量。消费者是否想要通过牺牲内存使用来利用并行性(例如,在线程中解压缩和反序列化页面)由他们自己决定。
此crate不能直接用于读取parquet(除了元数据)。要从parquet读取数据,请查看arrow2。
已实现的功能
- 读取字典页面
- 读取和写入V1页面
- 读取和写入V2页面
- 压缩和解压缩(全部)
尚未实现的功能
Parquet格式针对不同的物理类型有多种编码策略。此crate目前几乎支持从所有这些类型中读取,并支持将它们编码到子集。它们是
支持的解码
Delta编码仍然是实验性的,因为我无法从spark生成使用它们的编码的大页面,这阻碍了鲁棒性集成测试。
编码
组织
read
:读取元数据和页面write
:写入元数据和页面encoding
:不同parquet编码的编码器和解码器page
:页面声明metadata
:parquet文件元数据(例如FileMetaData
)schema
:类型元数据声明(例如ConvertedType
)types.rs
:物理类型声明(即如何在内存中表示)。statistics
:反序列化表示的parquet页面compression
:压缩和解压缩器压缩(例如Gzip)error
:错误声明
运行集成测试
有针对由pyarrow生成的parquet文件的集成测试。要运行,您需要先运行以下命令:
python3 -m venv venv
venv/bin/pip install pip --upgrade
venv/bin/pip install pyarrow==7
venv/bin/python tests/write_pyarrow.py
cargo test
。这只需要一次(每次更改tests/write_pyarrow.py
)。
如何实现页面读取器
用于消耗parquet页面的内存中格式强烈影响了页面应该如何反序列化。因此,此crate不承诺特定的内存格式。消费者负责将页面转换为他们的目标内存格式。
此git仓库包含一个序列化到简单内存格式的示例,在integration
中使用,用于验证与其他实现一起的集成。
还有对arrow格式的实现,请在此处查看这里。
更高的并行度
通常,将页面转换为内存是昂贵的,因此考虑如何将工作分配到线程。例如:
let handles = vec![];
for column in columns {
let column_meta = metadata.row_groups[row_group].column(column);
let compressed_pages = get_page_iterator(column_meta, &mut file, file)?.collect()?;
// each compressed_page has a buffer; cloning is expensive(!). We move it so that the memory
// is released at the end of the processing.
handles.push(thread::spawn move {
page_iter_to_array(compressed_pages.into_iter())
})
}
let columns_from_all_groups = handles.join_all();
这将在主线程中以尽可能快的速度读取文件,并将CPU密集型工作发送到其他线程,从而最大化IO读取(以在内存中存储多个压缩页面为代价;这里也可以选择缓冲)。
解码流
通常,以以下方式读取parquet文件:
- 读取元数据
- 查找行组和列
- 遍历(压缩)页面
这是IO密集型,需要解析thrift,并在文件中进行查找。
一旦压缩页面被加载到内存中,它就可以被解压缩、解码并反序列化为特定的内存格式。所有这些操作都是CPU密集型的,因此留给消费者执行,因为消费者可能希望将此工作发送到线程。
读取->压缩页面->解压缩页面->解码字节->反序列化
许可证
根据Apache License,Version 2.0或MIT许可证许可。
- Apache License, Version 2.0 (LICENSE-APACHE或https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT许可证 (LICENSE-MIT或http://opensource.org/licenses/MIT)
您可以选择。
贡献
除非您明确声明,否则任何有意提交给作品以包括在内的贡献,如Apache-2.0许可证所定义,将根据上述许可证双许可,没有额外的条款或条件。
依赖关系
~12MB
~364K SLoC