使用Arrow Dataset C++读取Parquet文件时遇std::bad_alloc错误求助
问题解决:C++读取大Parquet文件子集的内存错误与替代方案
一、std::bad_alloc错误排查与解决
你遇到的std::bad_alloc大概率和dict_columns的默认行为有关。默认情况下,ParquetFileFormat的reader_options会尝试预加载所有字典列的完整字典,如果你的10GB Parquet里有大量高基数的字典列,这会瞬间占用巨量内存,直接触发内存分配失败。
解决步骤:
- 显式指定需要加载的字典列,避免默认加载全部:
// 初始化format时指定仅加载目标字典列 auto format = std::make_shared<ParquetFileFormat>(); format->reader_options.dict_columns = {"目标字典列1", "目标字典列2"};
- 如果不需要字典解码,直接禁用字典加载:
format->reader_options.use_dictionary = false;
- 补全FileSystem初始化:你当前代码中
fs是空指针,这会导致内部逻辑异常,需先初始化本地文件系统:
std::shared_ptr<FileSystem> fs = LocalFileSystem::Make();
- 限制扫描范围,减少元数据加载压力:
ds::FileSystemFactoryOptions options; // 仅扫描目录下的.parquet文件,避免无关文件干扰 options.file_extension_whitelist = {".parquet"};
二、不使用Arrow Dataset的替代方案
如果不想依赖Arrow Dataset,直接用Parquet C++ API实现过滤扫描也能达到目的,核心是通过列投影和行过滤只加载必要数据:
方案1:直接使用Parquet Reader API做精准过滤
#include <parquet/arrow/reader.h> #include <parquet/filter.h> // 打开目标Parquet文件 std::unique_ptr<parquet::arrow::FileReader> reader; PARQUET_THROW_NOT_OK(parquet::arrow::OpenFile("C:/parquet_data/your_file.parquet", fs, &reader)); // 设置列投影:仅读取需要的列(用列索引指定) std::vector<int> column_indices = {0, 2, 3}; // 替换为你的目标列索引 PARQUET_THROW_NOT_OK(reader->SetColumnIndices(column_indices)); // 设置行过滤条件:例如过滤某列值大于100的行 auto filter = parquet::Filter::Gt("target_column", 100); // 替换为你的过滤规则 PARQUET_THROW_NOT_OK(reader->SetFilter(filter)); // 读取过滤后的数据到Arrow Table std::shared_ptr<arrow::Table> table; PARQUET_THROW_NOT_OK(reader->ReadTable(&table));
方案2:分块读取行组,逐块处理
如果文件过大,单次读取内存压力仍高,可以按行组分块读取,逐块过滤处理:
int num_row_groups = reader->num_row_groups(); for (int i = 0; i < num_row_groups; ++i) { std::shared_ptr<arrow::Table> chunk; // 读取单个行组数据 PARQUET_THROW_NOT_OK(reader->ReadRowGroup(i, &chunk)); // 对当前行组应用过滤逻辑(使用Arrow Compute API) auto filtered_chunk = arrow::compute::Filter( chunk, arrow::compute::Greater(chunk->GetColumnByName("target_column"), arrow::Scalar(100)) ).ValueOrDie(); // 处理过滤后的chunk(如写入结果文件、计算统计值等) }
这种方式内存占用可控,每次仅处理一个行组的数据,适合超大型Parquet文件。
内容的提问来源于stack exchange,提问作者what_is_ads
相关产品推荐
相关产品推荐

