我的 C++ 应用程序基本上有面向行的/流数据 (Netflow),我想将数据写入 Parquet-gzip 文件。
查看parquet-cpp项目中的示例reader-writer.cc程序,看来我只能以柱状方式将数据喂给parquet-cpp:
constexpr int NUM_ROWS_PER_ROW_GROUP = 500;
...
// Append a RowGroup with a specific number of rows.
parquet::RowGroupWriter* rg_writer = file_writer->AppendRowGroup(NUM_ROWS_PER_ROW_GROUP);
// Write the Bool column
for (int i = 0; i < NUM_ROWS_PER_ROW_GROUP; i++) {
bool_writer->WriteBatch(1, nullptr, nullptr, &value);
}
// Write the Int32 column
...
// Write the ... column
Run Code Online (Sandbox Code Playgroud)
这似乎意味着我需要自己缓冲 NUM_ROWS_PER_ROW_GROUP 行,然后循环遍历它们,将它们一次传输到 parquet-cpp 一列。我希望有更好的方法,因为这似乎效率低下,因为数据需要复制两次:一次进入我的缓冲区,然后在一次将数据输入 parquet-cpp 一列时再次复制。
有没有办法将每一行的数据放入 parquet-cpp 而不必先缓冲一堆行?Apache Arrow 项目(parquet-cpp 使用)有一个教程,展示了如何将行数据转换为 Arrow 表。对于每一行输入数据,代码附加到每个列构建器:
for (const data_row& row : rows) {
ARROW_RETURN_NOT_OK(id_builder.Append(row.id));
ARROW_RETURN_NOT_OK(cost_builder.Append(row.cost));
Run Code Online (Sandbox Code Playgroud)
我想用 parquet-cpp 做类似的事情。那可能吗?
您将永远无法完全没有缓冲,因为我们需要从行式表示转换为列式表示。在撰写本文时,最好的方法是构建 Apache Arrow 表,然后将这些表送入parquet-cpp
.
parquet-cpp
提供了特殊的 Arrow API,然后可以直接对这些表进行操作,大多数情况下不需要任何额外的数据副本。您可以在parquet/arrow/reader.h
和 中找到 API parquet/arrow/writer.h
。
最佳但尚未实施的解决方案可以通过执行以下操作来节省一些字节:
虽然这个最佳解决方案可能会为您节省一些内存,但仍有一些步骤需要有人来实现(请随意贡献它们或寻求帮助来实现这些),您可能很擅长使用基于 Apache Arrow 的 API。
归档时间: |
|
查看次数: |
3390 次 |
最近记录: |