首页 文章

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

提问于
浏览
2

我对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 回答

  • 2

    我现在已经找到了一些方法,但还没有对它们进行性能测试,请注意:

    首先,我们需要创建一个派生的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")
    

相关问题