spark介绍

184830_e7qn_3215753.png

以SparkContext为程序运行的总入口,在SparkContext的初始化过程中,Spark会分别创建DAGScheduler作业调度和TaskScheduler任务调度两级调度模块。作业调度模块为每个Spark作业计算具有依赖关系的多个调度阶段(通常根据shuffle来划分),然后为每个阶段构建出一组具体的任务(通常会考虑数据的本地性等),然后以TaskSets(任务组)的形式提交给任务调度模块来具体执行。而任务调度模块则负责具体启动任务、监控和汇报任务运行情况。 

 

Application:  用户编写的应用应用程序。    

Driver: Application中运行main函数并创建的SparkContext, 创建SparkContext的目的是和集群的ClusterManager通讯,进行资源的申请、任务的分配和监控等。所以,可以用SparkContext代表Driver         

Worker:集群中可以运行Application代码的节点。     
    
Executor: 某个Application在Worker上面的一个进程,该进程负责执行某些Task,并负责把数据存在内存或者磁盘上。每个Application都各自有一批属于自己的Executor。        

Task:被送到Executor执行的工作单元,和Hadoop MapReduce中的MapTask和ReduceTask一样,是运行Application的基本单位。多个Task组成一个Stage,而Task的调度和管理由TaskScheduler负责。

Job:包含多个Task组成的并行计算,往往由Spark Action触发产生。一个Application可以产生多个Job。  

Stage:每个Job的Task被拆分成很多组Task, 作为一个TaskSet,命名为Stage。Stage的调度和划分由DAGScheduler负责。Stage又分为Shuffle Map Stage和Result Stage两种。Stage的边界就在发生Shuffle的地方。

**RDD:**Spark的基本数据操作抽象,可以通过一系列算子进行操作。RDD是Spark最核心的东西,可以被分区、被序列化、不可变、有容错机制,并且能并行操作的数据集合。存储级别可以是内存,也可以是磁盘。

DAGScheduler:根据Job构建基于Stage的DAG(有向无环任务图),并提交Stage给TaskScheduler

TaskScheduler:将Stage提交给Worker(集群)运行,每个Executor运行什么在此分配。

 

val spark = SparkSession.builder
      .appName(f"log clean:traffic_${beginInput}_$endInput")
      .config("spark.executor.memory", "2g")
      .config("spark.sql.warehouse.dir", "/user/hive/warehouse")
      .enableHiveSupport()
      .getOrCreate()

val trafficLog = config.getString("logPath.trafficLog").format(inputDate)

def lineExplain(line: String) = {
        try {
          val lineArr = line.stripLineEnd.split("\\?t\\?=")
          val ngCookieList = lineArr(0).split("\\|\\|")
          val ngCookieLen = ngCookieList.length

          if (lineArr.length >= 29 && List(2, 4, 9).contains(ngCookieLen)){
            //修复url后面加/
            val requestUrl = lfb.repairUrl(lineArr(1).replace("\"", ""))
            val domain = (new java.net.URL(requestUrl)).getHost
            val seoUrl: String = Try(lineArr(29).split(" ")(0)) match {
              case Success(seoUrl) => seoUrl
              case Failure(ex) => ""
            }
            //url解析
            val tids: Tids = seoUrl match {
              case _ if seoUrl.length > 5 => classify(seoUrl)
              case _ => classify(requestUrl)
            }
            if (tids.siteIds.nonEmpty) {
              val iploc = lineArr(2)
              val randomStr = lineArr(3).split("\\?")(1)
              val referUrl = lineArr(7)
              val referDomain = Try((new java.net.URL(referUrl)).getHost).toOption.getOrElse("0")
              
              }
              val uniqKey = (randomStr, suv, svn, ssid)
              val lineObj = TrafficLine(ip, iploc, area.country, area.province, area.city,
                tids.siteIds, tids.cnlIds, tids.colIds, tids.gids,addTime, inputDate
              )
              Some((uniqKey, lineObj))

            } else None

          } else None


        } catch {
          case e => {
            logger.error(line)
            logger.error(e)
            None
          }
        }
      }

spark.sparkContext.textFile(trafficLog).repartition(40).flatMap(lineExplain).
        reduceByKey((v1, v2) => v1, numPartitions=20).map(_._2).toDF.repartition(4).
        write.partitionBy("dt").mode(SaveMode.Append).parquet(f"$saveLogPath/")

spark.sql("msck repair table traffic_log")
spark.stop()


#伪代码
import scala.collection.mutable.{Map, Set}
spark.sparkContext.textFile(trafficLog).map(line => (url, Set(userId))).reduceByKey(_ ++ _).
                   map(lst => (user, len(userIdSet))).collectAsMap()



spark.sparkContext.textFile(trafficLog).map(line => (url, userId)).distinct().map(lst => (url, 1)).
                 reduceByKey(_ + _).collectAsMap()
                   

 

1、repartition 和 coalesce

2、宽依赖和窄依赖

192224_mX6e_3215753.png

窄依赖指父RDD的每一个分区最多被一个子RDD的分区所用,表现为一个父RDD的分区对应于一个子RDD的分区,或多个父RDD的分区对应于一个子RDD的分区。图中,map/filter和union属于第一类,对输入进行协同划分(cogroup)的join属于第二类。

宽依赖指子RDD的分区依赖于父RDD的多个或所有分区,这是因为shuffle类操作,如图中的groupByKey和未经协同划分的join。

3、RDD 的 Transformation与Action,DAG

 

 

转载于:https://my.oschina.net/whx403/blog/903912

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值