spark - 如何读取和写入多个子文件夹

时间:2018-04-05 21:38:13

标签: java scala apache-spark hadoop bigdata

在/ mypath / orc / path下,我有几个不同日期的子文件夹: 即

/mypath/orc/mydate=20170817/part1.orc
/mypath/orc/mydate=20170817/part2.orc
/mypath/orc/mydate=20170820/part1.orc
/mypath/orc/mydate=20170820/part2.orc
/mypath/orc/mydate=20170821/part1.orc
/mypath/orc/mydate=20170821/part2.orc

我想要的输出与此类似(文件的实际名称并不重要):

/mypath/parquet/mydate=20170817/part1and2together.parquet
/mypath/parquet/mydate=20170820/part1and2together.parquet
/mypath/parquet/mydate=20170821/part1and2together.parquet

我一直在尝试下面的内容,我可以在每个日期硬编码过滤器并调用3次,但如果我有1000个日期,它会运行很长时间。我在代码中缺少什么,以便一次性将多个日期输入处理为多个日期输出?

./spark-shell 
val orcfile = "hdfs:///mypath/orc/*/*.orc*"
val df = spark.read.format("orc").load(orcfile) 
df.createOrReplaceTempView("MYTBL") 
val results = spark.sql("SELECT * FROM MYTBL")
results.write.mode("Overwrite").format("parquet").save("hdfs:///mypath/parquet/")

ENV:

  1. 独立模式下的Spark 2.3.0
  2. Hadoop 2.8.3
  3. EC2群集 - 1个拥有64个CPU,256GB RAM和5个工作者的主人(每个拥有64个CPU,256GB RAM)
  4. 很长一段时间是“几天到几周”,理想情况下它会在不到一天的时间内运行。

1 个答案:

答案 0 :(得分:0)

我猜为partitionBy(“ myDate”)ala:

http://javaagile.blogspot.com/2017/12/parquet-vs-avro-vs-orc.html

此处分区如下:

  spark.read
    .option("header", "true")
    .option("inferSchema", "true")
    .csv("IN_FILE").sort(partitionBy)
    .write.partitionBy("STREET").mode(SaveMode.Overwrite)
    .parquet("OUT_PARTITIONED")

产生如下目录结构:

$ hadoop fs -ls OUT_PARTITIONED.parquet |头 共找到69415项 drwxrwxr-x-用户用户0 2017-11-23 09:16 OUT_PARTITIONED.parquet / STREET =%22%22%22Glück-auf%22%22-Straße%22 drwxrwxr-x-用户用户0 2017-11-23 09:16 OUT_PARTITIONED.parquet / STREET =%22Kellergasse%22%22Moorberg%22%22%22 drwxrwxr-x-用户user 0 2017-11-23 09:16 OUT_PARTITIONED.parquet / STREET = 0Montangebiet drwxrwxr-x-用户用户0 2017-11-23 09:16 OUT_PARTITIONED.parquet / STREET = 0塔高

在这种情况下,我有街道数据。请注意,由于我在STREET上进行分区,所以现在每条街道都有自己的目录。

当您要加入分区时,这很方便,但请注意不要在Hadoop NameNode中创建太多条目。

如果使用Orc,也会得到类似的区别,即: