HDFS文件的互斥写入?

Posted

技术标签:

【中文标题】HDFS文件的互斥写入?【英文标题】:Mutually exclusive write for HDFS file? 【发布时间】:2016-04-30 18:34:19 【问题描述】:

基本上,在我的程序中,任务将附加到 HDFS 文件中。但是,我不希望两个任务同时附加文件。是否有一种机制,我只有一个任务附加到 HDFS 文件。基本上是一种互斥体机制。我在创建文件的时候也需要这样的互斥体。

【问题讨论】:

您使用的是哪个版本的 Spark? 我使用的是 Spark 1.6 任何其他发现而不是 DataFrame .. 请保持发布。我想知道是否还有其他东西。谢谢 【参考方案1】:

据我所知,您不能让多个处理程序写入同一个 HDFS 文件。

这不是 Spark 的限制,这正是 HDFS 的设计方式。在 HDFS 中,文件是不可变的。每个文件只有一个编写器,关闭后没有附加内容。这对于大数据和 Spark 来说非常有用,因为您始终知道同一个文件将产生相同的数据。

在 Hadoop 中解决此问题的方法是让每个编写者编写自己的文件,然后使用最终的 MapReduce 作业将它们合并到一个文件中(如果这是您真正想要的)。

大多数情况下,您可以只使用这些多个文件。诀窍是将文件夹作为容器;例如,/a/b/people,其中人员文件夹有很多不同的文件,每个文件都包含不同的“人员”子集。 Spark 读取多个文件并将它们加载到同一个 DataFrame 或 RDD 中没有问题。

【讨论】:

你的第二个建议,这正是我正在做的,但问题是,我必须合并数百个文件。如果生产部分只制作一个文件,那么我会减少在消费部分读取这么多文件的开销。 我认为使用 HDFS 是无法解决的。您也可以使用 HBase 来存储数据,这样您就不必在文件级别管理数据。或者您可以将所有内容添加到队列中(例如 Kafka),然后使用一个读取器从 Q 中读取并仅创建一个文件。 @Marios:可以在 spark 1.5 之后使用 DataFrames 来实现(我们已经做到了如下。为了详细说明下面的答案,我们正在从消息系统接收特定 cobdate/business/env/ 的消息,所以我们在摄取端制作我们的 HDFS 文件夹结构,如 cobdate/business/env/0-9(分区文件夹)。在处理端,我们正在按照逻辑从我们正在处理的数据帧中加载这些分区文件夹。对于一个特定的业务/cobdate/env 有多个文件夹 0-9 并且能够将它们保存为 parquet-avro 文件(当然不是 1 个文件) @Marios:在这种情况下,SaveMode.Append 是什么? Data-Frame 如何在内部处理它? 【参考方案2】:

Spark1.5 及更高版本中的数据帧提供了附加到 HDFS 上现有 DF 的能力。 Spark 在内部使用@marios 在另一个答案中描述的技术。

例如(在 Java 中):

dataframe.write().mode(SaveMode.Append).
   format(FILE_FORMAT).partitionBy("parameter1", "parameter2").save(path);

如果您检查 HDFS,您会看到(写入“hello”的示例):

-rw-r--r--   3 vagrant supergroup          0 2016-05-13 17:48 /home/hello/_SUCCESS
-rw-r--r--   3 vagrant supergroup        281 2016-05-13 17:48 /home/hello/_common_metadata
-rw-r--r--   3 vagrant supergroup       2041 2016-05-13 17:48 /home/hello/_metadata
-rw-r--r--   3 vagrant supergroup        499 2016-05-13 17:46 /home/hello/part-r-00000-182e0b9b-a15d-47f9-8a3e-07739d6f2534.gz.parquet
-rw-r--r--   3 vagrant supergroup        499 2016-05-13 17:48 /home/hello/part-r-00000-a8cf0223-69b3-4c2c-88f6-91252d99967c.gz.parquet
-rw-r--r--   3 vagrant supergroup        499 2016-05-13 17:46 /home/hello/part-r-00001-182e0b9b-a15d-47f9-8a3e-07739d6f2534.gz.parquet
-rw-r--r--   3 vagrant supergroup        499 2016-05-13 17:48 /home/hello/part-r-00001-a8cf0223-69b3-4c2c-88f6-91252d99967c.gz.parquet
-rw-r--r--   3 vagrant supergroup        499 2016-05-13 17:46 /home/hello/part-r-00002-182e0b9b-a15d-47f9-8a3e-07739d6f2534.gz.parquet
-rw-r--r--   3 vagrant supergroup        499 2016-05-13 17:48 /home/hello/part-r-00002-a8cf0223-69b3-4c2c-88f6-91252d99967c.gz.parquet
-rw-r--r--   3 vagrant supergroup        499 2016-05-13 17:46 /home/hello/part-r-00003-182e0b9b-a15d-47f9-8a3e-07739d6f2534.gz.parquet
-rw-r--r--   3 vagrant supergroup        499 2016-05-13 17:48 /home/hello/part-r-00003-a8cf0223-69b3-4c2c-88f6-91252d99967c.gz.parquet

请查看适合您要求的不同保存模式选项here

如果您使用的是 Spark1.4 请关注SaveMode doc

【讨论】:

以上是关于HDFS文件的互斥写入?的主要内容,如果未能解决你的问题,请参考以下文章

配置 Spark 写入 HDFS 的 Avro 文件大小

Python写入hdfs文件

Pig UDF 将文件写入 HDFS

在 Spark/Scala 中写入 HDFS,读取 zip 文件

Hadoop HDFS:读取正在写入的序列文件

将文件上传到 HDFS 或直接创建和写入 HDFS 文件哪个更快?