Spark - 如何重组HDFS中的目录

时间:2018-03-08 18:33:46

标签: hadoop apache-spark hdfs

我的目录结构如下:

temp/Tweets/userId123/Tweets.csv
temp/Tweets/userId456/Tweets.csv
temp/Tweets/userId789/Tweets.csv

temp/Mentions/userId123/Mentions.csv
temp/Mentions/userId456/Mentions.csv
temp/Mentions/userId789/Mentions.csv

.
.
.

数据由数据实体的类型构成,我想由用户对其进行重组,如下所示:

final/userId123/Tweets.csv
final/userId123/Mentions.csv
.
.

final/userId456/Tweets.csv
final/userId456/Mentions.csv
.
.

我一直在浏览google / StackOverflow / Spark文档,但还没有看到这样做的方法,但我认为应该有一种方法来修改目录结构。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

您可以使用Scala的hadoop.fs.FileSystem API(或Python或Java - 这里我将使用Scala):

import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.{FileSystem, Path}

首先,让我们定义一种列出userids hdfs文件夹的方法:

def listFolderNamesInFolder(hdfsPath: String): List[String] =
  FileSystem
    .get(new Configuration())
    .listStatus(new Path(hdfsPath))
    .flatMap(status => if (!status.isFile) Some(status.getPath.getName) else None)
    .toList

然后让我们定义两个帮助程序来移动hdfs文件并创建hdfs文件夹:

def moveFile(oldPath: String, newPath: String): Unit = {
  val fileSystem = FileSystem.get(new Configuration())
  fileSystem.rename(new Path(oldPath), new Path(newPath))
}

def createFolder(hdfsPath: String): Unit =
  FileSystem.get(new Configuration()).mkdirs(new Path(hdfsPath))

最后,让我们遍历每个userid文件夹,并将每个推文,提及文件移动到相关的最终文件夹:

def moveTweetFiles(hdfsPath: String): Unit =
  listFolderNamesInFolder(s"$hdfsPath/temp/Tweets").foreach {
    case userid =>
      createFolder(s"$hdfsPath/final/$userid")
      moveFile(
        s"$hdfsPath/temp/Tweets/$userid/Tweets.csv",
        s"$hdfsPath/final/$userid/Tweets.csv")
  }

def moveMentionsFiles(hdfsPath: String): Unit =
  listFolderNamesInFolder(s"$hdfsPath/temp/Mentions").foreach {
    case userid =>
      createFolder(s"$hdfsPath/final/$userid")
      moveFile(
        s"$hdfsPath/temp/Mentions/$userid/Mentions.csv",
        s"$hdfsPath/final/$userid/Mentions.csv")
  }

如果您的hdfs根文件夹(包含临时文件夹和最终文件夹的文件夹)是“src / test / resources”(我用来测试的那个):

moveTweetFiles("src/test/resources")
moveMentionsFiles("src/test/resources")

顺便说一下:FileSystem已嵌入Spark依赖项中(无需添加其他依赖项)。

这可以作为Spark作业(spark-submit)启动,即使我们不使用任何Spark管道;或者可能只是来自火花壳。