弹性分布式数据集(RDD)

我们会先介绍一下RDD的概念和在spark中的定位,接下来讲解一下RDD的特点,最后给出RDD的一些基本操作函数和一个操作示例。

RDD概念

RDD:Spark的核心概念是RDD(resilientdistributed dataset),指的是一个只读的,可分区的分布式数据集,这个数据集的全部或部分可以缓存在内存中,在多次计算间重用。RDD本质就是一个数组,因此构造数据时候使用的是List(链表)和Array(数组)类型。RDD是spark的基石,它的一个角色定位如下图所示:


RDD特点

1.   RDD数据只读,不可修改。如果需要修改数据,必须从父RDD转换(transformation)到子RDD。所以,在容错策略中,RDD没有数据冗余,而是通过RDD父子依赖(血缘)关系进行重算实现容错。

2.   多个RDD操作之间,数据不用落地到磁盘上,避免不必要的I/O操作。

3.   RDD中存放的数据可以是java对象,所以避免的不必要的对象序列化和反序列化。

4.   RDD在抽象上来说是一种元素集合,包含了数据。它是被分区的,分为多个分区,每个分区分布在集群中的不同节点上,从而让RDD中的数据可以被并行操作。(分布式数据集)

5.   RDD提供了容错性,可以自动从节点失败中恢复过来。即如果某个节点上的RDD partition,因为节点故障,导致数据丢了,那么RDD会自动通过自己的数据来源重新计算该partition。这一切对使用者是透明的。

6.   RDD的数据默认情况下存放在内存中的,但是在内存资源不足时,Spark会自动将RDD数据写入磁盘。(弹性)

RDD基本API

操作类型

函数名

作用

转化操作

map()

参数是函数,函数应用于RDD每一个元素,返回值是新的RDD

flatMap()

参数是函数,函数应用于RDD每一个元素,将元素数据进行拆分,变成迭代器,返回值是新的RDD

filter()

参数是函数,函数会过滤掉不符合条件的元素,返回值是新的RDD

distinct()

没有参数,将RDD里的元素进行去重操作

union()

参数是RDD,生成包含两个RDD所有元素的新RDD

intersection()

参数是RDD,求出两个RDD的共同元素

subtract()

参数是RDD,将原RDD里和参数RDD里相同的元素去掉

cartesian()

参数是RDD,求两个RDD的笛卡儿积

行动操作

collect()

返回RDD所有元素

count()

RDD里元素个数

countByValue()

各元素在RDD中出现次数

reduce()

并行整合所有RDD数据,例如求和操作

fold(0)(func)

和reduce功能一样,不过fold带有初始值

aggregate(0)(seqOp,combop)

和reduce功能一样,但是返回的RDD数据类型和原RDD不一样

foreach(func)

对RDD每个元素都是使用特定函数

RDD操作实例

本实例的pom.xml所依赖的文件和上一章节《 spark环境构建及示例》里面例子的pom.xml一致,这里不再累述

package org.mAegis.spark.machine.learning.engine;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
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.FlatMapFunction2;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.Function2;
import org.apache.spark.api.java.function.VoidFunction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * RDDApp
 * 
 */
public class RDDApp {
	private final static Logger logger = LoggerFactory.getLogger(RDDApp.class);

	public static void main(String[] args) {
		SparkConf conf = new SparkConf().setAppName("rdd");
		JavaSparkContext sc = new JavaSparkContext(conf);
		
		//输入数据构造 rdd
		JavaRDD<Integer> rddInput01 = sc.parallelize(Arrays.asList(1,2,3,4,5));
		JavaRDD<Integer> rddInput02 = sc.parallelize(Arrays.asList(6,7,8,9,10));
		JavaRDD<Integer> rddInput03 = sc.parallelize(Arrays.asList(6,7,6,7,6));
		JavaRDD<Integer> rddInput04 = sc.parallelize(Arrays.asList(-1,2,3,4,5));
		JavaRDD<String> rddInput05 = sc.parallelize(Arrays.asList("1:2:3","4:5"));
		logger.info("rddInput01 ===>"+rddInput01.collect());
		logger.info("rddInput02 ===>"+rddInput02.collect());
		logger.info("rddInput03 ===>"+rddInput03.collect());
		logger.info("rddInput04 ===>"+rddInput04.collect());
		logger.info("rddInput05 ===>"+rddInput05.collect());
		
		//数据缓存
		rddInput01.cache();
		rddInput02.cache();
		rddInput03.cache();
		rddInput04.cache();
		rddInput05.cache();
		
		//转化操作数据输出
		JavaRDD<Integer> rddOutPutUnion = rddInput01.union(rddInput02);
		logger.info("rddInput01 rddOutPutUnion rddInput02===>"+rddOutPutUnion.collect());
		JavaRDD<Integer> rddOutPutDistinct = rddInput03.distinct();
		logger.info("rddInput03 rddOutPutDistinct===>"+rddOutPutDistinct.collect());
		JavaPairRDD<Integer, Integer> rddOutPutCartesian = rddInput01.cartesian(rddInput02);
		logger.info("rddInput01 rddOutPutCartesian rddInput02===>"+rddOutPutCartesian.collect());
		JavaRDD<Integer> rddOutPutSubtract = rddInput03.subtract(rddInput02);
		logger.info("rddInput03 rddOutPutSubtract rddInput02===>"+rddOutPutSubtract.collect());
		JavaRDD<Integer> rddOutPutIntersection = rddInput03.intersection(rddInput02);
		logger.info("rddInput03 rddOutPutIntersection rddInput02===>"+rddOutPutIntersection.collect());
		JavaRDD<Integer> rddOutPutFilter = rddInput04.filter(new Function<Integer, Boolean>() {
			@Override
			public Boolean call(Integer v1) throws Exception {
				if(v1 <0) {
					return false;
				}
				return true;
			}
			
		});
		logger.info("rddInput04 rddOutPutFilter===>"+rddOutPutFilter.collect());
		JavaRDD<Integer> rddOutPutSquare = rddInput01.map(new Function<Integer, Integer>() {
			@Override
			public Integer call(Integer v1) throws Exception {
				return v1*v1;
			}
		});
		logger.info("rddInput01 rddOutPutSquare===>"+rddOutPutSquare.collect());
//		JavaRDD<String> rddOutPutFlatMap = rddInput05.flatMap(new FlatMapFunction(){
//			@Override
//			public Iterable call(Object t) throws Exception {
//				// TODO Auto-generated method stub
//				return null;
//			}
//			
//		}
//		);
//		logger.info("rddInput05 rddOutPutFlatMap===>"+rddOutPutFlatMap.collect());
		
		//行动操作数据输出
		Integer rddOutPutSquareAdd = rddOutPutSquare.reduce(new Function2<Integer, Integer, Integer>() {
			@Override
			public Integer call(Integer v1, Integer v2) throws Exception {
				return v1+v2;
			}
		});
		logger.info("rddOutPutSquare rddOutPutSquareAdd===>"+rddOutPutSquareAdd);
		Integer rddOutPutFlodAdd = rddInput01.fold(0, new Function2<Integer, Integer, Integer>() {

			@Override
			public Integer call(Integer v1, Integer v2) throws Exception {
				return v1+v2;
			}
			
		});
		logger.info("rddInput01 rddOutPutFlodAdd===>"+rddOutPutFlodAdd);
		Integer rddOutPutAggregate = rddInput02.aggregate(0, new Function2<Integer, Integer, Integer>() {

			@Override
			public Integer call(Integer v1, Integer v2) throws Exception {
				return v1*v2;
			}
			
		}, new Function2<Integer, Integer, Integer>() {

			@Override
			public Integer call(Integer v1, Integer v2) throws Exception {
				return v1+v2;
			}
			
		});
		logger.info("rddInput02 aggregate===>"+rddOutPutAggregate);
		rddInput03.foreach(new VoidFunction<Integer>() {
			@Override
			public void call(Integer t) throws Exception {
				t = t*2;
			}
		});
		logger.info("rddInput03 foreach t*2===>"+rddInput03.collect());
		List<Integer> rddOutPut3Collect = rddInput03.collect();
		logger.info("rddInput03 rddOutPut3Collect ===>"+rddOutPut3Collect);
		List<Integer> rddOutPutCollect = rddInput01.collect();
		logger.info("rddInput01 rddOutPutCollect ===>"+rddOutPutCollect);
		int count = (int) rddInput02.count();
		logger.info("rddInput02 count ===>"+count);
		Map<Integer,Long> countByValueMap = rddInput03.countByValue();
		logger.info("rddInput03 countByValue ===>"+countByValueMap);
	}
}
示例运行结果:

16/11/08 20:02:31 INFO RDDApp: rddInput01 ===>[1, 2, 3, 4, 5]
16/11/08 20:02:31 INFO RDDApp: rddInput02 ===>[6, 7, 8, 9, 10]
16/11/08 20:02:31 INFO RDDApp: rddInput03 ===>[6, 7, 6, 7, 6]
16/11/08 20:02:32 INFO RDDApp: rddInput04 ===>[-1, 2, 3, 4, 5]
16/11/08 20:02:32 INFO RDDApp: rddInput05 ===>[1:2:3, 4:5]
16/11/08 20:02:32 INFO RDDApp: rddInput01 rddOutPutUnion rddInput02===>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
16/11/08 20:02:33 INFO RDDApp: rddInput03 rddOutPutDistinct===>[6, 7]
16/11/08 20:02:33 INFO RDDApp: rddInput01 rddOutPutCartesian rddInput02===>[(1,6), (1,7), (1,8), (1,9), (1,10), (2,6), (2,7), (2,8), (2,9), (2,10), (3,6), (3,7), (3,8), (3,9), (3,10), (4,6), (5,6), (4,7), (5,7), (4,8), (5,8), (4,9), (4,10), (5,9), (5,10)]
16/11/08 20:02:33 INFO RDDApp: rddInput03 rddOutPutSubtract rddInput02===>[]
16/11/08 20:02:33 INFO RDDApp: rddInput03 rddOutPutIntersection rddInput02===>[6, 7]
16/11/08 20:02:34 INFO RDDApp: rddInput04 rddOutPutFilter===>[2, 3, 4, 5]
16/11/08 20:02:34 INFO RDDApp: rddInput01 rddOutPutSquare===>[1, 4, 9, 16, 25]
16/11/08 20:02:34 INFO RDDApp: rddOutPutSquare rddOutPutFlatMap===>55
16/11/08 20:02:34 INFO RDDApp: rddInput01 rddOutPutFlodAdd===>15
16/11/08 20:02:34 INFO RDDApp: rddInput02 aggregate===>0
16/11/08 20:02:34 INFO RDDApp: rddInput03 foreach t*2===>[6, 7, 6, 7, 6]
16/11/08 20:02:34 INFO RDDApp: rddInput03 rddOutPut3Collect ===>[6, 7, 6, 7, 6]
16/11/08 20:02:34 INFO RDDApp: rddInput01 rddOutPutCollect ===>[1, 2, 3, 4, 5]
16/11/08 20:02:34 INFO RDDApp: rddInput02 count ===>5
16/11/08 20:02:34 INFO RDDApp: rddInput03 countByValue ===>{6=3, 7=2}



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值