Spark1.4从HDFS读取文件运行Java语言WordCounts并将结果保存至HDFS
本次实验相关信息如下:
操作系统:Ubuntu 14
Hadoop版本:2.4.0
Spark版本:1.4.0
运行前提是Hadoop与Spark均已正确安装配置
2、在Linux中生成一个文件test.txt,保存在/home/testjars/目录下
3、通过hadoop fs -put命令上传
hadoop fs -put /home/testjars/test.txt
4、在文件系统中查看:
![](https://app.yinxiang.com/shard/s22/res/3d6abe79-8736-42f2-8b5c-e4554a0b3536/test1.png)
(Spark1.4 官方文档中的一段)
记住路径:hdfs://localhost:9000/user/root/test.txt
端口好在hadoop安装时有配置,上传命令中若不指定上传文件夹,默认存入/user/root文件夹下
5、编写Spark的Java版WordCount程序
需要导入的jar包在SPARK_HOME/assembly/target/scala-2.10下
spark-assembly-1.4.0-hadoop2.4.0.jar如下图所示:![](https://app.yinxiang.com/shard/s22/res/cbb49941-3b53-423e-9526-da3d804266b5/jar1.png)
![](https://app.yinxiang.com/shard/s22/res/cbb49941-3b53-423e-9526-da3d804266b5/jar1.png)
该jar包中包含了spark的所有依赖包,大小为132.3M
在eclipse中部分展开图如下:
![](https://app.yinxiang.com/shard/s22/res/c61b1bb4-bbb0-43a2-9547-9abc966f123a/jar2.png)
6、jar包导入完成后,便可编写Java程序:
import org.apache.spark.SparkConf; import org.apache.spark.api.java.JavaPairRDD; import org.apache.spark.api.java.JavaRDD; import org.apache.spark.api.java.JavaSparkContext; import org.apache.spark.api.java.function.FlatMapFunction; import org.apache.spark.api.java.function.Function2; import org.apache.spark.api.java.function.PairFunction; import scala.Tuple2; import java.util.Arrays; import java.util.List; import java.util.regex.Pattern; public final class JavaWordCount { private static final Pattern SPACE = Pattern.compile(" "); public static void main(String[] args) throws Exception { if (args.length < 1) { System.err.println("Usage: JavaWordCount <file>"); System.exit(1); } //创建SparkConf,包含application的相关信息 SparkConf sparkConf = new SparkConf().setAppName("JavaWordCount"); //创建一个JavaSparkContext对象 JavaSparkContext ctx = new JavaSparkContext(sparkConf); //textFile()方法可将本地文件或HDFS文件转换成RDD,读取本地文件需要各节点上都存在,或者通过网络共享该文件 //读取一行 JavaRDD<String> lines = ctx.textFile(args[0], 1); //flatMap与map的区别是,对每个输入,flatMap会生成一个或多个的输出,而map只是生成单一的输出 //用空格分割各个单词,输入一行,输出多个对象,所以用flatMap JavaRDD<String> words = lines.flatMap(new FlatMapFunction<String, String>() { @Override public Iterable<String> call(String s) { return Arrays.asList(SPACE.split(s)); } }); //对每个单词生成key-value对,PairFunction<T,K,V> //表示输入类型为T,生成的key-value对中的key类型为k,value类型为v,对本例,T=String, K=String, V=Integer(计数) //重写scala的Tupple2方法 JavaPairRDD<String, Integer> ones = words.mapToPair(new PairFunction<String, String, Integer>() { @Override //scala.Tuple2<K,V> call(T t) //Tuple2为scala中的一个对象,call方法的输入参数为T,即输入一个单词s,新的Tuple2对象的key为这个单词,计数为1 public Tuple2<String, Integer> call(String s) { return new Tuple2<String, Integer>(s, 1); } }); //调用reduceByKey方法,按key值进行reduce //调用Function2对象,Function2<T1,T2,R> //输入两个参数,T1,T2,返回R //若ones有<"one", 1>, <"one", 1>,会根据"one"将相同的pair单词个数进行统计,输入为Integer,输出也为Integer //输出<"one", 2> JavaPairRDD<String, Integer> counts = ones.reduceByKey(new Function2<Integer, Integer, Integer>() { @Override public Integer call(Integer i1, Integer i2) { return i1 + i2; } }); //将结果保存到HDFS中 counts.saveAsTextFile(args[1]); //collect返回一个包含RDD内所有元素的Array List<Tuple2<String, Integer>> output = counts.collect(); for (Tuple2<?, ?> tuple : output) { System.out.println(tuple._1() + ": " + tuple._2()); } ctx.stop(); } }
7、将该java程序导出为jar文件,保存在/home/testjars文件夹下
8、启动spark,在SPARK_HOME/sbin文件夹下
./start-all.sh
浏览器输入:localhost:8080
![](https://app.yinxiang.com/shard/s22/res/52893897-de0d-412b-a0f0-bac620d64f0c/spark.png)
记住红色方框中的内容。
9、使用spark-submit命令上传任务
spark-submit命令更多参数可使用spark-submit --help进行查看
本次任务使用的命令如下:
spark-submit --master spark://chenkm-Lenovo:7077 --name JavaWordCount --class JavaWordCount --executor-memory 1G --total-executor-cores 2 /home/testjars/JavaWordCount.jar hdfs://localhost:9000/user/root/test.txt hdfs://localhost:9000/user/root/testoutput
10、运行结果如下:
![](https://app.yinxiang.com/shard/s22/res/36c21ac4-98a3-432a-b567-f573546ea3fb/result1.png)
在HDFS中保存:
![](https://app.yinxiang.com/shard/s22/res/20f04683-df30-4691-b6bd-3566c7d1c22f/result2.png)
同时在localhost:8080页面中可以看到
![](https://app.yinxiang.com/shard/s22/res/81e1d83c-2286-4dea-a441-f21061c3bb01/sss.png)