<Spark><Programming><RDDs>
Introduction to Core Spark Concepts
- driver program:
- 在集群上启动一系列的并行操作
- 包含应用的main函数,定义集群上的分布式数据集,操作数据集
- 通过SparkContext对象访问spark,这表示了与计算集群的连接
- executors:
- the place to run the operations
- Spark automatically takes ur function and ships it to executor nodes.
Programming with RDDs
- RDD: spark's core abstraction for working with data.
- RDD简单来说就是元素的分布式集合
- 在Spark中所有的工作都可以表示成创建一个新的RDDs,转换已有的RDDs,或者是在RDDs上运行operations
RDD Basics
- An immutable distributed collection of objects.
- 每个RDD被split成多个partitions,每个partition可能在cluster的不同节点上被计算
- RDD的创建:
- loading一个外部数据集
- distributing对象集合(eg: a list or set)
- transformations:从原RDD创建一个新的RDD
- actions:基于RDD计算一个result,这个结果要么返回给driver program,要么存储到外部存储系统(eg: HDFS)
- RDD.persist():由于缺省情况下,每次运行action的时候RDDs是重新计算的。如果对RDD进行persist,那么该RDD会persist到内存(或disk),下次action的时候可以reuse。
RDD操作:(区分这两种操作的原因是Spark的计算是lazy fashion的
Creating RDDs
- parallelize()
val lines = sc.parallelize(List("pandas", "I like pandas"))
- textFile()
val lines = sc.textFile("/path/to/README.md")
RDD Operations
- Transformation & Action
Transformations
- Compute lazily
- 没有改变原RDD(immutable),而是生成了新的RDD,spark会保存这一系列依赖关系(lineage)
Actions
- Actually do something with our dataset
Passing Functions to Spark
- Scala: we can pass in functions defined inline, references to methods, or static functions
- Scala: 我们所传送的函数和其中的数据引用需要被序列化(实现Java的Serializable接口)
- 如果我们pass一个对象中的函数,或者包含了对象中的字段的引用(eg: self.field),spark会把整个对象发送给worker nodes,这会远大于你所需要的信息。并且如果你的对象不能持久化(pickle in python)的话,会导致是你的程序失败。举一个python的例子:
错误示范如下:
正确示范:(提取对象中你所需的字段为局部变量,然后传进去)
- 同样的,对scala我们也要尽量避免上述情况,而且要注意的是在scala中不需要显示的self.或者this.,所以这种情况显得很不明显,但仍然要注意。举个栗子
如果在scala中出现了NotSerializableException,那么多半是因为引用了一个不可序列化的类中的变量或字段。所以,传送一个局部的可序列化的变量或函数才是安全的。
- Any code that is shared by RDD transformations must always be serializable.
Common Transformations and Actions
Basic RDDs
- 我们首先介绍基本的RDD操作,它们可以执行在所有RDDs上而不用管数据
Element-wise transformations
- map() and filter()
- flatMap(): 为每一个输入元素产生多个输出元素。返回的是一个迭代器iterator
val lines = sc.parallelize(List("hello world", "hi"))
val words = lines.flatMap(line => line.split(" "))
Psedudo set operations
- 一些简单的集合操作:(需要RDDs是同一类型的)
- RDD1.distinct() --> 十分昂贵的操作,需要shuffle all data over the network
- RDD1.union(RDD2) --> 最简单的集合操作,会保留原RDD中的重复值
- RDD1.intersection(RDD2) --> 需要去重(来识别共同元素),因而也需要shuffle
- RDD1.substract(RDD2) --> perform shuffle
- RDD1.cartesian(RDD2) --> returns all possible pairs of (a, b) where a is in the source RDD and b is in the other RDD .十分昂贵
- 为什么叫psedudo即假的集合操作呢,因为这里的集合丢失了一个重要特性:uniqueness即元素的唯一性。因为我们经常有duplicates
Actions
- reduce() & fold() :都需要返回值和RDD中的元素保持同一类型。
fold()接收与reduce接收的函数签名相同的函数,另外再加上一个初始值作为第一次调用的结果.
val sum = rdd.reduce((x, y) => x + y)
- aggregate(): frees us from the constraint of having the return be the same types as the RDD we are working on.
aggregate的函数原型:
def aggregate [U: ClassTag] (zeroValue: U) (seqOp: (U,T)=>U,combOp: (U,U)=>U):U
可以看到,(zeroValue: U)是给定的一个初值,后半部分有两个函数,seqOp相当于是在各个分区里进行的聚合操作,它支持(U, T) => U,也就是支持不同类型的聚合。comOp是将sepOp后的结果聚合,此时的结果全部是U类,也就是只能进行同构聚合。
一个经典的例子是求平均值。即先用seqOp求出各个分区中的sum和个数,再将seqOp后的结果聚合得到总的sum和总的个数。
- collect(): 返回整个RDD中的内容,常用于单元测试,因为它需要你的整个数据集能够fit on a single machine.
- take(n): 返回RDD中的n个元素,并且试图最小化所访问的partition数,所以它可能会返回一个biased collection。
- takeSample(withReplacement, num, seed): allows us to take a sample of our data either with or without replacement.
- foreach(): 可以允许我们在每个元素上执行操作or计算,而不需要把元素送回driver
Converting Between RDD Types
- 一些functions只在某些特定类型RDD上可用。比如mean(), variance()只用于numericRDDs, join()只用于key/value pair RDDs.
- 在scala和Java中,这些方法未在标准RDD类中定义,因此为了访问这些附加的功能,我们需要确保我们得到了正确的specialized class。
Scala
- 在scala中。RDDs的转换可以通过使用隐式转换(using implicit conversions)来自动进行。
- 看一段RDD.scala源码中的介绍
- 关于scala隐式转换: 当对象调用类中不存在的方法或成员时,编译器会自动将对象进行隐式转换
- 隐式转换带来的confusion:当你在RDD上调用mean()这样的方法时,你会发现在RDDclass 的Scaladocs中找不到mean()方法,但是该方法能成功调用是由于实现了RDD[Double]到DoubleRDDFunctions的隐式转换。
Persistence(Caching)
- As discussed earlier, Spark RDDs是惰性求值的,如果我们想要多次使用同一个RDD的话,Spark通常会每次都重新计算该RDD和它所有的依赖。这对于迭代算法是十分昂贵的。
- 一个比较直观的例子如下,每次action的时候都会重新计算:
- 为了避免多次重复计算同一个RDD,我们可以让Spark来persist数据。这样的话,计算该RDD的那个节点会保存它们的partition。
- 如果有数据持久化的节点fail掉了,Spark会在需要的时候重新计算丢失的partitons。当然我们也可以通过在多个节点保存副本的方式来避免节点故障时的slowdown。
- Spark有很多levels of persistence供选择。
Level Space Used CPU time In Memory On Disk Comments MEMORY_ONLY
High Low Y N MEMORY_ONLY_SER
Low High Y N MEMORY_AND_DISK
High Medium Some Some Spils to disk if there is too much data to fit in memory. MEMORY_AND_DISK_SER
Low High Some Some Spills to disk if there is too much data to fit in memory. Stores serialized representation in memory.
DISK_ONLY
Low High N Y - 在Java和scala中,缺省的情况下persist()回将未序列化的对象数据保存在JVM的堆中。
- 如果你试图在内存中cache过多的数据,Spark将会自动驱逐旧的partitions,使用最少最近使用(Least Recently Used, LRU)缓存策略。对于MEMORY_ONLY level,下次访问的时候会重新计算这些被驱逐的分片。
- 由于Spark'的各种机制,无论使用哪种level,你都可以不用担心job breaking。但是缓存不必要的数据将会导致有用数据被驱逐,从而增加重计算的时间。
- Spark提供了unpersist()方法可以让你手工地将RDD移除缓存。
Off-heap caching is experimental and uses Tachyon. If you are interested in off-heap caching with Spark, take a look at the Running Spark on Tachyon guide.
<Spark><Programming><RDDs>的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- pytorch变量
下文中所使用的pytorch版本为1.0.1 在python,如果全局变量在函数中没有提前用global申明,就修改其值,结果是这个全局变量不会被修改,会在这个函数中另外产生一个局部变量(名字相同). ...
- 性能测试工具 Web Service 性能测试工具比较
[转自]https://testerhome.com/topics/3003 背景 希望选择一款Web Service性能测试工具,能真实模拟大量用户访问网站时的请求,从而获取服务器当前的请求处理能力 ...
- 代码版本控制[version control]之Git
如何多人协同开发同一个项目? 使用代码版本控制[version control]软件, 目前市面上比较流行的代码版本控制器有: git,svn,csv 1. 使用git管理代码版本 本项目使用git管 ...
- python基础之正则表达式 re模块
内容梗概: 1. 正则表达式 2. re模块的使⽤ 3. 一堆练习正则表达式是对字符串串操作的一种逻辑公式. 我们一般使用正则表达式对字符串进行匹配和过滤.使用正则的优缺点: 优点: 灵活,功能性强, ...
- python记录_day31 进程同步和进程通信
一.进程同步 1.同步锁(又叫互斥锁) 加锁的代码以后,同一时间内只能被一个进程执行 from multiprocessing import Process, Lock def fun(loc): l ...
- java getInstance()的使用
转自:https://www.cnblogs.com/roadone/p/7977544.html 对象的实例化方法,也是比较多的,最常用的方法是直接使用new,而这是最普通的,如果要考虑到其它的需要 ...
- python-day91--同源策略与Jsonp
一.同源策略 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础之 ...
- mysql 全文搜索(转载http://blog.csdn.net/manbujingxin/article/details/6656992)
前提:mysql只支持英文内容的全文索引,所以只考虑英文的全文搜索.假定数据表名为post,有三列:id.title.content.id是自增长序号,title是varchar,content是te ...
- ADG配置(主备库环境)
@font-face { font-family: "Courier New"; }@font-face { font-family: "宋体"; }@font ...
- 六、持久层框架(Hibernate)
一.乐观锁 Hibernate使用乐观锁来处理脏数据问题. 比如有这样一个制造脏数据的场景: 1.通过session1得到id=1的对象product1 2.在product1原来的价格基础上增加10 ...