在Spark中发现和读取多个文件

时间:2019-03-17 03:07:45

标签: scala apache-spark

具有不同的系统,这些系统具有不同的文件集(txt,csv)要加载,转换和写入文件 使用Apache Spark / Scala。 假设SystemA有3个文件,SystemB在各自的目录中有2个文件。

FileType       |FileNames
-----------------------------------------
Customer       |Customer_20190301.csv
Account        |Account_20190301.csv
Order          |Order_20190301.csv
OrderDetails   |OrderDetails_20190301.txt
Transactions   |Transactions_20190301.txt

现在,我想根据输入的系统名称获取文件名和路径,以便我可以加载它们各自的系统文件。 我不想为每个系统创建单独的程序并加载它们的文件,因为将来文件名或路径可能会更改。

是否有一种有效的方法来处理此问题?使用配置文件? 还是正在使用或不使用任何外部库?请引导我。

1 个答案:

答案 0 :(得分:1)

此问题是采用分治法的很好的选择:

  1. 描述系统数量+参数化进一步处理所需的任何参数。如何执行取决于您的部署环境,选择的语言等。没有一个正确的答案。

  2. 将(1)中的信息读取到数据结构中。

  3. 使用(2)以及(递归)目录列表的某种组合来生成要处理的文件列表。请注意,给定路径,您可以使用FileSystem.get(new java.net.URI(path), new Configuration())在Spark中获得Hadoop文件系统。

  4. 按类型对文件进行分组。

  5. 对于每个组,从DataFrameReader参数化一个spark.read,并使用.load(paths: _*)调用多路径加载版本。您可以通过创建组名映射到返回DataFrameReader的函数来通用化此代码。

以下是操作方法示例(5):

val readers: Map[String, SparkSession => DataFrameReader] = Map(
  "customer" -> ((spark: SparkSession) => spark.read.option("format", "csv"))
)

val groups: Map[String, Seq[String]] = ???

groups.map { case (groupName, paths) =>
  readers(groupName)(spark).load(paths: _*)
}