从spark以Map(String,List(String))列表/检索HDFS分区

时间:2019-06-27 19:17:18

标签: scala apache-spark hadoop hdfs

我想知道是否有某种方法可以利用Spark中hdfs文件夹结构中已经存在的元数据信息。例如,我正在使用以下代码将数据写入hdfs,

val columns = Seq("country","state")
dataframe1.write.partitionBy(columns:_*).mode("overwrite").
save(path)

这会生成相似的目录结构,

path/country=xyz/state=1
path/country=xyz/state=2
path/country=xyz/state=3
path/country=abc/state=4

我想知道的是使用spark,有没有一种方法可以推断所有分区和子分区为Map(String,List(String))(无需加载整个文件并使用group by?),其中关键是分区该值是该分区内所有子分区的列表。

以上示例的输出类似于以下内容

Map(xyz->List(1,2,3),abc->(4))

1 个答案:

答案 0 :(得分:3)

您的hdfs文件结构是这样的...

$tree path
path
├── country=abc
│   └── state=4
└── country=xyz
    ├── state=1
    ├── state=2
    ├── state=3
    ├── state=4
    ├── state=5
    └── state=6

您需要使用它来获取完整的路径作为字符串。

hive.s3.aws-secret-key

一旦获得具有所有文件完整路径(包括子文件夹)的listbuffer,就需要编写逻辑来填充 在地图上。我把它留给你。 TIY ..

注意:ListBuffer具有返回映射所依据的组,您可以使用它

就我而言,我做了这样的尝试...

val lb = new ListBuffer[String]
  def getAllFiles(path:String, sc: SparkContext):Unit = {
  val conf = sc.hadoopConfiguration
    val fs = FileSystem.get(conf)
    val files: RemoteIterator[LocatedFileStatus] = fs.listLocatedStatus(new Path(path))
    while(files.hasNext) {
      var filepath = files.next.getPath.toString
      //println(filepath)
      lb += (filepath)
      getAllFiles(filepath, sc)
    }
    println(lb)
  }

我得到的结果是

  println( lb.groupBy(_.toString.replaceAll("file:/Users/xxxxxx/path/country=", "")substring(0, 3) ))

也许您可以使用这个想法进一步完善您想要的结果。