我处于类似于the one mentioned here的情况。问题没有得到满意的答复。此外,我处理的数据较少(每天大约1G)。
我的情况:我有一定数量的数据(~500G)已经可以作为实木复合地板(这是商定的“存储格式”),我得到定期的增量更新。我希望之后能够处理ETL部分以及分析部分。
为了能够有效地生成某些“中间数据产品”的更新,我看到三个选项:
require(data.table)
require(dplyr)
# Example 1
fn <- function(x) substitute_c(x)
fn2 <- function(y) fn(substitute_c(y))
fn3 <- function(z) fn2(substitute_c(z))
fn(quote(a + b)
fn(a + b)
fn2(a + b)
fn3(quote(a + b))
# Example 2
dtcars <- mtcars %>% as.data.table
subset_test <- function(dt, cols) {
cols <- substitute_c(cols)
dt[, eval(cols)]
}
subset_test2 <- function(dt, cols) {
cols <- substitute_c(cols)
subset_test(dt, cols)
}
subset_test(dtcars, .(mpg, cyl))
subset_test(dtcars, list(mpg, cyl))
subset_test2(dtcars, .(mpg, cyl))
subset_test2(dtcars, list(mpg, cyl))
将每个更新保存到单独的文件夹,例如:
upload_timestamp
这样就可以使用data
+- part_001
| +- various_files.parquet
+- part_002
| +- various_files.parquet
+- ...
作为data/*
的路径来阅读整个数据集。
我正在倾向于最后一种方法,也因为有评论(证据?),当分区数量增加时,追加模式会导致问题(例如参见this SO question)。
所以我的问题:创建像这样的数据集结构有一些严重的缺点吗?显然,Spark在阅读多个文件夹时需要进行“一些”合并/排序,但除此之外?
我正在使用Spark 2.1.0。
答案 0 :(得分:0)
这正是您在第三个选项中描述的内容。
这样做可以显着提高性能,因为在主数据集上执行的功能只能访问与计算相关的数据。这使得批量查询和服务层中的索引创建速度更快。文件夹的名称取决于您,但通常涉及时间戳组件。
无论您是否构建Lambda架构,垂直分区都将使您的分析更加高效。
答案 1 :(得分:0)
我注意到目录中的文件夹数量越多,spark.read
执行的时间就越长,因为spark会对数据/元数据进行采样以找出架构。但这可能是你必须要处理的必然性。
如果您添加upload-timestamp
甚至更好upload-date-hour
并通过它进行分区,它自然会写入该文件夹。如果有可能在给定的小时内有多组文件,请确保通过api访问写入,确保在写入之前对现有数据执行union
。