概述
spark作为一个分布式的集群计算框架,其核心为RDD(resilient distribution dataset),即弹性分布式数据集。 整个spark的编程也都是围绕着RDD进行的,大部分情况下的步骤都是:创建RDD -->转换RDD–>操作RDD(action),下面这个单词计数的demo也是按照这个顺序来的。
废话不多说,直接上代码:
package org.apache.spark.spark_learning;
import java.util.Arrays;
import java.util.Iterator;
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;
public class WordCount {
@SuppressWarnings({ "resource", "serial" })
public static void main(String[] args) throws Exception {
// 指定输入输出文件的位置
String inputFile = "F:\\tmp\\input\\wordcount.txt";
String outputFile = "F:\\tmp\\output\\spark_demo001";
// 设置spark的程序名称以及运行方式为本地运行
SparkConf conf = new SparkConf().setAppName("wordCount").setMaster("local");
// 创建spark的java上下文对象JavaSparkContext,sparkContext代表对计算集群的一个连接
JavaSparkContext sc = new JavaSparkContext(conf);
// 加载输入文件创建一个RDD(弹性分布式数据集)
JavaRDD<String> input = sc.textFile(inputFile);
/**
* 对初始RDD进行转换操作(transformation),得到新的RDD
* 具体的转换操作为调用RDD的flatMap方法对原始的RDD元素进行切割得到多个单词后返回给新的RDD
* flatMap的参数为一个实现了FlatMapFunction接口的实现类,下面我们使用的是匿名内部类
* 我们在FlatMapFunction接口的call抽象方法下实现我们具体的转换逻辑(切割得到单词)
*/
JavaRDD<String> words = input.flatMap(new FlatMapFunction<String, String>() {
public Iterator<String> call(String x) {
return Arrays.asList(x.split(" ")).iterator();
}
});
/**
* 在得到了由文件中所有单词组成的RDD(words)以后,为了统计每个单词出现次数,
* 我们需要对RDD进行再次转换操作,得到键值对形式的PairRDD,通过调用mapToPair方法 例:spark,mapreduce,spark ->
* (spark,1),(mapreduce,1),(spark,1)
*
* 为此我们需要通过原始RDD的每一个元素得到一个键值对,这里spark是通过返回一个二元组对象(Tuple2)实现的
*/
JavaPairRDD<String, Integer> pairRDD = words.mapToPair(new PairFunction<String, String, Integer>() {
public Tuple2<String, Integer> call(String x) {
return new Tuple2(x, 1);
}
});
/**
* 在得到键值对形式的PairRDD以后,开始对单词进行计数,即将(spark,1),(spark,1)转换为(spark,2)
*
* 为此我们调用PairRDD的reduceByKey方法,其参数为Function2接口的实现
* reduceByKey()会对数据集中的每个键进行并行的规约操作,每个规约操作会将键相同的值合并起来
*/
JavaPairRDD<String, Integer> counts = pairRDD.reduceByKey(new Function2<Integer, Integer, Integer>() {
public Integer call(Integer x, Integer y) {
return x + y;
}
});
/**
* 经过以上对RDD的转换操作,我们已经得到了单词计数的结果,接下就调用RDD的行动操作(action)将RDD保存到本地。
*/
counts.saveAsTextFile(outputFile);
}
}