互斥写入HDFS文件?

时间:2016-04-30 18:34:19

标签: scala hadoop apache-spark bigdata

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

2 个答案:

答案 0 :(得分:2)

Spark1.5及更高版本中的DataFrame提供了附加到HDFS上现有DF的功能。 Spark内部使用了@marios描述的技术。

例如(在Java中):

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

如果你检查HDFS,你会看到(写给“你好”的例子):

-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

答案 1 :(得分:2)

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

这不是Spark限制,这正是HDFS的设计方式。在HDFS中,文件是不可变的。每个文件只有一个编写器,关闭后不会附加。这对大数据和Spark很有用,因为你总是知道同一个文件会产生相同的数据。

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

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