RDD(五)——action
reduce(func)
通过func函数聚集RDD中的所有元素并得到最终的结果,先聚合分区内数据,再聚合分区间数据。Func函数决定了聚合的方式。
def main(args: Array[String]): Unit = {
val sc: SparkContext = new SparkContext(new SparkConf().
setMaster("local[*]").setAppName("spark"))
val value: RDD[Int] = sc.makeRDD(Array(1,2,3))
val result: Int = value.reduce(_ + _)
println(result)
val value1: RDD[(String, Int)] = sc.makeRDD(Array(("a", 1), ("b", 2), ("c", 3)))
val tuple: (String, Int) = value1.reduce((x: (String, Int), y: (String, Int)) => (x._1 + y._1, x._2 + y._2))
println(tuple)
}
打印结果为:
6
cba 6
collect()案例
在驱动程序中,以数组的形式返回数据集的所有元素。数组的元素类型为RDD的元素类型;
count()案例
返回RDD中元素的个数
val value: RDD[Int] = sc.makeRDD(Array(1,2,3))
println(value.count())
first()、take()
first返回RDD中的第一个元素
take返回一个由RDD的前n个元素组成的数组
从first的原码来看,它底层是由take实现的;
def first(): T = withScope {
take(1) match {
case Array(t) => t
case _ => throw new UnsupportedOperationException("empty collection")
}
}
查看take的原码及其注释,原码目前看不大懂,应该是去取出相应个数的分区,将分区中的元素装配成数组,再返回该数组。所以可以这么理解:first取出的是第一个分区的第一个元素,take取出的是前x个分区的n个元素;
/**
* Take the first num elements of the RDD. It works by first scanning one partition, and use the
* results from that partition to estimate the number of additional partitions needed to satisfy
* the limit.
*
* @note This method should only be used if the resulting array is expected to be small, as
* all the data is loaded into the driver's memory.
*
* @note Due to complications in the internal implementation, this method will raise
* an exception if called on an RDD of `Nothing` or `Null`.
*/
def take(num: Int): Array[T] = withScope {
...
}
示例代码如下:
def main(args: Array[String]): Unit = {
val sc: SparkContext = new SparkContext(new SparkConf().
setMaster("local[*]").setAppName("spark"))
val value: RDD[Int] = sc.makeRDD(Array(3,6,4,5,8,1,2,0),4);
value.saveAsTextFile("E:/idea/spark2/out/take")
println(value.first())
value.take(3).foreach(println)
}
数据在分区的分布如下:
36 45 81 20
first取出的元素是3;
take取出的元素是364
印证了上述的函数执行逻辑;
takeOrdered(n)
返回该RDD排序(升序)后的前n个元素组成的数组
aggregate
参数:(zeroValue: U)(seqOp: (U, T) ⇒ U, combOp: (U, U) ⇒ U)
作用:aggregate函数将每个分区里面的元素通过seqOp和初始值进行聚合,然后用combine函数将每个分区的结果和初始值(zeroValue)进行combine操作。这个函数最终返回的类型不需要和RDD中元素类型一致。(分区内要与初始值进行聚合操作,分区间也要与初始值进行聚合操作)与reduce算子相比,aggregate能分别控制分区间和分区内的运算。
def main(args: Array[String]): Unit = {
val sc: SparkContext = new SparkContext(new SparkConf().
setMaster("local[*]").setAppName("spark"))
val value: RDD[Int] = sc.makeRDD(Array(1, 2, 3, 4), 4)
val i: Int = value.aggregate(0)(_ + _, _ + _)//它这里的函数类型是可以推断出来的
println(i)
}
打印结果为10;
fold(num)(func)
折叠操作,aggregate的简化操作,seqop和combop一样。
countByKey()
针对(K,V)类型的RDD,返回一个(K,Int)的map,表示每一个key对应的元素个数。
def main(args: Array[String]): Unit = {
val sc: SparkContext = new SparkContext(new SparkConf().
setMaster("local[*]").setAppName("spark"))
val value: RDD[(String, Int)] = sc.parallelize(Array(("a", 3), ("a", 2),("b",1)))
val result: collection.Map[String, Long] = value.countByKey()
result.foreach(println)
}
打印结果为:
(a,2)
(b,1)
foreach(func)
在数据集的每一个元素上,运行函数func进行更新。
def main(args: Array[String]): Unit = {
val sc: SparkContext = new SparkContext(new SparkConf().
setMaster("local[*]").setAppName("spark"))
val raw: RDD[Int] = sc.makeRDD(Array(1, 2, 3, 4), 4);//driver端执行
val ints: Array[Int] = raw.collect()
ints.foreach(x => {println(x+1)})//在driver端执行
raw.foreach(x => {println(x+1)})//在executor端执行
}
}
foreachPartition()
在数据集的每一个分区上,运行函数func()进行更新。它与foreach的源码如下:
/**
* Applies a function f to all elements of this RDD.
*/
def foreach(f: T => Unit): Unit = withScope {
val cleanF = sc.clean(f)
sc.runJob(this, (iter: Iterator[T]) => iter.foreach(cleanF))
} /**
* Applies a function f to each partition of this RDD.
*/
def foreachPartition(f: Iterator[T] => Unit): Unit = withScope {
val cleanF = sc.clean(f)
sc.runJob(this, (iter: Iterator[T]) => cleanF(iter))
}
他们之间的性能区别类似于map与mapPartition。更详细的例子见博客《JdbcRDD连接MySQL》
RDD(五)——action的更多相关文章
- 关于spark RDD trans action算子、lineage、宽窄依赖详解
这篇文章想从spark当初设计时为何提出RDD概念,相对于hadoop,RDD真的能给spark带来何等优势.之前本想开篇是想总体介绍spark,以及环境搭建过程,但个人感觉RDD更为重要 铺垫 在h ...
- Spark RDD概念学习系列之Pair RDD的action操作
不多说,直接上干货! Pair RDD的action操作 所有基础RDD 支持的行动操作也都在pair RDD 上可用
- spark transform操作卡死,请先对rdd进行action操作
这两天一直在写spark程序,遇到了一个奇怪的问题. 问题简单描述如下,有两个RDD,设为rdd_a,rdd_b,当将这两个rdd合并的时候,spark会在运行中卡死. 解决方式也是奇葩. 只要在合并 ...
- Struts(五)Action的访问
在struts开发中,Action作为框架的核心类,实现对用户的请求的处理,Action被称为业务逻辑控制器.一个Action类代表一次请求或调用.Action就是用来处理一次用户请求的对象 Acti ...
- Struts2(五)Action二配置
一.method参数 action package com.pb.web.action; public class HourseAction { public String add(){ System ...
- vuex 源码分析(五) action 详解
action类似于mutation,不同的是Action提交的是mutation,而不是直接变更状态,而且action里可以包含任意异步操作,每个mutation的参数1是一个对象,可以包含如下六个属 ...
- PLAY2.6-SCALA(五) Action的组合、范围的设置以及错误的处理
一.自定义action 从一个日志装饰器的例子开始 1.在invokeBlock方法中实现 import play.api.mvc._ class LoggingAction @Inject() (p ...
- 五 Action访问方法,method配置,通配符(常用),动态
1 通过method配置(有点low) 建立前端JSP:demo4.jsp <%@ page language="java" contentType="text/h ...
- Struts2学习笔记(五)——Action访问Servlet API
在Strut2中访问Servlet API有三种方式: 1.通过ActionContext访问Servlet API,推荐使用这种,但是这种方案它获取的不是真正的事Servlet API. 步骤: 1 ...
随机推荐
- JS常用的正则表达式包
结构: Code: /* 用途:检查输入的Email信箱格式是否正确 输入:strEmail:字符串 返回:如果通过验证返回true,否则返回false */ function checkEmail( ...
- https://www.jianshu.com/p/fc78dab5736f
在学习Swift 3的过程中整理了一些笔记,如果想看其他相关文章可前往<Swift 3必看>系列目录 swift 3中对C层级的GCD的API进行了彻头彻尾的改变.本文将从实际使用场景来了 ...
- 禁用 Bootstrap 模态框(Modal) 点击空白时自动关闭
在做项目的时候,来了这么一个需求,要求打开模态框后,点击空白的地方不让他自动关闭,只能点击关闭按钮才能关闭. 有了需求,就开始查找资料寻求解决的方法. 我找到的解决方法如下: $('#registCo ...
- CSS绘制小三角
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 寒假day22
今天解决了标签模块的一些错误,同时美化了界面
- .equal()和==的区别
1.首先,equal和==最根本的区别在于equal是一个方法,而==是一个运算符. 2.一般来说,==运算符比较的是在内存中的物理地址,.equal()比较的是哈希算法值是否相等(即hashcode ...
- 技术沙龙|原来落地AI应用是这么回事儿!
目前人工智能已经迈入应用落地之年,作为备受关注的话题,在重磅政策的加持下市场规模迅速扩大并渗透到各行各业的形势越发鲜明.在此背景下,作为国内不容忽视的创新企业之一,京东AI依托于NeuHub平台对数据 ...
- rabbitmq设置队列消息存活时间
public static final int ALIVETIME = 600000; public static final String QUEUE = "hnyz_gs_queue&q ...
- 吴裕雄--天生自然Django框架开发笔记:Django简介
Python下有许多款不同的 Web 框架.Django是重量级选手中最有代表性的一位.许多成功的网站和APP都基于Django. Django是一个开放源代码的Web应用框架,由Python写成. ...
- 吴裕雄--天生自然MySQL学习笔记:MySQL 复制表
如果需要完全的复制MySQL的数据表,包括表的结构,索引,默认值等. 如果仅仅使用CREATE TABLE ... SELECT 命令,是无法实现的. 如何完整的复制MySQL数据表,步骤如下: 使用 ...