在Spark中按时间戳分区Parquet文件的最佳做法是什么?

时间:2015-07-17 10:03:54

标签: apache-spark pyspark

我对Spark很新(2天),我正在考虑分割镶木地板文件的最佳方法。

我的粗略计划ATM是:

  • 使用com.databricks.spark.csv读取源TSV文件(这些文件具有TimeStampType列)
  • 写出镶木地板文件,按年/月/日/小时划分
  • 将这些镶木地板文件用于将来会发生的所有查询

对于简单的版本工作来说,这很荒谬(对Spark开发人员来说很荣幸) - 除了按照我喜欢的方式进行分区。这是在python BTW:

input = sqlContext.read.format('com.databricks.spark.csv').load(source, schema=myschema)
input.write.partitionBy('type').format("parquet").save(dest, mode="append")

是映射RDD的最佳方法,添加年,月,日,小时的新列,然后使用PartitionBy?那么对于任何查询,我们必须手动添加年/月等?鉴于到目前为止我发现了多么优雅的火花,这看起来有点奇怪。

由于

1 个答案:

答案 0 :(得分:3)

我现在找到了一些方法可以做到这一点,还没有对它们进行性能测试,请注意:

首先,我们需要创建一个派生的DataFrame(下面显示的三种方式),然后将其写出来。

1)sql查询(内联函数)

sqlContext.registerFunction("day",lambda f: f.day, IntegerType())
input.registerTempTable("input")
input_ts = sqlContext.sql(
  "select day(inserted_at) AS inserted_at_day, * from input")

2)sql查询(非内联) - 非常相似

def day(ts):
  return f.day
sqlContext.registerFunction("day",day, IntegerType())
... rest as before

3)withColumn

from pyspark.sql.functions import udf
day = udf(lambda f: f.day, IntegerType())
input_ts = input.withColumn('inserted_at_day',day(input.inserted_at))

写出来:

input_ts.write.partitionBy(['inserted_at_day']).format("parquet").save(dest, mode="append")