原文链接:
我们都知道,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 |
class IteblogDiscountRDD(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 |
class IteblogRDD(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 ...
随机推荐
- Ubuntu下Node.js开发起步之旅
因为忙其它的事,把Node.js的学习放下了快两个月了,世事变化还真快,发现很多东东都改变了,express已经升级到4.x了,变化还不小! 我原来的学习过程是在VirtualBox中安装Ubuntu ...
- openldap quick start guide
openldap 2.4 在centos 7 x64系统上部署 1 下载源码编译解压tar -xvf xx ./configure make && make install 2 更改配 ...
- web学习测试环境
ref:https://www.owasp.org/index.php/OWASP_Vulnerable_Web_Applications_Directory_Project/Pages/Offlin ...
- Java线程池使用和常用参数(待续)
线程池怎么实现的,核心参数讲一讲? Executors是线程池的工厂类,通过调用它的静态方法如下: Executors.newCachedThreadPool(); Executors.newFixe ...
- 2017 计蒜之道 初赛 第五场 B. UCloud 的安全秘钥(简单)
暴力. 暴力枚举$S$串的每一个长度为$m$的子串,排序判断即可. #include <iostream> #include <cstdio> #include <cst ...
- 洛谷P1404 平均数 [01分数规划,二分答案]
题目传送门 平均数 题目描述 给一个长度为n的数列,我们需要找出该数列的一个子串,使得子串平均数最大化,并且子串长度>=m. 输入输出格式 输入格式: N+1行, 第一行两个整数n和m 接下来n ...
- Java变量和运算符
1.变量 变量概述 什么是变量?变量是一个内存中的小盒子(小容器),容器是什么?生活中也有很多容器,例如水杯是容器,用来装载水:你家里的大衣柜是容器,用来装载衣裤:饭盒是容器,用来装载饭菜.那么变量是 ...
- redis_NoSql数据库四大分类
前面简单介绍了什么是NoSql,以及NoSql的应用场景,今天简单来学习一下NoSql的分类 一.KV键值对 典型的介绍:新浪(BerkeleyDB+redis).美团(redis+tair).阿里, ...
- NYOJ 298 点的变换 矩阵乘法
http://acm.nyist.net/JudgeOnline/problem.php?pid=298 最好还是自己手推一下矩阵式子..不算太难..但是有一些小知识.... 首先当然是矩阵的细节.. ...
- 【tarjan】BZOJ2140-稳定婚姻
又名NTR的故事 [题目大意] n对夫妻Bi和Gi.若某男Bi与某女Gj曾经交往过,他们有私奔的可能性.不妨设Bi和Gj旧情复燃,进而Bj会联系上了他的初恋情人Gk,以此递推.若在Bi和Gi离婚的前提 ...