在 R 中批量编写 Apache Arrow 数据集
Writing Apache Arrow dataset in batches in R
我想知道按 here 所述批量创建 Apache Arrow 多文件数据集的正确方法是什么。该教程很好地解释了如何从内存中的数据写入新的分区数据集,但是是否可以批量执行此操作?
我目前的做法是简单地将数据集单独写入,但写入同一目录。 似乎 可以正常工作,但我不得不想象这会导致支持该功能的元数据出现问题。本质上,我的逻辑如下(伪代码):
data_ids <- c(123, 234, 345, 456, 567)
# write data in batches
for (id in data_ids) {
## assume this is some complicated computation that returns 1,000,000 records
df <- data_load_helper(id)
df <- group_by(df, col_1, col_2, col_3)
arrow::write_dataset(df, "arrow_dataset/", format = 'arrow')
}
# read in data
dat <- arrow::open_dataset("arrow_dataset/", format="arrow", partitioning=c("col_1", "col_2", "col_3"))
# check some data
dat %>%
filter(col_1 == 123) %>%
collect()
正确的做法是什么?或者我的方法是否正确?将所有数据加载到一个对象中然后一次写入它是不可行的,并且某些数据块会随着时间的推移在不同时期更新。
TL;DR:您的解决方案看起来很合理。
您可能 运行 遇到一两个问题。首先,如果您的批次并非都具有相同的模式,那么您需要确保在打开数据集进行读取时传入 unify_schemas=TRUE
。这也可能会变得代价高昂,您可能只想单独保存统一架构。
certain chunks of the data will update at different periods over time.
如果“更新”是指“添加更多数据”,那么您可能需要提供 basename_template
。否则每次调用 write_dataset
都会尝试创建 part-0.arrow
并且它们会相互覆盖。解决此问题的常见做法是在 basename_template
.
中包含某种 UUID
如果“更新”是指“替换现有数据”,那么事情会有点棘手。如果你想替换整个分区的数据,你可以使用 existing_data_behavior="delete_matching"
。如果您想替换匹配的行,我不确定目前是否有很好的解决方案。
这种方法也可能导致小批量,具体取决于每个 data_id 中每个组中的数据量。例如,如果您有 100,000 个数据 ID,并且每个数据 ID 有 100 万条记录分布在 col_1/col_2/col_3 的 1,000 种组合中,那么您最终将得到 100 万个文件,每个文件有 1,000 行。这不会很好地执行。理想情况下,您希望最终得到 1,000 个文件,每个文件有 1,000,000 行。您或许可以通过某种偶尔的压缩步骤来解决这个问题。
我想知道按 here 所述批量创建 Apache Arrow 多文件数据集的正确方法是什么。该教程很好地解释了如何从内存中的数据写入新的分区数据集,但是是否可以批量执行此操作?
我目前的做法是简单地将数据集单独写入,但写入同一目录。 似乎 可以正常工作,但我不得不想象这会导致支持该功能的元数据出现问题。本质上,我的逻辑如下(伪代码):
data_ids <- c(123, 234, 345, 456, 567)
# write data in batches
for (id in data_ids) {
## assume this is some complicated computation that returns 1,000,000 records
df <- data_load_helper(id)
df <- group_by(df, col_1, col_2, col_3)
arrow::write_dataset(df, "arrow_dataset/", format = 'arrow')
}
# read in data
dat <- arrow::open_dataset("arrow_dataset/", format="arrow", partitioning=c("col_1", "col_2", "col_3"))
# check some data
dat %>%
filter(col_1 == 123) %>%
collect()
正确的做法是什么?或者我的方法是否正确?将所有数据加载到一个对象中然后一次写入它是不可行的,并且某些数据块会随着时间的推移在不同时期更新。
TL;DR:您的解决方案看起来很合理。
您可能 运行 遇到一两个问题。首先,如果您的批次并非都具有相同的模式,那么您需要确保在打开数据集进行读取时传入 unify_schemas=TRUE
。这也可能会变得代价高昂,您可能只想单独保存统一架构。
certain chunks of the data will update at different periods over time.
如果“更新”是指“添加更多数据”,那么您可能需要提供 basename_template
。否则每次调用 write_dataset
都会尝试创建 part-0.arrow
并且它们会相互覆盖。解决此问题的常见做法是在 basename_template
.
如果“更新”是指“替换现有数据”,那么事情会有点棘手。如果你想替换整个分区的数据,你可以使用 existing_data_behavior="delete_matching"
。如果您想替换匹配的行,我不确定目前是否有很好的解决方案。
这种方法也可能导致小批量,具体取决于每个 data_id 中每个组中的数据量。例如,如果您有 100,000 个数据 ID,并且每个数据 ID 有 100 万条记录分布在 col_1/col_2/col_3 的 1,000 种组合中,那么您最终将得到 100 万个文件,每个文件有 1,000 行。这不会很好地执行。理想情况下,您希望最终得到 1,000 个文件,每个文件有 1,000,000 行。您或许可以通过某种偶尔的压缩步骤来解决这个问题。