将数据添加到存储在磁盘上的Spark / Parquet数据

时间:2017-04-10 20:35:34

标签: apache-spark pyspark apache-spark-sql parquet pyspark-sql

我处于类似于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。

2 个答案:

答案 0 :(得分:0)

前任Twitter和Lambda Architecture作者的Nathan Marz描述了用于在批处理层中存储数据的垂直分区的过程,这是真实的来源并包含所有数据这座建筑曾见过。此主数据集是不可变的并且仅附加。垂直分区只是一个奇特的名称,用于将数据分类到单独的文件夹中。

这正是您在第三个选项中描述的内容。

这样做可以显着提高性能,因为在主数据集上执行的功能只能访问与计算相关的数据。这使得批量查询和服务层中的索引创建速度更快。文件夹的名称取决于您,但通常涉及时间戳组件。

无论您是否构建Lambda架构,垂直分区都将使您的分析更加高效。

答案 1 :(得分:0)

我注意到目录中的文件夹数量越多,spark.read执行的时间就越长,因为spark会对数据/元数据进行采样以找出架构。但这可能是你必须要处理的必然性。

如果您添加upload-timestamp甚至更好upload-date-hour并通过它进行分区,它自然会写入该文件夹。如果有可能在给定的小时内有多组文件,请确保通过api访问写入,确保在写入之前对现有数据执行union