简介
看过我前面分享的博客的小伙伴已经知道了基于MR分布式计算架构的wordcount,现在来进入spark的世界了。
这次我将分享一下基于spark架构的分布式计算框架,分别实现基于java和scala语言的两种不同的脚本。
spark-shell初体验
首先你的虚拟机或者服务器需要先部署spark的伪分布或者是全分布模式,这个可以看我以前的blog,然后这次我使用的是伪分布模式。
安装好之后我们启动spark,然后登陆web dashboard查看,然后进入安装目录下的bin目录,打开spark-shell,
命令如下:
./spark-shell --master spark://你的主机名:7077
然后进入shell命令行。
通过spark-shell实现wordcount
这里我们输入如下命令:
text.txt是我自己创建的txt文件,大家可以根据自己的路径
scala> sc.textFile("/text.txt").flatMap( _.split(" ")).map((_,1)).reduceByKey(_+_).collect
这样就完成了一个最简单的wordcount。
简单分析一下:
- textFile读取文件内容的函数
- flatMap和scala中的一样,下划线代表的是每一行,然后用空格做split
- map函数封装成map格式,这也就是为什么里面要嵌套一层括号,然后给每个map中的value值赋值为1
- reduceByKey,将相同的key的value相加
- collect表示触发计算
注:当然也可以用hdfs文件系统上的文件进行操作,但是要确保集群已经启动。
scala> sc.textFile("hdfs://集群IP:9000/1222_1.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).saveAsTextFile("hdfs://集群IP:9000/out/1222_1")
知识点
在这次操作中我觉得有几点比较重要的点和大家分享一下
对了我再说一下,大家还是需要吧scala的语法夯实一下。
spark的基本单位:RDD:弹性分布式数据集,他有什么特点呢:
- 依赖关系 后一个RDD依赖于前一个RDD。
- 算子,这个后面的blog我会分享清楚,现在有一个概念就行。
Transformation 延时计算 flatMap map reduceByKey
- 也就是说,这些函数并不会进行计算,这个scala中的懒值的概念是一样的。
Action 触发计算 collect
- 相当于如果不输入collect就不会触发计算,那么即使有错误也不会报出。
Idea实现jar包的编写
首先我们先写一下提交的命令,这里我们使用spark-submit工具,因为spark-shell其实真正应用的时候是非常少的,一般都是使用和spark-shell同目录级的spark-submit工具。
下面我将分享一下scala和java的jar包编写,然后下面是jar包的提交运行命令。
spark-submit --master spark://spark81:7077 --class 类reference jar包目录 args[0] args[1]
上面的args[0] args[1]一般是输入输出路径。
下面我写的local模式,如果大家想用spark-submit提交到集群运行,那么就将setMater()去掉。
java:
package wordcount;
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.Iterator;
import java.util.List;
import java.util.regex.Pattern;
/**
* @Author: Braylon
* @Date: 2020/2/9 11:52
* @Version: 1.0
*/
public class wordcount {
private static final Pattern SPACE = Pattern.compile(" ");
public static void main(String[] args) {
SparkConf conf = new SparkConf().setAppName("JAVA_wordcount").setMaster("local");
JavaSparkContext context = new JavaSparkContext(conf);
JavaRDD<String> lines = context.textFile("D:\\idea\\projects\\scalaDemo\\resources\\text.txt");
JavaRDD<String> terms = lines.flatMap(new FlatMapFunction<String, String>() {
public Iterator<String> call(String s) throws Exception {
return Arrays.asList(SPACE.split(s)).iterator();
}
});
JavaPairRDD<String, Integer> ones = terms
.mapToPair(new PairFunction<String, String, Integer>() {
public Tuple2<String, Integer> call(String s) throws Exception {
return new Tuple2<String, Integer>(s, 1);
}
});
JavaPairRDD<String, Integer> counts = ones
.reduceByKey(new Function2<Integer, Integer, Integer>() {
public Integer call(Integer integer, Integer integer2) throws Exception {
return integer + integer2;
}
});
List<Tuple2<String, Integer>> result = counts.collect();
for (Tuple2 item : result) {
System.out.println(item._1() + "-->" + item._2());
}
context.stop();
}
}
scala:
package myDemo06
import org.apache.spark.{SparkConf, SparkContext}
/**
* @Author: Braylon
* @Date: 2019/12/24 13:08
* @Version: 1.0
*/
object wordcount {
def main(arg: Array[String]): Unit = {
/*
* 如果Master是local,表示在本地运行,可以在IDE中运行
* 若需要提交到集群中,就不需要设置Master
* */
val conf = new SparkConf().setAppName("wordcount").setMaster("local")
//创建SparkContext对象
val sc = new SparkContext(conf)
val result = sc.textFile("D:\\idea\\projects\\scalaDemo\\resources\\text.txt")
.flatMap(_.split(" "))
.map((_,1))
.reduceByKey(_+_)
.collect
result.foreach(println)
sc.stop()
}
}
我也在学习的路上,欢迎指正
大家共勉~!