介绍

Spork是Pig on Spark的highly experimental版本号,依赖的版本号也比較久,如之前文章里所说。眼下我把Spork维护在自己的github上:flare-spork

本文分析的是Spork的实现方式和详细内容。

Spark Launcher

在hadoop executionengine包路径下,写了一个Spark启动器,同MapReduceLauncher类似,会在launchPig的时候,把传入的物理运行计划进行翻译。
MR启动器翻译的是MR的操作,以及进一步的MR JobControl。而Spark启动器将物理运行计划的部分物理操作直接翻译成了RDD的操作。
有一个缺点是翻译成RDD算子之后,缺少优化过程,也就是直接物理操作的映射翻译。详细运行逻辑会全然交给Spark DAGScheduler去切分,由TaskScheduler去调度任务。
比方对Pig来说。直到见到Dump/Store,才会触发整个翻译和launch。

那么在这一次物理运行计划中,相应到Spark可能是多次任务。


在眼下的实现方式下,翻译物理操作交给多个Convertor的实现类来完毕,
public interface POConverter<IN, OUT, T extends PhysicalOperator> {

    RDD<OUT> convert(List<RDD<IN>> rdd, T physicalOperator) throws IOException;

}

抽象类POConvertor提供了convert方法,输入參数中的List<RDD>是本次物理操作的前驱们产生的RDDs,能够觉得是会依赖的父RDDs。

这样一次转化结果就是产生nextRDD。而nextRDD是否在spark上真正触发计算,眼下来看是不去控制的。也就是上面提到的,一次Pig物理运行计划可能会有Spark运行多次任务。


在使用的时候。以-x spark的方式就能够启动以Spark为backend engine的Pig环境。

以下详细看眼下做了哪些PO操作的转化工作。详细怎么转化的。

Load/Store

走的都是NewHadoopRDD路线。

Load方面是通过POLoad获得文件路径,pigContext获得必要配置信息,然后交由SparkContext调用newAPIHadoopFile来获得NewHadoopRDD,最后把Tuple2<Text, Tuple>的RDD map成仅仅剩value的RDD<Tuple>。

Store方面是先把近期的前驱rdd转会成Key为空Text的Tuple2<Text, Tuple>。然后映射为PairRDDFunctions。借助pigContext生成POStore操作,最后调用RDD的saveAsNewAPIHadoopFile存到HDFS上。

Foreach、Filter、Limit

ForEach里实现一个Iterator[T] => Iterator[T]的方法,把foreach转化为rdd.mapPartitions()方法。

Iterator[T]=> Iterator[T]方法的实现。会依赖原本的POForEach来获得nextTuple和进行一些别的操作,来实现一个新的Iterator。

对于hadoop backend的executionengine里的抽象类PhysicalOperator来说。

setInput()和attachInput()方法是放入带处理的tuple数据。

getNextTuple()的时候触发processTuple()。处理对象就是内部的Input Tuple。

所以ForEach操作实现Iterator的时候。在readNext()方法里掺入了以上设置Input数据的操作,在返回前调用getNextTuple()返回处理后的结果。

POFilter也是通过setInput()和attachInput()以及getNextTuple()来返回处理结果。

所以在实现为RDD操作的时候。把以上步骤包装成一个FilterFunction,传入rdd.filter(Function)处理。

POLimit同POFilter是全然一样的。

Distinct

如今RDD已经直接具备distinct(numPartitions: Int)方法了。

这里的distinct实现同rdd里的distinct逻辑是全然一样的。

第一步:把类型为Tuple的rdd映射成为Tuple2<Tuple, Object>。当中value部分是null的;

第二步:进行rdd.reduceByKey(merge_function, parallelism)操作,merge_function对两个value部分的Object不做不论什么处理。也就是按key reduce且不正确value部分处理;

第三步:对第二步的结果进行rdd.map(function, ClassTag)处理,function为得到Tuple2<Tuple, Object>里的._1,即key值:Tuple。


Union

Union是一次求并过程,直接new UnionRDD<Tuple>返回。

因为UnionRDD处理的是Seq<RDD>。所以使用JavaConversions.asScalaBuffer(List<RDD<Tuple>>)进行一下转换再传入。


Sort

Sort过程:

第一步:把Tuple类型的RDD转成Tuple2<Tuple, Object>类型。Object为空

第二步:依据第一步结果。new OrderedRDDFunctions<Tuple, Object,Tuple2<Tuple, Object>>

,其sortByKey方法产出一个排过序的RDD<Tuple2<Tuple, Object>>。OrderedRDDFunctions里的Key类型必须是可排序的,比較器复用的是POSort的mComparator。sortByKey结果返回的是ShuffleRDD。其Partitioner是RangePartitioner,排序之后,每一个Partition里存放的都是一个范围内的排过序的值。

第三步:调用rdd.mapPartition(function, xx, xx),function作用为把Iterator<Tuple2<Tuple,Object>>吐成Iterator<Tuple>。即再次取回Key值,此时已有序。

Split

POSplit的处理是直接返回第一个祖先RDD。

LocalRearrange

LocalRearrange -> Global Rearrange -> Package是一同出现的。



Local rearrange直接依赖

  physicalOperator.setInputs(null);
physicalOperator.attachInput(t);
result = physicalOperator.getNextTuple();

三步得到result。返回的Tuple格式为(index, key, value)。

依赖POLocalRearrange本身内部对input tuple的处理。

GlobalRearrange

待处理的Tuple格式是(index, key, value)。最后结果为(key, { values })

假设父RDD仅仅有一个:

先进行按key进行一次groupBy。得到结果是Tuple2<Object, Seq<Tuple>>

然后做一次map操作,得到(key, { values })形态的RDD,即Tuple<Object, Iterator>

假设父RDD有多个:

让通过rdd的map操作先将Tuple从(index, key, value)转成(key, value)形态,然后把这个rdd集合new成CoGroupRDD,包括一次(Seq) JavaConversions.asScalaBuffer(rddPairs)转化。最后调用CoGroupRDD的map方法,把Tuple2<Object,Seq<Seq<Tuple>>>转化成Tuple<Object, Iterator>,即(key, { values })形态。实际上。CoGroupRDD的map方法内部做的事情。是针对每一个Key里的Iterator集合,进行了Iterator之间的合并操作。

Package

Package须要把global rearrange处理后的key, Seq<Tuple>进行group。

详细的待处理Tuple结构是这种:(key, Seq<Tuple>:{(index,key, value without key)})

tuple.get(0)是keyTuple,tuple.get(1)是Iterator<Tuple>。最后返回(key, {values})。即Tuple<Object, Iterator>

全文完 :)

Spork: Pig on Spark实现分析的更多相关文章

  1. flare-spork: 自己维护的Pig on Spark项目

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zbf8441372/article/details/24726501 关于flare-spork 非 ...

  2. Spark源代码分析之六:Task调度(二)

    话说在<Spark源代码分析之五:Task调度(一)>一文中,我们对Task调度分析到了DriverEndpoint的makeOffers()方法.这种方法针对接收到的ReviveOffe ...

  3. Spark原理分析目录

    1 Spark原理分析 -- RDD的Partitioner原理分析 2 Spark原理分析 -- RDD的shuffle简介 3 Spark原理分析 -- RDD的shuffle框架的实现概要分析 ...

  4. 从0到1进行Spark history分析

    一.总体思路 以上是我在平时工作中分析spark程序报错以及性能问题时的一般步骤.当然,首先说明一下,以上分析步骤是基于企业级大数据平台,该平台会抹平很多开发难度,比如会有调度日志(spark-sub ...

  5. 大数据分析处理框架——离线分析(hive,pig,spark)、近似实时分析(Impala)和实时分析(storm、spark streaming)

    大数据分析处理架构图 数据源: 除该种方法之外,还可以分为离线数据.近似实时数据和实时数据.按照图中的分类其实就是说明了数据存储的结构,而特别要说的是流数据,它的核心就是数据的连续性和快速分析性: 计 ...

  6. Spark网络通信分析

    之前分析过spark RPC的基本流程(spark RPC详解),其实无论是RPC还是Spark内部的数据(Block)传输,都依赖更底层的网络通信,本文将对spark的网络通信做一下剖析. 1,概要 ...

  7. hive Spark SQL分析窗口函数

    Spark1.4发布,支持了窗口分析函数(window functions).在离线平台中,90%以上的离线分析任务都是使用Hive实现,其中必然会使用很多窗口分析函数,如果SparkSQL支持窗口分 ...

  8. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  9. Spark源代码分析之中的一个:Job提交执行总流程概述

    Spark是一个基于内存的分布式计算框架.执行在其上的应用程序,依照Action被划分为一个个Job.而Job提交执行的总流程.大致分为两个阶段: 1.Stage划分与提交 (1)Job依照RDD之间 ...

随机推荐

  1. TensorFlow——分布式的TensorFlow运行环境

    当我们在大型的数据集上面进行深度学习的训练时,往往需要大量的运行资源,而且还要花费大量时间才能完成训练. 1.分布式TensorFlow的角色与原理 在分布式的TensorFlow中的角色分配如下: ...

  2. 测试数据准备中用到到csv写文件知识点

    对于大数据测试中,有时需要自己去准备一些数据,用csvreader来写一个比较大的文件就比较方便,下面我就直接贴示例代码了: package com.acxm.amysu.test;import co ...

  3. Core篇——初探IdentityServer4(OpenID Connect模式)

    Core篇——初探IdentityServer4(OpenID Connect客户端验证) 目录 1.Oauth2协议授权码模式介绍2.IdentityServer4的OpenID Connect客户 ...

  4. 使用C#正则表达式获取必应每日图片地址

    微软的Bing搜索引擎首页每天都会提供了一些有趣的图片,下面使用正则表达式获取图片的地址,不管是在手机app还是在网站上都是很好的图片素材,而且每天更新,非常不错. 首先访问微软的API,该地址返回的 ...

  5. 大白话理解this

    日常开发中,我们经常用到this.一开始常会用一种感觉去判断this的指向,当遇到复杂的函数调用时,就分不清this的指向. 今天我们来由浅入深来学习下. function family1(){ va ...

  6. hdu1317 XYZZY Floyd + Bellman_Ford

    这题,我在学搜索的时候做过.不过好像不叫这名字. 1.先用Floyd算法判断图的连通性.如果1与n是不连通的,输出hopeless. 2.用Bellman_Ford算法判断是否有正圈,如果某点有正圈, ...

  7. 【Oracle】闪回drop后的表

    本文介绍的闪回方式只适用于:删除表的表空间非system,drop语句中没有purge关键字(以上两种情况的误删除操作只能通过日志找回): 1.删除表后直接从回收站闪回 SCOTT@LGR> d ...

  8. Vue 项目打包和上线

    1.把绝对路径改为相对路径 我们打开config/index.js 会看到一个build属性,这里就我们打包的基本配置了.你在这里可以修改打包的目录,打包的文件名.最重要的是一定要把绝对目录改为相对目 ...

  9. /usr/bin/ld: cannot find -lxxx 问题 解决方法总结

    最近在做毕设的收尾工作,很多程序都要部署到linux下来运行,遇到了挺多问题,昨天就集中性遇到了 在编译应用时,遇到了 /usr/bin/ld: cannot find -lxxx 这种情况是系统找不 ...

  10. mDNS 原理的简单理解

    转自:http://www.binkery.com/post/318.html mDNS 原理的简单理解 mDNS multicast DNS , 使用5353端口. 在局域网内,你要通过一台主机和其 ...