一、spark的core:
- spark中一个core同时只能同时执行一个任务。
- 计算机的1核1线程(并行一个任务)可以给spark提供1个core,1核2线程(并行两个任务)可以给spark提供2个core。
二、RDD(弹性分布式数据库、RDD中是不存数据的,partition中也不存数据)
- 一个RDD包含一个或多个partition,一个partition同时只能被一个任务处理。
- WordCount中RDD的执行过程
- RDD五大特性:RDD是由一系列partition组成、算子(函数)是作用于partition上的、RDD之间有依赖关系(当RDD2丢失后,可以根据RDD1通过算子恢复RDD2)、分区器是作用在K、V格式的RDD上、partition对外提供最佳的计算位置,利于数据处理的本地化。
三、问题
- K、V格式的RDD:RDD中每个元素是一个个的二元组,那么这个RDD就是K、V格式的RDD。
- sparkContext.textFile():spark没有直接读取HDFS文件的方法,textFile()底层调用的是MR读取HDFS文件的方法,首先会split,每个split默认大小为128M,就是一个block大小,每个split对应一个partition。
- RDD的弹性(容错):1、RDD partition的个数可多(当数据量大时,可由一个partition拆成多个partition,并且执行)可少(当数据量大时,先由10个partition并行执行过滤,过滤之后每个partition只剩下十条数据,对这10个partition再做下一次操作的时候,需要启动是个任务来执行,启动任务的时候也是需要时间的,这时可以把10个partition合并为1个partition,启动一个任务)。2、RDD之间有依赖关系。
- RDD的分布式:RDD中的partition分布在多个结点上。
四、WordCount案例
package com.cfl.spark;
import java.util.Arrays;
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 org.apache.spark.api.java.function.VoidFunction;
import scala.Tuple2;
public class WordCount {
@SuppressWarnings({ "resource" })
public static void main(String[] args) {
SparkConf sparkConf = new SparkConf();
sparkConf.setMaster("local");
sparkConf.setAppName("测试");
/**
* JavaSparkContext 通往集群的唯一通道
*/
JavaSparkContext sparkContext = new JavaSparkContext(sparkConf);
JavaRDD<String> lines = sparkContext.textFile("./test");
/**
* flatMap 进一条数据出多条数据,一对多关系
*/
JavaRDD<String> words = lines.flatMap(new FlatMapFunction<String, String>() {
private static final long serialVersionUID = 1L;
@Override
public Iterable<String> call(String line) throws Exception {
return Arrays.asList(line.split(" "));
}
});
/**
* mapToPair 在java中 如果想让某个RDD转换成K,V格式 使用xxxToPair
* K,V格式的RDD:JavaPairRDD<Tuple<String, Integer>>
*/
JavaPairRDD<String, Integer> pairWords = words.mapToPair(new PairFunction<String, String, Integer>() {
private static final long serialVersionUID = 1L;
public Tuple2<String, Integer> call(String word) throws Exception {
return new Tuple2<String, Integer>(word, 1);
}
});
/**
* 1、先将相同的key分组
* 2、对每一组的key对应的value去按照逻辑去处理
* Function2:第1个参数(第1条数据的value), 第2个参数(第2条数据的value), 第3个参数(内部方法call的返回值类型),
*/
JavaPairRDD<String, Integer> reduce = pairWords.reduceByKey(new Function2<Integer, Integer, Integer>() {
private static final long serialVersionUID = 1L;
@Override
public Integer call(Integer v1, Integer v2) throws Exception {
return v1+v2;
}
});
/**
* 排序 先转换K,V -> 按key拍讯 -> 转换回来K,V
*/
JavaPairRDD<Integer,String> mapToPair = reduce.mapToPair(new PairFunction<Tuple2<String,Integer>, Integer, String>() {
private static final long serialVersionUID = 1L;
@Override
public Tuple2<Integer, String> call(Tuple2<String, Integer> v) throws Exception {
return v.swap();
}
});
JavaPairRDD<Integer, String> sortMapToPair = mapToPair.sortByKey(false);
JavaPairRDD<String, Integer> mapToPair2 = sortMapToPair.mapToPair(new PairFunction<Tuple2<Integer,String>, String, Integer>() {
private static final long serialVersionUID = 1L;
@Override
public Tuple2<String, Integer> call(Tuple2<Integer, String> v) throws Exception {
return v.swap();
}
});
/**
* 遍历打印
*/
mapToPair2.foreach(new VoidFunction<Tuple2<String,Integer>>() {
private static final long serialVersionUID = 1L;
@Override
public void call(Tuple2<String,Integer> arg0) throws Exception {
System.out.println(arg0);
}
});
// 结束
sparkContext.stop();
}
}