在本博客的《Hadoop多文件输出:MultipleOutputFormat和MultipleOutputs深究(一)》《Hadoop多文件输出:MultipleOutputFormat和MultipleOutputs深究(二)》两篇文章中我介绍了如何在Hadoop中根据Key或者Value的不同将属于不同的类型记录写到不同的文件中。在里面用到了MultipleOutputFormat这个类。
因为Spark内部写文件方式其实调用的都是Hadoop那一套东西,所以我们也可以通过Spark实现多文件输出。不过遗憾的是,Spark内部没有多文件输出的函数供大家直接调用,值得欣慰的是,我们自己实现这个功能也是很简单的。我们可以通过调用saveAsHadoopFile函数并自定义一个OutputFormat类即可,代码如下:
/**
* User: 过往记忆
* Date: 15-03-11
* Time: 上午08:24
* bolg: https://www.iteblog.com
* 过往记忆博客,专注于hadoop、hive、spark、shark、flume的技术博客,大量的干货
* 过往记忆博客微信公共帐号:iteblog_hadoop
*/
import
org.apache.hadoop.io.NullWritable
import
org.apache.spark.
_
import
org.apache.spark.SparkContext.
_
import
org.apache.hadoop.mapred.lib.MultipleTextOutputFormat
class
RDDMultipleTextOutputFormat
extends
MultipleTextOutputFormat[Any, Any] {
override
def
generateFileNameForKeyValue(key
:
Any, value
:
Any, name
:
String)
:
String
=
key.asInstanceOf[String]
}
object
Split {
def
main(args
:
Array[String]) {
val
conf
=
new
SparkConf().setAppName(
"SplitTest"
)
val
sc
=
new
SparkContext(conf)
sc.parallelize(List((
"w"
,
"www"
), (
"b"
,
"blog"
), (
"c"
,
"com"
), (
"w"
,
"bt"
)))
.map(value
=
> (value.
_
1
, value.
_
2
+
"Test"
))
.partitionBy(
new
HashPartitioner(
3
))
.saveAsHadoopFile(
"/iteblog"
, classOf[String], classOf[String],
classOf[RDDMultipleTextOutputFormat])
sc.stop()
}
}
|
RDDMultipleTextOutputFormat类中的generateFileNameForKeyValue函数有三个参数,key和value就是我们RDD的Key和Value,而name参数是每个Reduce的编号。本例中没有使用该参数,而是直接将同一个Key的数据输出到同一个文件中。执行:
bin/spark-submit --master yarn-cluster
--
class
Split ./iteblog-
1.0
-SNAPSHOT.jar
|
然后我们可以看到在HDFS上输出的文件列表如下:
[iteblog@master ]$ bin
/hadoop
fs -
ls
/iteblog
Found 4 items
-rw-r--r-- 3 iteblog hadoop2 0 2015-03-09 11:26
/iteblog/_SUCCESS
-rw-r--r-- 3 iteblog hadoop2 11 2015-03-09 11:26
/iteblog/b
-rw-r--r-- 3 iteblog hadoop2 10 2015-03-09 11:26
/iteblog/c
-rw-r--r-- 3 iteblog hadoop2 19 2015-03-09 11:26
/iteblog/w
[iteblog@master ]$ bin
/hadoop
fs -
cat
/iteblog/w
w btTest
w wwwTest
|
从上面的输出可以看出key为w的记录全部输出到文件名为w的文件中去了。
转载地址:https://www.iteblog.com/archives/1281.html