概念
Spark是一个集群计算系统,主要抽象为一个弹性分布式数据集(resilient distributed data set,RDD)。
RDD创建
- Hadoop InputForm(如HDFS)
- 其他RDD转换
- 通过转换集合类数据额结构来创建(例如List和Map)
- Java或Scala集合对象以及其他持久数据存储库创建
RDD的两种操作
动作有
- reduce()
- collect()
- count()
- saveAsTextFile()
变换有
- map()
- filter()
- union()
- groupBykey()
- reduceByKey()
提供StorageLevel类来控制Spark RDD存储,例如:
- MEMORY_ONLY(只使用内存来存储RDD)
- DISK_ONLY(只使用硬盘存储RDD)
- MEMORY_AND_DIST(组合使用)
Spark操作
Spark作业完成对RDD的工作(动作与变换),Spark主程序在Spark驱动器上执行,而变换在Spark工作节点上执行。在Spark中创建一个RDD对象后,可以通过调用Spark API完成一组操作。主要包括变换与动作两类操作:
变换(Transformations)
变换是根据原来的RDD返回一个新的RDD。
动作(Actions)
动作根据RDD上完成的某个计算返回一个值。
Tuple <N>
Spark中使用的大量的元组,如scala.Tuple2(两元素元组),scala.Tuple3等,scala.Tuple<N>表示N个元素的一个组合数据结构。
这里取元组元素使用_(标号),例如:_1,如下:
import scala.Tuple2;
Tuple2<String,Integer> t = new Tuple2<String,Integer>("abc",234);
String str = t._1;
Integer num = t._2;
Java Spark API中还定义了scala.Tuple3到scala.Tuple22
具体RDD介绍
RDD是Spark中的基本数据抽象,Spark提供了许多子类和包装器(例如JavaRDD,JavaPairRDD,JavaHadoopRDD)。
RDD是一个不可变的分区元素结合,只读,不能修改或更新,但可以并行处理。
JavaRDD和JavaPairRDD在org.apache.spark.api.java包中定义
创建RDD
- 创建一个JavaSparkContext,可以使用Spark主URL创建,或者使用YARN的资源管理器主机名来创建,还可以使用SparkUtil类来创建,也可以用以下方法创建:
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
...
SparkConf sparkConf = new SparkConf().setAppName("my-app-name");
JavaSparkContext ctx = new JavaSparkContext(sparkConf);
- 一旦有了JavaSparkContext实例,就可以由很多不同来源创建RDD:Java集合对象,文本文件以及HDFS文件(文本或二进制)。
- 一旦有了JavaRDD或JavaPairRDD的一个实例,就可以通过map()、reduceByKey()、filter()或groupByKey()方法创建新的RDD。还可以使用Java集合对象或者通过读取文件(文本文件或文本/二进制HDFS文件)来创建RDD。
使用集合对象创建RDD
import java.util.List;
import com.google.common.collect.Lists;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
SparkConf sparkConf = new SparkConf().setAppName("my-app-name");
JavaSparkContext ctx = new JavaSparkContext(sparkConf);
final List<String> list1 = Lists.newArrayList(
"url1,2",
"url1,3",
"url2,7",
"url3,4"
);
JavaRDD<String> rdd1 = ctx.parallelize(list1);
收集RDD元素
上边生成的rdd1可以收集为一个List<String>,如下:
//从java对象创建RDD
JavaRDD<String> rdd1 = ctx.parallelize(list1);
//返回一个数组,包含RDD中的所有元素
java.util.list<String> collected = rdd1.collect();
将已有的RDD转换为一个新的RDD
以rdd1为例,把它转化为键值对(作为一个javaPairRDD对象),使用JavaRDD.mapToPair()方法。
JavaRDD<String> rdd1 = ctx.parallelize(list1);
JavaPairRDD<String,Integer> kV1 = rdd1.mapToPair(
new PairFunction<
String, // T 作为输入
String, // K 作为输出
Integer // V 作为输出
>(){
@Override
public Tuple2<String,Integer> call(String element){
String[] tokens = element.split(",");
//tokens[0] = URL;
//tokens[1] = count
return new Tuple2<String,Integer>(tokens[0],new Integer(tokens[1]));
}
});