spark使用方法(一)
来源:互联网 发布:如何查询淘宝购买记录 编辑:程序博客网 时间:2024/06/03 15:14
1、问题的起源
之前的集群计算系统都是基于非循环的数据流模型,即从稳定的物理存储系统加载记录,传给一组确定性操作构成的DAG,然后在将得到的结果写回存储系统。这种方式如果用在迭代计算中,或者是交互式查询中(即不断的在数据子集中筛选数据),此时会存在大量的读磁盘和写磁盘及网络传输。通信开销大,整个计算效率会很低。
2、RDD的提出
RDD(Resilient Distrubuted Dataset),即弹性分布式数据集。它主要通过两种手段克服上面提到的问题:一是允许将数据缓存到内存中,这样如果重用到此数据直接从内存读取即可;二是很多的RDD操作并不会马上运行出结果,而是将一系列转化记录下来即lineage。只有当遇到动作操作时才会出发计算。当然,lineage也能用于数据恢复。
我们可以从RDD的内部接口来窥探它的实现方式。
RDD只有转换操作和动作操作两种操作,转化操作只记录RDD之间的血统关系并不产生真正的计算;当动作操作触发真正的计算时,它是先由血统关系逐级往回,找到源头的RDD,这种源头可以是定义从节点磁盘上获取数据的RDD,也可以是中间已缓存到内存中的RDD,再由源头RDD逐级计算得到最终结果,而不需每一步都去计算和缓存。
转化操作或动作操作能够执行的基础是记录了RDD之间的依赖关系,依赖分为窄依赖和宽依赖,下图揭示了这两种依赖的景象。
区分这两种依赖:首先,窄依赖能够并行的在所有节点中进行,对于单个节点来讲,一系列的操作可以在节点内部以流水线的方式完成,如逐个元素进行map和filter,而宽依赖则需要计算好所有父分区数据,然后在节点之间shuffle,类似于reduce;其次,窄依赖更容易实现对故障节点的恢复,只需要计算丢失RDD分区的父分区,而且各节点可以并行进行,而宽依赖,单个节点的失效需要整体的重新计算。
熟悉各种RDD是窄依赖还是宽依赖非常重要,恰当选择合适的RDD组合来实现相同功能,会使应用的效率大大提升。
3、关于spark
spark是实现RDD这种思想的系统,并且可以用来开发多种并行应用。
要使用spark,必须编写驱动程序。一个驱动程序(也可以把它当成应用程序),包含一个到集群的连接,在python语言实现的驱动程序中用sparkcontext(),这个接口作用就跟连接数据库的jdbc一样或者文件读取的open()一样,我们可以对这个连接进行配置,比如连接到哪个集群;包含一系列的RDD,这些RDD是我们实现各种功能的基础;包含RDD上的动作,真正触发计算,缓存等操作,从而实现功能。
驱动程序的功能由集群中的worker来执行,在连接集群的时候会启动和运行这些worker,下图是一个简单示意图。
worker是长时运行的节点上的进程,worker从分布式文件系统读取数据块,并将计算后的RDD分区以java对象的形式缓存在内存中。worker之所以可以完成这些功能原因是spark系统把驱动程序的字节码分发到相应的节点了。
spark内部由调度器来为动作确定有效的执行计划,计划是根据RDD的结构信息来安排。调度器的接口是rubjob函数,参数是RDD及其分区,和分区上的函数。
调度器根据RDD的lineage图来创建一个由stage构成的有向无环图(DAG),如下图所示
上图中虚线表示stage,实线表示RDD,实心矩形表示分区(黑色表示该分区已被缓存),本例不再执行stage1,因为B已经存在于缓存中,只需执行stage2,stage3
在每一个stage内部尽可能的包含一组具有窄依赖关系的转化,并将它们流水线并行化。stage的边界有两种情况,一是宽依赖上的shuffle操作,这个很容易理解,因为宽依赖不可能实现流水线;二是已经缓存分区,已缓存分区直接取数就可以。
调度器根据数据存放的位置来分配任务,以最小化通信开销。如果某个任务需要处理已缓存的分区,则将该任务直接分配给该分区的节点;如果需要处理的分区位于多个可能的位置,则将该任务分配给一组节点。
对于宽依赖,目前的实现方式是在父分区的节点上将中间结果物化,简化容错处理。
如果某个任务失败,只要stage中父RDD分区可用,只需要在另一个节点上重新运行这个人员即可。如果某些stage不可用,则需要重新提交这个stage中所有的任务来恢复丢失的分区。
lookup动作允许从一个哈希分区或范围分区上的RDD根据关键字来读取一个数据元素。从这句话可以看到lookup是有使用单位的。只适用哈希或范围分区,行为有映射关系,就可以根据这种映射关系去寻找单个元素。
spark获取数据的方法
一是在驱动程序中对一个集合进行并行化,利用SparkContext()的parallelize(),如
sc.parallelize(["gdf","kgdr","vVy"])
这种方法需要将整个数据集先放在一台机器的内存中。
二是从外部读取,如
sc.textfile("文件路径")
如果sc的配置是连接集群,则从集群读取,如果没有配置,则从本地读取。
如果不是从hdfs的系统文件夹中读取数据,而是从本地读取数据,需要同一个文件存在所有的worker node上面,在读取的时候每个worker node的task会去读取本文件的一部分,不然会出错;spark app所运行的节点也需要有这个file,因为需要用到file进行Partition划分。每个worker node的executor执行的task要读取的Split的Location信息是localhost,他不会到master上面读,只会在运行这个task的worker node本地读。
这种使用textFile方法读取本地文件系统的文件的方法,只能用于debug,不用于其他任何用途,因为他会导致file的replication数与node的个数同步增长;上述描述中的分成2份是默认值,你可以自己设置partition个数。具体可参考该文。
spark传递函数的两种方法
一是过lambda,比如
lambda line:"python" in line
二是自定义一个函数,比如,
define haspython(line): return "python" in line
4、Spark中的函数
针对一个RDD的转化操作
针对两个RDD的转化操作
动作操作
pair RDD 的转化操作
mergeValue,mergeCombiners,partitioner)
针对两个pair RDD的转化操作
Pair RDD的行动操作
待整理
- spark使用方法(一)
- Spark GraphX相关使用方法
- Spark-TimeSeries使用方法
- spark job server使用方法
- Spark (一)
- spark sql基本使用方法介绍
- spark sql根本使用方法介绍
- Spark API Java编程使用方法
- spark sql基本使用方法介绍
- Spark的使用方法(二)
- [Spark]Spark RDD 指南一 引入Spark
- Spark研究一 什么是Spark
- 学习Spark:一.Spark简介
- spark 框架分析 (一)
- Spark 机器学习《一》
- spark笔记一
- Spark Streaming 理解一
- spark杂记(一)
- 设计模式之单例模式
- Java不定参数Object… obj 和 Object[] 的区别
- Docker 使用指南 (五)—— Dockerfile 详解
- Linux 多线程
- 你应该知道 装备克制!学会通过出装针对对面!
- spark使用方法(一)
- Opencv ROI区域图像叠加
- 课堂实践2:运用"图像蒙版"的方法,合成Apple-Mauth图片。
- 每个测试工程师都有自己一套测试流程
- lanproxy 使用教程 内网穿透软件
- Ubuntu下安装Tensorflow
- Maven打包无法将mapper.xml打进war包
- 递归算法
- 【第七届蓝桥杯】煤球数目