原文链接:
我们都知道,Apache Spark内置了很多操作数据的API。但是很多时候,当我们在现实中开发应用程序的时候,我们需要解决现实中遇到的问题,而这些问题可能在Spark中没有相应的API提供,这时候,我们就需要通过扩展Spark API来实现我们自己的方法。
我们可以通过两种方法来扩展Spark API,(1)、其中一种就是在现有的RDD中添加自定义的方法;(2)、第二种就是创建属于我们自己的RDD。在这篇文章中,我将对这两种方法进行阐述,并赋予代码 。下面我就开始介绍第一种方法。
假如我们中有一些商品的销售数据,数据的格式是CSV的。为了简单起见,假如每行数据都是由id, customerId, itemId 以及itemValue四个字段组成,我们用SalesRecord来表示:
1 |
class SalesRecord(val id: String, |
2 |
val customerId: String, |
4 |
val itemValue: Double) extends Comparable[SalesRecord] |
所以我们可以将商品的销售数据进行解析,并存储到RDD[SalesRecord]中:
07 |
* 过往记忆博客,专注于hadoop、hive、spark、shark、flume的技术博客,大量的干货 |
08 |
* 过往记忆博客微信公共帐号:iteblog_hadoop |
11 |
val sc = new SparkContext(args(0), "iteblogRDDExtending") |
13 |
val salesRecordRDD = dataRDD.map(row => { |
14 |
val colValues = row.split(",") |
15 |
new SalesRecord(colValues(0),colValues(1), |
16 |
colValues(2),colValues(3).toDouble) |
如果我们想计算出这些商品的总销售额,我们会这么来写:
1 |
salesRecordRDD.map(_.itemValue).sum |
虽然这看起来很简洁,但是理解起来却有点困难。但是如果我们可以这么来写,可能会很好理解:
1 |
salesRecordRDD.totalSales |
在上面的代码片段中,totalSales方法让我们感觉就是Spark内置的操作一样,但是Spark是不提供这个方法的,我们需要在现有的RDD中实现我们自定义的操作。
下面我就来介绍一些如何在现有的RDD中添加我们自定义的方法。
一、定义一个工具类,来存放我们所有自定义的操作
当然,你完全没必要自定义一个类类添加我们自定义的方法,但是为了管理,还是建议你这么做。下面我们来定义IteblogCustomFunctions类,它存储所有我们自定义的方法。它是专门用来处理RDD[SalesRecord],所以这个类中提供的操作全部是用来处理销售数据的:
1 |
class IteblogCustomFunctions(rdd:RDD[SalesRecord]) { |
2 |
def totalSales =rdd.map(_.itemValue).sum |
二、隐形转换来实现在RDD中添加方法
我们定义了隐形的addIteblogCustomFunctions函数,这可以将所有操作销售数据的方法作用于RDD[SalesRecord]上:
07 |
* 过往记忆博客,专注于hadoop、hive、spark、shark、flume的技术博客,大量的干货 |
08 |
* 过往记忆博客微信公共帐号:iteblog_hadoop |
11 |
object IteblogCustomFunctions { |
12 |
implicit def addIteblogCustomFunctions(rdd: RDD[SalesRecord]) = new |
13 |
IteblogCustomFunctions(rdd) |
三、使用自定义的方法
下面方法通过导入IteblogCustomFunctions 中的相应方法来实现使用我们自定义的方法:
1 |
import IteblogCustomFunctions._ |
2 |
println(salesRecordRDD.totalSales) |
通过上面三步我们就可以在现有的RDD中添加我们自定义的方法。
自定义一个RDD类
在上文中我介绍了如何在现有的RDD中添加自定义的函数。本文将介绍如何自定义一个RDD类,假如我们想对没见商品进行打折,我们想用Action操作来实现这个操作,下面我将定义IteblogDiscountRDD类来计算商品的打折,步骤如下:
一、创建IteblogDiscountRDD类
自定义RDD类需要继承Spark中的RDD类,并实现其中的方法:
07 |
* 过往记忆博客,专注于hadoop、hive、spark、shark、flume的技术博客,大量的干货 |
08 |
* 过往记忆博客微信公共帐号:iteblog_hadoop |
10 |
classIteblogDiscountRDD(prev:RDD[SalesRecord],xxxxx:Double) |
11 |
extends RDD[SalesRecord](prev){ |
14 |
override def compute(split: Partition, context: TaskContext): Iterator[SalesRecord] = { |
15 |
firstParent[SalesRecord].iterator(split, context).map(salesRecord => { |
16 |
val discount = salesRecord.itemValue*discountPercentage |
17 |
new SalesRecord(salesRecord.id, |
18 |
salesRecord.customerId,salesRecord.itemId,discount) |
22 |
override protected def getPartitions: Array[Partition] = |
23 |
firstParent[SalesRecord].partitions |
上面代码中,我创建了一个IteblogDiscountRDD类,这个RDD只操纵销售数据,当我们继承RDD类时,我们必须重载两个方法:
compute
这个函数是用来计算RDD中每个的分区的数据,在我代码中,我们输入了销售数据,并对其中的数据计算打折计算。
getPartitions
getPartitions函数允许开发者为RDD定义新的分区,在我们的代码中,并没有改变RDD的分区,重用了父RDD的分区。
定义IteblogDiscountRDD的时候将类型写死了(SalesRecord),它只能用来处理SalesRecord数据。如果我们想定义一个通用的RDD,只需要类似下面写即可
01 |
classIteblogRDD(prev:RDD[T],XXXX:C) |
05 |
override def compute(split: Partition, context: TaskContext): Iterator[T] = { |
06 |
................................ |
10 |
override protected def getPartitions: Array[Partition] = |
11 |
................................ |
二、自定义discount函数
我们自定义discount函数,该函数可以创建一个IteblogDiscountRDD:
1 |
def discount(discountPercentage:Double) = new IteblogDiscountRDD(rdd,discountPercentage) |
三、使用IteblogDiscountRDD
使用IteblogDiscountRDD也是非常简单的,我们可以像使用内置的RDD一样来使用:
1 |
import IteblogCustomFunctions._ |
3 |
val discountRDD = salesRecordRDD.discount(0.1) |
4 |
println(discountRDD.collect().toList) |
自此,我们已经学会了如何在现有的RDD中定义方法和自定义自己的RDD。
- Spark RDD API详解(一) Map和Reduce
RDD是什么? RDD是Spark中的抽象数据结构类型,任何数据在Spark中都被表示为RDD.从编程的角度来看,RDD可以简单看成是一个数组.和普通数组的区别是,RDD中的数据是分区存储的,这样不同 ...
- Spark RDD API具体解释(一) Map和Reduce
本文由cmd markdown编辑.原始链接:https://www.zybuluo.com/jewes/note/35032 RDD是什么? RDD是Spark中的抽象数据结构类型,不论什么数据在S ...
- Spark RDD API详解之:Map和Reduce
RDD是什么? RDD是Spark中的抽象数据结构类型,任何数据在Spark中都被表示为RDD.从编程的角度来看, RDD可以简单看成是一个数组.和普通数组的区别是,RDD中的数据是分区存储的,这样不 ...
- Spark RDD API(scala)
1.RDD RDD(Resilient Distributed Dataset弹性分布式数据集)是Spark中抽象的数据结构类型,任何数据在Spark中都被表示为RDD.从编程的角度来看,RDD可以简 ...
- spark (java API) 在Intellij IDEA中开发并运行
概述:Spark 程序开发,调试和运行,intellij idea开发Spark java程序. 分两部分,第一部分基于intellij idea开发Spark实例程序并在intellij IDEA中 ...
- 且谈 Apache Spark 的 API 三剑客:RDD、DataFrame 和 Dataset
作者:Jules S. Damji 译者:足下 本文翻译自 A Tale of Three Apache Spark APIs: RDDs, DataFrames, and Datasets ,翻译已 ...
- Spark RDD/Core 编程 API入门系列之动手实战和调试Spark文件操作、动手实战操作搜狗日志文件、搜狗日志文件深入实战(二)
1.动手实战和调试Spark文件操作 这里,我以指定executor-memory参数的方式,启动spark-shell. 启动hadoop集群 spark@SparkSingleNode:/usr/ ...
- Spark RDD/Core 编程 API入门系列之map、filter、textFile、cache、对Job输出结果进行升和降序、union、groupByKey、join、reduce、lookup(一)
1.以本地模式实战map和filter 2.以集群模式实战textFile和cache 3.对Job输出结果进行升和降序 4.union 5.groupByKey 6.join 7.reduce 8. ...
- Apache Spark 2.2.0 中文文档 - Spark RDD(Resilient Distributed Datasets)论文 | ApacheCN
Spark RDD(Resilient Distributed Datasets)论文 概要 1: 介绍 2: Resilient Distributed Datasets(RDDs) 2.1 RDD ...
随机推荐
- 【58沈剑架构系列】细聊分布式ID生成方法
一.需求缘起 几乎所有的业务系统,都有生成一个记录标识的需求,例如: (1)消息标识:message-id (2)订单标识:order-id (3)帖子标识:tiezi-id 这个记录标识往往就是数据 ...
- vue引入自己写的js文件
话不多说,直接上代码呀~ 先来个结构图: 中规中矩的vue-cli就写了一个自己的js文件 那么我想要引入到vue组件里. 1.首先写我的js文件 2.引入到vue组件!!!一定要用{}把方法名拿过来 ...
- 使用 Java 查找字符串中出现次数最多的字符以及出现的次数?
使用 Java 查找字符串中出现次数最多的字符以及出现的次数? import java.util.HashMap; import java.util.Map; public class TestStr ...
- OOD沉思录 --- 类和对象的关系 --- 使用关系原则
4.1 尽量减少类的协作的数量,即减少使用者和被使用者的数量. 协作意味着一定程度的耦合,但是完全没有协作的类也是没有意义的,最多只能作为一个库使用. 通过抽象,依赖接口,可以最大程度减少依赖的实现类 ...
- 转:gcc编译C++程序
转:http://blog.csdn.net/liujiayu2/article/details/49864381 单个源文件生成可执行程序 下面是一个保存在文件 helloworld.cpp 中一个 ...
- shell top解析
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器. top显示系统当前的进程和其他状况,是一个动态显示过程,即可以通过用户按键来不 ...
- TCP/IP——基础概念简记
TCP/IP协议族的分层: 应用层 运输层 网络层 链路层 互联网地址(IP地址):互联网上的每个接口必须有一个唯一的Internet地址,它一定的结构,分为ABCDE五类.A类保留给政府机构,B类分 ...
- java基础小测试
1.JDK,JRE,JVM三者的区别 jdk:java 开发工具包 jre:运行环境 jvm:虚拟机 2.javac的作用 ,反编译工具的作用 javac:将java文件编译成class文件 反编译: ...
- Web应用程序信息收集工具wig
Web应用程序信息收集工具wig 很多网站都使用成熟的Web应用程序构建,如CMS.分析网站所使用的Web应用程序,可以快速发现网站可能存在的漏洞.Kali Linux新增加了一款Web应用程序信 ...
- RxSwift 系列(六)
前言 本篇文章将要学习RxSwift中数学和集合操作符,在RxSwift中包括了: toArray reduce concat toArray 将一个Observable序列转化为一个数组,并转换为一 ...