第2章 Spark分布式执行涉及的组件

每个Spark应用都由一个驱动程序来发起集群上的各种并行操作,驱动程序通过一个SparkContext对象访问Spark;驱动程序管理多个执行器节点,可以用SparkContext来创建RDD。

第3章 RDD(Resilient Distributed Dataset:弹性分布式数据集)

RDD特点

  • Spark中,对数据的所有操作不外乎:创建RDD、转化已有RDD、调用RDD操作进行求值。
  • Spark会自动将RDD中的数据分发到集群上,并将操作并行化执行。
  • Spark中的RDD是一个不可变的分布式对象集合
  • RDD一旦创建就无法修改

RDD两种创建方法

  • 读取一个外部数据集。如sc.textFile("readme.md")
  • 在驱动程序里分发驱动程序的对象集合(如list、set)。即把程序中一个已有集合传递给SparkContext的parallelize()方法。这种方法用的并不多,因为需要把整个数据集先放在一台机器的内存中。

RDD支持两种类型的操作——之一:转化操作(transform)

  • 返回一个新的RDD的操作。
  • 许多转化操作是针对各个元素的,但并不是所有的转化操作都是这样的。
  • 常用转化操作filter():接收一个函数,并将RDD中满足该函数的元素组成新的RDD。
  • 常用转化操作map():接收一个函数,把函数作用于RDD每个元素,所有函数返回结果组成了新的RDD。
  • 还有一些伪集合操作:RDD中最常缺失的集合属性就是元素的唯一性。可以用RDD.distinct()来生成一个只包含不同元素的新RDD。但distinct的开销很大,因为所有数据需要经过网络进行混洗(shuffle).

RDD支持两种类型的操作——之二:行动操作 (action)

  • 向驱动器程序返回结果或把结果写入外部系统的操作,会触发实际的计算。默认情况下,Spark的RDD会在每次对它们进行行动操作时重新计算。如果想在多个行动操作时重用同一个RDD,可以使用RDD.persist()把这个RDD缓存起来(持久化)。
  • RDD有一个collect(),可以用来获取整个RDD中的数据,但这要求RDD的数据是较小规模的。
  • 常用行动函数reduce():接收一个函数作为参数,这个函数要操作两个相同类型的RDD数据并返回一个同样类型的新元素。一个简单的例子就是函数“+”。
  • 比如count()

RDD支持两种类型的操作——相关

  • 转化操作和行动操作的区别:计算RDD的方式不同:Spark只会惰性计算RDD:即所有转化操作只有第一次在一个行动操作中用到时,才会真正计算涉及到的转化和行动操作。
  • 惰性求值:“我们不应把RDD看作存放着特定数据的数据集,而最好把每个RDD当作我们通过转化操作构建出来的、记录如何计算数据的指令列表

第4章 之 Pair RDD及相关操作

Pair RDD

Pair RDD也还是RDD,在Scala存储为Tuple2对象。

创建Pair RDD

方法一:很多存储键值对的数据格式会在读取时直接返回pair RDD。

方法二:若需要把普通RDD转为pair RDD,可调用map(),传递的函数需要返回键值对。

Pair RDD的转化操作

聚合:

reduceByKey(func) 合并具有相同键的值

foldByKey(func)

combineByKey(...) 合并具有相同键的值 ,参数比较重要,待继续理解?

分组:

groupByKey()

cogroup ,针对两个Pair RDD的操作

连接:

join

rightOuterJoin 右外连接,保留右侧全部,具体形式见书。

leftouterJoin

根据值筛选:

mapValues(func) 功能类似于map{case (x,y):(x, func(y))}

数据排序:

sortByKey()

Pair RDD行动操作

和转化操作一样,所有基础RDD支持的行动操作也都在Pair RDD上可用。此外Pair RDD 提供了一些额外的行动操作。

第4章 之 数据分区

  • Spark程序可以通过控制RDD分区方式来减少开销,当然这只针对于当数据集有多次连接等基于键的操作时,分区才会有帮助。

    • 具体的,默认情况下,连接操作会将两个数据集中的所有键的哈希值都求出来,将该哈希值相同的记录通过网络传到同一台机器,然后在那台机器上对所有键相同的记录进行连接操作。这样每次连接都要使两边数据混洗,产生的网络通信造成许多额外开销。特别的,若含静态数据(不更改),则每次连接都将进行一次混洗,这是不必要的。
    • 这种情况下,可以预先将一边的静态数据进行hash分区,将避免这一边的混洗。
  • Spark中所有键值对RDD都可以进行分区

分区操作(重点)

  • 事实上,许多Spark操作会自动为结果RDD设定已知的分区方式信息,比如sortByKey()和groupByKey()会分别生成范围分区的RDD和哈希分区的RDD;join等操作会利用到已有的分区信息;另外,map这样的操作会导致新的RDD失去父RDD的分区信息,因为该操作理论上会改变RDD的键。
  • partitionBy()转化操作:其中可以传入testRdd.partitonBy(new HashPartitioner(100))表示使用哈希分区,构造100个分区;RangePartitioner则表示范围分区。此外,要考虑是否在partitionBy()后面接一个persist(),如果后续操作使用这个结果RDD,则应该加,否则当有行动操作时,会一次次执行partitionBy(),导致又在这个层次一遍遍地进行哈希分区操作。
  • 也可以使用自定义的分区器,需要继承org.apache.spark.Partitioner类并实现三个方法。

获取RDD的分区方式

使用RDD的partitioner属性可以获取RDD的分区方式,返回的是scala.Option对象(Scala一个存放可能存在的对象的容器类),Option对象的isDefined方法可以检查其中是否有值,get可以获取其中的值。

从分区获益的操作

Spark中引入将数据根据键进行混洗的过程的那些操作,都会从数据分区中获益。

从分区获益的操作有cogroup()、groupWith()、三种连接、groupByKey()、reduceByKey()、combineByKey()、lookup()

影响分区方式的操作

  • Spark内部知道各操作会如何影响分区,并将会对数据分区的操作的结果RDD自动设置为对应的分区器。
  • 另外,对于二元操作,输出数据的分区方式取决于父RDD的分区方式。若两个父RDD都没设置分区方式,则结构默认采用哈希分区,分区数量和操作并行度一样,若有一个父RDD设置了则随父,若两个父RDD都设置了则随第一个。
  • 为结果RDD设好分区方式的操作列表见P57。
  • 为了最大化分区相关的潜在作用,应该在无需改变元素的键时尽量使用mapValues()flatMapValues()。(使用mapValues()而不是map()来保留父RDD的分区方式,在后续可能会减少开销)。

[Spark快速大数据分析]阅读笔记的更多相关文章

  1. [spark 快速大数据分析读书笔记] 第一章 导论

    [序言] Spark 基于内存的基本类型 (primitive)为一些应用程序带来了 100 倍的性能提升.Spark 允许用户程序将数据加载到 集群内存中用于反复查询,非常适用于大数据和机器学习. ...

  2. spark快速大数据分析学习笔记*初始化sparkcontext(一)

    初始化SparkContext 1// 在java中初始化spark import org.apache.spark.SparkConf; import org.apache.spark.api.ja ...

  3. Spark快速大数据分析之RDD基础

    Spark 中的RDD 就是一个不可变的分布式对象集合.每个RDD 都被分为多个分区,这些分区运行在集群中的不同节点上.RDD 可以包含Python.Java.Scala中任意类型的对象,甚至可以包含 ...

  4. 《Spark快速大数据分析》—— 第五章 数据读取和保存

    由于Spark是在Hadoop家族之上发展出来的,因此底层为了兼容hadoop,支持了多种的数据格式.如S3.HDFS.Cassandra.HBase,有了这些数据的组织形式,数据的来源和存储都可以多 ...

  5. 《Spark快速大数据分析》—— 第六章 Spark编程进阶

    这章讲述了Spark编程中的高级部分,比如累加器和广播等,以及分区和管道...

  6. 《spark快速大数据分析》

    第一 概论 1.spark的特点 适用多种不同分布式平台的场景,包括批处理,迭代算法,交互式查询,流处理: spark提供了python,scale,java等接口 2.spark的组件 spark的 ...

  7. spark快速大数据分析

    从上层来看,每个Spark 应用都由一个驱动器程序(driver program)来发起集群上的各种并行操作.驱动器程序包含应用的main 函数,并且定义了集群上的分布式数据集,还对这些分布式数据集应 ...

  8. 关于《Spark快速大数据分析》运行例子遇到的报错及解决

    一.描述 在书中第二章,有一个例子,构建完之后,运行: ${SPARK_HOME}/bin/spark-submit --class com.oreilly.learningsparkexamples ...

  9. 《Spark快速大数据分析》—— 第三章 RDD编程

随机推荐

  1. 极简 Node.js 入门 - 2.4 定时器

    极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...

  2. 【面经】超硬核面经,已拿蚂蚁金服Offer!!

    写在前面 很多小伙伴都反馈说,现在的工作不好找呀,也不敢跳槽,在原来的岗位上也是战战兢兢!其实,究其根本原因,还是自己技术不过关,如果你技术真的很硬核,怕啥?想去哪去哪呗!这不,我的一个读者去面试了蚂 ...

  3. Orcal语法Merge into用法

    Orcal语法 Merge into 1.语法介绍 MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句.通过MERGE语句,根据一张表或子查询的连接条件对另外一张表进行 ...

  4. 在 Go 语言中,我为什么使用接口

    强调一下是我个人的见解以及接口在 Go 语言中的意义. 如果您写代码已经有了一段时间,我可能不需要过多解释接口所带来的好处,但是在深入探讨 Go 语言中的接口前,我想花一两分钟先来简单介绍一下接口. ...

  5. 基于OpenSIPS 实现分机注册服务服务器

    呼叫中心平台中坐席是不可或缺的一环,而坐席打电话自然需要使用办公分机.通常情况下我们通过软交换平台FreeSWITCH.Asterisk即可搭建分机注册服务. 但单台FreeSWITCH或Asteri ...

  6. 利用C#实现OPC-UA服务端

    前言 最近接手了一个项目,做一个 OPC-UA 服务端?刚听到这个消息我是一脸懵,发自灵魂的三问“OPC-UA是什么?”.“要怎么做?”.“有什么用?”.我之前都是做互联网相关的东西,这种物联网的还真 ...

  7. 使用BurpSuite、Hydra和medusa爆破相关的服务

    一.基本定义 1.爆破=爆破工具(BP/hydra)+字典(用户字典/密码字典). 字典:就是一些用户名或者口令(弱口令/使用社工软件的生成)的集合. 2.BurpSuite 渗透测试神器,使用Jav ...

  8. 完全基于 Java 的开源深度学习平台,亚马逊的大佬带你上手

    本文适合有 Java 基础的人群 作者:DJL-Lanking HelloGitHub 推出的<讲解开源项目>系列.有幸邀请到了亚马逊 + Apache 的工程师:Lanking( htt ...

  9. pandas 数据库数据的读取

    绝大多数公司都会选择将数据存入数据库中,因为数据库既可以存放海量数据,又可以非常便捷地实现数据的查询.下面以MySQL和SQL Server为例,来练习Pandas模块和 对应的数据库模块. 首先需要 ...

  10. 关于C#.WinForm 与 WinApi的SendMessage 方法

    介绍: Windows Api 的 SendMessage 该函数将指定的消息发送到一个或多个窗口.此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回.而和函数PostMessage不同,P ...