Spark学习——常用RDD算子汇总
- 1. parallelize
- java版本
- 2. makeRDD
- 只有scala版本
- 3. textFile
- scala版本
- java版本
- 4. filter
- scala版本
- java版本
- 5. map
- scala版本
- java版本
- 6. flatMap
- scala版本
- java版本,spark2.0以上
- 7. distinct
- scala版本
- java版本
- 8. union
- scala版本
- java版本
- 9. subtract
- scala版本
- java版本
- 10. cartesian
- scala版本
- java版本
- 11. mapToPair
- scala版本
- java版本
- 12. flatMapToPair
- scala版本
- java版本 spark2.0以上
1. parallelize
java版本
def parallelize[T](list : java.util.List[T], numSlices : scala.Int) : org.apache.spark.api.java.JavaRDD[T] = { /* compiled code */ }
- 第一个参数是一个List集合
- 第二个参数是一个分区,可以默认
- 返回的是一个JavaRDD[T]
java版本只能接收List的集合
public class ParallelizeJava {
public static void main(String[] args) {
SparkConf conf= new SparkConf().setAppName("ParallelizeJava").setMaster("local[*]");
JavaSparkContext sc = new JavaSparkContext(conf);
List<String> strings = Arrays.asList("hello world", "hello java", "hello spark");
JavaRDD<String> rdd1=sc.parallelize(strings);
List<String> collect=rdd1.collect();
for(String value:
collect){
System.out.println(value);
}
JavaRDD<String> stringJavaRDD = sc.textFile("in/word.txt");
List<String> collect1 = stringJavaRDD.collect();
for(String str:
collect1){
System.out.println(str);
}
System.out.println("----------------------");
JavaRDD<String> stringJavaRDD1 = sc.textFile("hdfs://hadoop001:9000/kb09space/*.txt");
List<String> collect2 = stringJavaRDD.collect();
for(String str1:
collect2){
System.out.println(str1);
}
}
}
2. makeRDD
只有scala版本
只有scala版本的才有makeRDD
def makeRDD[T](seq : scala.Seq[T], numSlices : scala.Int = { /* compiled code */ })
跟parallelize类似
object MapToPairScala {
def main(args: Array[String]): Unit = {
val conf=new SparkConf().setMaster("local[*]").setAppName("makeRDD")
val sc=new SparkContext(conf)
sc.makeRDD(List("shenzhen", "is a beautiful city"))
}
}
3. textFile
调用SparkContext.textFile()方法,从外部存储中读取数据来创建 RDD
例如在我本地F:\dataexample\wordcount\input下有个sample.txt文件,文件随便写了点内容,我需要将里面的内容读取出来创建RDD
scala版本
object textFileRDDScala {
def main(args: Array[String]): Unit = {
val conf=new SparkConf().setMaster("local[*]").setAppName("textFileRDDScala")
val sc=new SparkContext(conf)
var lines = sc.textFile("F:/dataexample/wordcount/input")
}
}
java版本
public class textFileRDDJava {
public static void main(String[] args) {
SparkConf conf= new SparkConf().setAppName("textFileRDDJava").setMaster("local[*]");
JavaSparkContext sc = new JavaSparkContext(conf);
JavaRDD<String> lines = sc.textFile("F:/dataexample/wordcount/input");
}
}
// 多个路径可以使用逗号分隔,例如
var lines = sc.textFile("dir1,dir2",3)
4. filter
举例,在F:\sparktest\sample.txt 文件的内容如下
aa bb cc aa aa aa dd dd ee ee ee ee
ff aa bb zks
ee kks
ee zz zks
现在需要将包含 “zks” 的行的内容给找出来
scala版本
val lines = sc.textFile("F:/sparktest/sample.txt").filter(line=>line.contains("zks"))
//打印内容
lines.collect().foreach(println(_));
-------------输出------------------
ff aa bb zks
ee zz zks
java版本
public class filterRDDJava {
public static void main(String[] args) {
SparkConf conf= new SparkConf().setAppName("filterRDDJava").setMaster("local[*]");
JavaSparkContext sc = new JavaSparkContext(conf);
JavaRDD<String> lines = sc.textFile("F:/sparktest/sample.txt");
JavaRDD<String> zksRDD = lines.filter(new Function<String, Boolean>() {
@Override
public Boolean call(String s) throws Exception {
return s.contains("zks");
}
});
//打印内容
List<String> zksCollect = zksRDD.collect();
for (String str
:zksCollect) {
System.out.println(str);
}
}
}
5. map
map() 接收一个函数,把这个函数用于 RDD 中的每个元素,将函数的返回结果作为结果RDD编程
RDD 中对应元素的值 map是一对一的关系
举例,在F:\sparktest\sample.txt 文件的内容如下
aa bb cc aa aa aa dd dd ee ee ee ee
ff aa bb zks
ee kks
ee zz zks
把每一行变成一个数组
scala版本
object mapRDDScala {
def main(args: Array[String]): Unit = {
val conf=new SparkConf().setMaster("local[*]").setAppName("mapRDDScala")
val sc=new SparkContext(conf)
//读取数据
val lines = sc.textFile("F:/parktest/sample.txt")
//用map,对于每一行数据,按照空格分割成一个一个数组,然后返回的是一对一的关系
lines.map(line => line.split(" ")).foreach(println)
//读取第一个元素
mapRDD.first.foreach(println)
}
}
java版本
public class mapRDDJava {
public static void main(String[] args) {
SparkConf conf= new SparkConf().setAppName("mapRDDJava").setMaster("local[*]");
JavaSparkContext sc = new JavaSparkContext(conf);
JavaRDD<Iterable<String>> mapRDD = lines.map(new Function<String, Iterable<String>>() {
@Override
public Iterable<String> call(String s) throws Exception {
String[] split = s.split(" ");
return Arrays.asList(split);
}
}
);
//读取第一个元素
System.out.println(mapRDD.first());
}
}
6. flatMap
有时候,我们希望对某个元素生成多个元素,实现该功能的操作叫作 flatMap()
faltMap的函数应用于每一个元素,对于每一个元素返回的是多个元素组成的迭代器(想要了解更多,请参考scala的flatMap和map用法)
例如我们将数据切分为单词
scala版本
object flatMapRDDScala {
def main(args: Array[String]): Unit = {
val conf=new SparkConf().setMaster("local[*]").setAppName("flatMapRDDScala")
val sc=new SparkContext(conf)
val lines = sc.textFile("F:/sparktest/sample.txt")
val flatMapRDD = lines.flatMap(line=>line.split(" "))
flatMapRDD.foreach(println)
flatMapRDD.first().foreach(println)
}
}
java版本,spark2.0以上
spark2.0以上,对flatMap的方法有所修改,就是flatMap中的Iterator和Iteratable的小区别
public class flatMapRDDJava {
public static void main(String[] args) {
SparkConf conf= new SparkConf().setAppName("flatMapRDDJava").setMaster("local[*]");
JavaSparkContext sc = new JavaSparkContext(conf);
JavaRDD<String> flatMapRDD = lines.flatMap(new FlatMapFunction<String, String>() {
@Override
public Iterator<String> call(String s) throws Exception {
String[] split = s.split(" ");
return Arrays.asList(split).iterator();
}
});
}
}
7. distinct
distinct用于去重, 我们生成的RDD可能有重复的元素,使用distinct方法可以去掉重复的元素, 不过此方法涉及到混洗,操作开销很大
scala版本
scala> var RDD1 = sc.parallelize(List("aa","aa","bb","cc","dd"))
scala> RDD1.collect
res3: Array[String] = Array(aa, aa, bb, cc, dd)
scala> var distinctRDD = RDD1.distinct
scala> distinctRDD.collect
res5: Array[String] = Array(aa, dd, bb, cc)
java版本
JavaRDD<String> RDD1 = sc.parallelize(Arrays.asList("aa", "aa", "bb", "cc", "dd"));
JavaRDD<String> distinctRDD = RDD1.distinct();
List<String> collect = distinctRDD.collect();
for (String str:collect) {
System.out.print(str+", ");
}
---------输出----------
aa, dd, bb, cc,
8. union
两个RDD进行合并
scala版本
scala> var RDD1 = sc.parallelize(List("aa","aa","bb","cc","dd"))
scala> var RDD2 = sc.parallelize(List("aa","dd","ff"))
scala> RDD1.collect
res6: Array[String] = Array(aa, aa, bb, cc, dd)
scala> RDD2.collect
res7: Array[String] = Array(aa, dd, ff)
scala> RDD1.union(RDD2).collect
res8: Array[String] = Array(aa, aa, bb, cc, dd, aa, dd, ff)
java版本
JavaRDD<String> RDD1 = sc.parallelize(Arrays.asList("aa", "aa", "bb", "cc", "dd"));
JavaRDD<String> RDD2 = sc.parallelize(Arrays.asList("aa","dd","ff"));
JavaRDD<String> unionRDD = RDD1.union(RDD2);
List<String> collect = unionRDD.collect();
for (String str:collect) {
System.out.print(str+", ");
}
-----------输出---------
aa, aa, bb, cc, dd, aa, dd, ff,
9. subtract
RDD1.subtract(RDD2),返回在RDD1中出现,但是不在RDD2中出现的元素,不去重
scala版本
JavaRDD<String> RDD1 = sc.parallelize(Arrays.asList("aa", "aa","bb", "cc", "dd"));
JavaRDD<String> RDD2 = sc.parallelize(Arrays.asList("aa","dd","ff"));
scala> var substractRDD =RDD1.subtract(RDD2)
scala> substractRDD.collect
res10: Array[String] = Array(bb, cc)
java版本
JavaRDD<String> RDD1 = sc.parallelize(Arrays.asList("aa", "aa", "bb","cc", "dd"));
JavaRDD<String> RDD2 = sc.parallelize(Arrays.asList("aa","dd","ff"));
JavaRDD<String> subtractRDD = RDD1.subtract(RDD2);
List<String> collect = subtractRDD.collect();
for (String str:collect) {
System.out.print(str+" ");
}
------------输出-----------------
bb cc
10. cartesian
RDD1.cartesian(RDD2) 返回RDD1和RDD2的笛卡儿积,这个开销非常大
scala版本
scala> var RDD1 = sc.parallelize(List("1","2","3"))
scala> var RDD2 = sc.parallelize(List("a","b","c"))
scala> var cartesianRDD = RDD1.cartesian(RDD2)
scala> cartesianRDD.collect
res11: Array[(String, String)] = Array((1,a), (1,b), (1,c), (2,a), (2,b), (2,c), (3,a), (3,b), (3,c))
java版本
JavaRDD<String> RDD1 = sc.parallelize(Arrays.asList("1", "2", "3"));
JavaRDD<String> RDD2 = sc.parallelize(Arrays.asList("a","b","c"));
JavaPairRDD<String, String> cartesian = RDD1.cartesian(RDD2);
List<Tuple2<String, String>> collect1 = cartesian.collect();
for (Tuple2<String, String> tp:collect1) {
System.out.println("("+tp._1+" "+tp._2+")");
}
------------输出-----------------
(1 a)
(1 b)
(1 c)
(2 a)
(2 b)
(2 c)
(3 a)
(3 b)
(3 c)
11. mapToPair
举例,在F:\sparktest\sample.txt 文件的内容如下
aa bb cc aa aa aa dd dd ee ee ee ee
ff aa bb zks
ee kks
ee zz zks
将每一行的第一个单词作为键,1 作为value创建pairRDD
scala版本
scala是没有mapToPair函数的,scala版本只需要map就可以了
scala> val lines = sc.textFile("F:\\sparktest\\sample.txt")
scala> val pairs = lines.map(x => (x.split("\\s+")(0), 1))
scala> pairs.collect
res0: Array[(String, Int)] = Array((aa,1), (ff,1), (ee,1), (ee,1))
java版本
JavaRDD<String> lines = sc.textFile("F:\\sparktest\\sample.txt");
//输入的是一个string的字符串,输出的是一个(String, Integer) 的map
JavaPairRDD<String, Integer> pairRDD = lines.mapToPair(new PairFunction<String, String, Integer>() {
@Override
public Tuple2<String, Integer> call(String s) throws Exception {
return new Tuple2<String, Integer>(s.split("\\s+")[0], 1);
}
});
12. flatMapToPair
类似于xxx连接 mapToPair是一对一,一个元素返回一个元素,而flatMapToPair可以一个元素返回多个,相当于先flatMap,在mapToPair
例子: 将每一个单词都分成键为
scala版本
val lines = sc.textFile("F:\\sparktest\\sample.txt")
val flatRDD = lines.flatMap(x => (x.split("\\s+")))
val pairs = flatRDD.map(x=>(x,1))
scala> pairs.collect
res1: Array[(String, Int)] = Array((aa,1), (bb,1), (cc,1), (aa,1), (aa,1), (aa,1), (dd,1), (dd,1), (ee,1), (ee,1), (ee,1), (ee,1), (ff,1), (aa,1), (bb,1), (zks,1), (ee,1), (kks,1), (ee,1), (zz,1), (zks,1))
java版本 spark2.0以上
主要是iterator和iteratable的一些区别
JavaPairRDD<String, Integer> wordPairRDD = lines.flatMapToPair(new PairFlatMapFunction<String, String, Integer>() {
@Override
public Iterator<Tuple2<String, Integer>> call(String s) throws Exception {
ArrayList<Tuple2<String, Integer>> tpLists = new ArrayList<Tuple2<String, Integer>>();
String[] split = s.split("\\s+");
for (int i = 0; i <split.length ; i++) {
Tuple2 tp = new Tuple2<String,Integer>(split[i], 1);
tpLists.add(tp);
}
return tpLists.iterator();
}
});