【问题标题】:Apache Spark on HDFS: read 10k-100k of small files at onceHDFS 上的 Apache Spark:一次读取 10k-100k 的小文件
【发布时间】:2017-10-09 07:03:41
【问题描述】:

我可以拥有多达 10 万个小文件(每个 10-50 KB)。它们都存储在 HDFS 中,块大小为 128 MB。我必须使用 Apache Spark 立即阅读它们,如下所示:

// return a list of paths to small files
List<Sting> paths = getAllPaths(); 
// read up to 100000 small files at once into memory
sparkSession
    .read()
    .parquet(paths)
    .as(Encoders.kryo(SmallFileWrapper.class))
    .coalesce(numPartitions);

问题

The number of small files is not a problem from the perspective of memory consumption。问题是读取这么多文件的速度。读取490个小文件需要38秒,读取3420个文件需要266秒。我想读取 100.000 个文件需要很多时间。

问题

HAR 或序列文件会加快 Apache Spark 批量读取 10k-100k 小文件的速度吗?为什么?

HAR 或序列文件会减慢小文件的持久化速度吗?为什么?

附言

批量读取是小文件唯一需要的操作,我不需要通过 id 或其他任何方式读取它们。

【问题讨论】:

  • Hadoop 有一个标准的解决方法,通常在 Hive 中用于读取小型“流式”文件(参见我在您上一个问题中的评论),您不是第一个偶然发现该问题的 Spark-ikaze - - 参见。 stackoverflow.com/questions/24623402/…

标签: java apache-spark hdfs


【解决方案1】:

来自该帖子:How does the number of partitions affect `wholeTextFiles` and `textFiles`?

wholeTextFiles 使用WholeTextFileInputFormat ... 因为它扩展了CombineFileInputFormat,它会尝试合并 一组较小的文件到一个分区中... RDD 中的每条记录 ...包含文件的全部内容


在 Spark 1.6.3 Java API 文档中确认SparkContext
http://spark.apache.org/docs/1.6.3/api/java/index.html

RDD<scala.Tuple2<String,String>> wholeTextFiles(String path, int minPartitions)
从本地 HDFS 读取文本文件目录 文件系统(在所有节点上可用),或任何 Hadoop 支持的文件 系统 URI。


在源代码(分支 1.6)cmets 中确认类 WholeTextFileInputFormat
https://github.com/apache/spark/blob/branch-1.6/core/src/main/scala/org/apache/spark/input/WholeTextFileInputFormat.scala

org.apache.hadoop.mapreduce.lib.input.CombineFileInputFormat 为 阅读整个文本文件。每个文件都被读取为键值对,其中键是文件路径, 该值是文件的全部内容。


作为记录,Hadoop CombineInputFormat 是在单个 Mapper 中填充多个小文件的标准方法;它可以在具有hive.hadoop.supports.splittable.combineinputformathive.input.format 属性的Hive 中使用。

Spark wholeTextFiles() 重用了 Hadoop 功能,但有两个缺点:
(a) 您必须消耗整个目录,无法在加载文件之前按名称过滤文件(您只能在加载后过滤
(b) 如果需要,您必须通过将每个文件拆分为多个记录来对 RDD 进行后处理

尽管如此,这似乎是一个可行的解决方案,参见。那个帖子:Spark partitioning/cluster enforcing


或者,您可以基于相同的 Hadoop CombineInputFormat 构建自己的自定义文件阅读器,参见。那个帖子:Apache Spark on YARN: Large number of input data files (combine multiple input files in spark)

【讨论】:

  • 感谢您的回答!我已经通过序列文件saveAsHadoopFile(path, String.class, SmallFileWrapper.class, SequenceFileOutputFormat.class) 实现了这些东西。您能否将序列文件与wholeTextFiles 解决方案进行比较?哪个更好,什么时候更好?
  • Duh...恕我直言wholeTextFiles 是一种权宜之计,当您需要一次性有效读取大量小测试文件时(然后在内存中重新处理)。现在,如果您想先合并数据(例如,Write-Once-Read-Many times 场景),所有选项都已打开——文件格式、压缩等。这取决于。
猜你喜欢
  • 1970-01-01
  • 2017-06-14
  • 2021-06-18
  • 1970-01-01
  • 1970-01-01
  • 2021-06-25
  • 1970-01-01
  • 1970-01-01
  • 2019-08-22
相关资源
最近更新 更多