当前位置:首页 > Rust > 正文

Rust高效处理列式存储:Apache Parquet库入门指南(手把手教你用Rust读写Parquet文件)

在大数据和数据分析领域,Apache Parquet 是一种非常流行的列式存储格式。它具有高压缩率、高效查询能力以及良好的跨语言兼容性。而 Rust 作为一种内存安全、高性能的系统编程语言,正越来越多地被用于数据处理任务。

本文将带你从零开始,使用 Rust 的 parquet 官方库(由 Apache 提供)来读取和写入 Parquet 文件。即使你是 Rust 新手,也能轻松上手!

Rust高效处理列式存储:Apache Parquet库入门指南(手把手教你用Rust读写Parquet文件) Rust Parquet  Apache Rust读取Parquet Rust写入Parquet文件 第1张

什么是 Parquet?

Apache Parquet 是一种开源的列式存储格式,专为高效的数据分析而设计。与传统的行式存储(如 CSV)不同,Parquet 将同一列的数据连续存储,这使得:

  • 压缩效率更高(同一列数据类型相同,更容易压缩)
  • 查询更快(只需读取需要的列,跳过无关数据)
  • 支持复杂嵌套数据结构

准备工作:添加依赖

首先,你需要在你的 Rust 项目中添加 parquet 库。打开 Cargo.toml 文件,添加以下依赖:

[dependencies]parquet = "50.0"tokio = { version = "1", features = ["full"] }  # 可选,用于异步示例

注意:截至 2024 年,parquet crate 的最新主版本是 50.x,由 Apache 官方维护。

第一步:用 Rust 写入 Parquet 文件

我们将创建一个简单的用户数据结构,并将其写入 Parquet 文件。

use parquet::file::writer::FileWriter;use parquet::schema::parser::parse_message_type;use parquet::column::writer::ColumnWriter;use parquet::file::properties::WriterProperties;use std::fs::File;use std::sync::Arc;fn main() -> Result<(), Box> {    // 定义 Parquet 的 Schema(使用 Parquet 的 Schema 语言)    let schema_str = "message user {        optional int32 id;        optional binary name (UTF8);        optional boolean is_active;    }";    let schema = Arc::new(parse_message_type(schema_str)?);    let props = WriterProperties::builder().build();    let file = File::create("users.parquet")?;    let mut writer = FileWriter::new(file, schema.clone(), props);    // 准备数据    let ids = vec![1, 2, 3];    let names = vec!["Alice", "Bob", "Charlie"];    let active = vec![true, false, true];    // 获取行组写入器    let mut row_group_writer = writer.next_row_group()?;    // 写入 id 列    if let Some(mut col_writer) = row_group_writer.next_column()? {        col_writer.typed::()            .write_batch(&ids, None, None)?;        row_group_writer.close_column(col_writer)?;    }    // 写入 name 列    if let Some(mut col_writer) = row_group_writer.next_column()? {        let name_bytes: Vec> = names.iter()            .map(|s| s.as_bytes().to_vec())            .collect();        col_writer.typed::()            .write_batch(&name_bytes, None, None)?;        row_group_writer.close_column(col_writer)?;    }    // 写入 is_active 列    if let Some(mut col_writer) = row_group_writer.next_column()? {        col_writer.typed::()            .write_batch(&active, None, None)?;        row_group_writer.close_column(col_writer)?;    }    writer.close_row_group(row_group_writer)?;    writer.close()?;    println!("✅ Parquet 文件已成功写入 users.parquet");    Ok(())}

这段代码展示了如何使用底层 API 手动构建 Parquet 文件。虽然稍显繁琐,但它让你完全掌控写入过程。

第二步:用 Rust 读取 Parquet 文件

现在我们来读取刚刚生成的 users.parquet 文件:

use parquet::file::reader::FileReader;use parquet::file::serialized_reader::SerializedFileReader;use std::fs::File;fn main() -> Result<(), Box> {    let file = File::open("users.parquet")?;    let reader = SerializedFileReader::new(file)?;    let mut iter = reader.get_row_iter(None)?;    println!("读取 Parquet 数据:");    for record in iter {        let record = record?;        let id = record.get_int(0).unwrap_or(0);        let name = record.get_string(1).unwrap_or_else(|| "".to_string());        let is_active = record.get_bool(2).unwrap_or(false);        println!("ID: {}, Name: {}, Active: {}", id, name, is_active);    }    Ok(())}

运行后,你将看到类似以下的输出:

ID: 1, Name: Alice, Active: trueID: 2, Name: Bob, Active: falseID: 3, Name: Charlie, Active: true  

更简单的方式:使用 Arrow + Parquet(推荐)

如果你正在处理大量数据或希望与 DataFrame 工具(如 Polars 或 DataFusion)集成,建议使用 Apache Arrow 作为中间层。Arrow 提供了内存中的列式数据格式,与 Parquet 天然契合。

添加依赖:

[dependencies]arrow = "50.0"parquet = { version = "50.0", features = ["arrow"] }

这样你就可以使用 arrow::record_batch::RecordBatchparquet::arrow 模块进行更简洁的读写操作。

常见问题与最佳实践

  • Schema 设计:尽量使用 optional 字段以避免空值问题。
  • 压缩:Parquet 支持 Snappy、Gzip 等压缩算法,可在 WriterProperties 中配置。
  • 性能:批量写入比逐行写入快得多。
  • 错误处理:始终使用 Result 类型处理 I/O 和解析错误。

总结

通过本教程,你已经学会了如何在 Rust 中使用 Apache Parquet 库 来读写 Parquet 文件。无论你是构建数据管道、ETL 工具,还是高性能分析引擎,掌握 Rust Parquet 操作都是关键技能。

记住我们的核心 SEO 关键词

  • Rust Parquet
  • Apache Parquet Rust
  • Rust读取Parquet
  • Rust写入Parquet文件
这些关键词涵盖了你在搜索相关技术时最可能使用的术语。

现在,你可以自信地在你的 Rust 项目中集成 Parquet 支持了!🚀