Spark源代码阅读(一)

Win7下IDEA搭建Spark源代码阅读环境。 一:实验环境准备: JDK: Java 语言的软件开发工具包(SDK)Scala:Spark是用Scala语言写成的,在本地编译执行需要这个包SBT:scala工程构建的工具Git:IDEA自动下载SBT插件时可能会用到的工具IDEA:有两个版本:Ultimate Edition & Community EditionSparkSource Code:Spark源码 以上软件或者安装包 阅读详情

强烈推荐
https://blog.youkuaiyun.com/weixin_41705780/article/details/79273666

总体架构

Spark工程下的模块

  • spark core, spark 内核
  • spark streaming, spark流计算(基于batch方式)
  • spark sql
  • MLlib, 机器学习lib库
  • GraphX, 图计算
  • R, 与R语言结合
  • Python,与Python语言结合,PySpark。基于PY4J
  • external 与Kakfa,Flume等模块的整合
  • resource-managers 对Yarn mesos等的支持
  • 其他(文档,实例,实例数据,工具,启动脚本,打包,授权协议)

本系列文章将只涉及spark core的2.3.2版本。

Spark的单机运行

如果不能单机运行,我们对其原理理解将只能从阅读源代码获取。没有办法进行DEBUG。这对我们深入的理解和重构源代码都是非常不利的。

SparkContext

runJob和

class SparkContext(config: SparkConf) extends Logging {
  /**
   * Run a function on a given set of partitions in an RDD and pass the results to the given
   * handler function. This is the main entry point for all actions in Spark.
   *
   * @param rdd target RDD to run tasks on
   * @param func a function to run on each partition of the RDD
   * @param partitions set of partitions to run on; some jobs may not want to compute on all
   * partitions of the target RDD, e.g. for operations like `first()`
   * @param resultHandler callback to pass each result to
   */
  def runJob[T, U: ClassTag](
      rdd: RDD[T],
      func: (TaskContext, Iterator[T]) => U,
      partitions: Seq[Int],
      resultHandler: (Int, U) => Unit): Unit = {
    if (stopped.get()) {
      throw new IllegalStateException("SparkContext has been shutdown")
    }
    val callSite = getCallSite
    val cleanedFunc = clean(func)
    logInfo("Starting job: " + callSite.shortForm)
    if (conf.getBoolean("spark.logLineage", false)) {
      logInfo("RDD's recursive dependencies:\n" + rdd.toDebugString)
    }
    dagScheduler.runJob(rdd, cleanedFunc, partitions, callSite, resultHandler, localProperties.get)
    progressBar.foreach(_.finishAll())
    rdd.doCheckpoint()
  }

 /**
   * Submit a job for execution and return a FutureJob holding the result.
   *
   * @param rdd target RDD to run tasks on
   * @param processPartition a function to run on each partition of the RDD
   * @param partitions set of partitions to run on; some jobs may not want to compute on all
   * partitions of the target RDD, e.g. for operations like `first()`
   * @param resultHandler callback to pass each result to
   * @param resultFunc function to be executed when the result is ready
   */
  def submitJob[T, U, R](
      rdd: RDD[T],
      processPartition: Iterator[T] => U,
      partitions: Seq[Int],
      resultHandler: (Int, U) => Unit,
      resultFunc: => R): SimpleFutureAction[R] =
  {
    assertNotStopped()
    val cleanF = clean(processPartition)
    val callSite = getCallSite
    val waiter = dagScheduler.submitJob(
      rdd,
      (context: TaskContext, iter: Iterator[T]) => cleanF(iter),
      partitions,
      callSite,
      resultHandler,
      localProperties.get)
    new SimpleFutureAction(waiter, resultFunc)
  }

DAGScheduler

在这些RDD.Action操作中(如count,collect)会自动触发runJob提交作业,不需要用户显式的提交作业。
在这里插入图片描述
作业调度的两个主要入口是submitJob和runJob,两者的区别在于前者返回一个Jobwaiter对象,可以用在异步调用中,用来判断作业完成或者取消作业,runJob在内部调用submitJob,等待waiter对象完成,保持阻塞直到作业完成(或失败)。

  /**
   * Run an action job on the given RDD and pass all the results to the resultHandler function as
   * they arrive.
   *
   * @param rdd target RDD to run tasks on
   * @param func a function to run on each partition of the RDD
   * @param partitions set of partitions to run on; some jobs may not want to compute on all
   *   partitions of the target RDD, e.g. for operations like first()
   * @param callSite where in the user program this job was called
   * @param resultHandler callback to pass each result to
   * @param properties scheduler properties to attach to this job, e.g. fair scheduler pool name
   *
   * @note Throws `Exception` when the job fails
   */
  def runJob[T, U](
      rdd: RDD[T],
      func: (TaskContext, Iterator[T]) => U,
      partitions: Seq[Int],
      callSite: CallSite,
      resultHandler: (Int, U) => Unit,
      properties: Properties): Unit = {
    val start = System.nanoTime
    val waiter = submitJob(rdd, func, partitions, callSite, resultHandler, properties)
    ThreadUtils.awaitReady(waiter.completionFuture, Duration.Inf)
    waiter.completionFuture.value.get match {
      case scala.util.Success(_) =>
        logInfo("Job %d finished: %s, took %f s".format
          (waiter.jobId, callSite.shortForm, (System.nanoTime - start) / 1e9))
      case scala.util.Failure(exception) =>
        logInfo("Job %d failed: %s, took %f s".format
          (waiter.jobId, callSite.shortForm, (System.nanoTime - start) / 1e9))
        // SPARK-8644: Include user stack trace in exceptions coming from DAGScheduler.
        val callerStackTrace = Thread.currentThread().getStackTrace.tail
        exception.setStackTrace(exception.getStackTrace ++ callerStackTrace)
        throw exception
    }
  }


  /**
   * Submit an action job to the scheduler.
   *
   * @param rdd target RDD to run tasks on
   * @param func a function to run on each partition of the RDD
   * @param partitions set of partitions to run on; some jobs may not want to compute on all
   *   partitions of the target RDD, e.g. for operations like first()
   * @param callSite where in the user program this job was called
   * @param resultHandler callback to pass each result to
   * @param properties scheduler properties to attach to this job, e.g. fair scheduler pool name
   *
   * @return a JobWaiter object that can be used to block until the job finishes executing
   *         or can be used to cancel the job.
   *
   * @throws IllegalArgumentException when partitions ids are illegal
   */ 
  def submitJob[T, U](
      rdd: RDD[T],
      func: (TaskContext, Iterator[T]) => U,
      partitions: Seq[Int],
      callSite: CallSite,
      resultHandler: (Int, U) => Unit,
      properties: Properties): JobWaiter[U] = {
    // Check to make sure we are not launching a task on a partition that does not exist.
    val maxPartitions = rdd.partitions.length
    partitions.find(p => p >= maxPartitions || p < 0).foreach { p =>
      throw new IllegalArgumentException(
        "Attempting to access a non-existent partition: " + p + ". " +
          "Total number of partitions: " + maxPartitions)
    }

    val jobId = nextJobId.getAndIncrement()
    if (partitions.size == 0) {
      // Return immediately if the job is running 0 tasks
      return new JobWaiter[U](this, jobId, 0, resultHandler)
    }

    assert(partitions.size > 0)
    val func2 = func.asInstanceOf[(TaskContext, Iterator[_]) => _]
    val waiter = new JobWaiter(this, jobId, partitions.size, resultHandler)
    //实际上是将JOB put进一个LinkedBlockingDeque。另一个线程负责将JOB取出。另一个线程将执行下面的方法
    eventProcessLoop.post(JobSubmitted(
      jobId, rdd, func2, partitions.toArray, callSite, waiter,
      SerializationUtils.clone(properties)))
    waiter
  }

  //接收的上面JOB的事件
  private def doOnReceive(event: DAGSchedulerEvent): Unit = event match {
    case JobSubmitted(jobId, rdd, func, partitions, callSite, listener, properties) =>
      dagScheduler.handleJobSubmitted(jobId, rdd, func, partitions, callSite, listener, properties)

    case MapStageSubmitted(jobId, dependency, callSite, listener, properties) =>
      dagScheduler.handleMapStageSubmitted(jobId, dependency, callSite, listener, properties)

    case StageCancelled(stageId, reason) =>
      dagScheduler.handleStageCancellation(stageId, reason)

    case JobCancelled(jobId, reason) =>
      dagScheduler.handleJobCancellation(jobId, reason)

    case JobGroupCancelled(groupId) =>
      dagScheduler.handleJobGroupCancelled(groupId)

    case AllJobsCancelled =>
      dagScheduler.doCancelAllJobs()

    case ExecutorAdded(execId, host) =>
      dagScheduler.handleExecutorAdded(execId, host)

    case ExecutorLost(execId, reason) =>
      val workerLost = reason match {
        case SlaveLost(_, true) => true
        case _ => false
      }
      dagScheduler.handleExecutorLost(execId, workerLost)

    case WorkerRemoved(workerId, host, message) =>
      dagScheduler.handleWorkerRemoved(workerId, host, message)

    case BeginEvent(task, taskInfo) =>
      dagScheduler.handleBeginEvent(task, taskInfo)

    case SpeculativeTaskSubmitted(task) =>
      dagScheduler.handleSpeculativeTaskSubmitted(task)

    case GettingResultEvent(taskInfo) =>
      dagScheduler.handleGetTaskResult(taskInfo)

    case completion: CompletionEvent =>
      dagScheduler.handleTaskCompletion(completion)

    case TaskSetFailed(taskSet, reason, exception) =>
      dagScheduler.handleTaskSetFailed(taskSet, reason, exception)

    case ResubmitFailedStages =>
      dagScheduler.resubmitFailedStages()
  }

LiveListenerBus

在SparkContext中, 首先会创建LiveListenerBus实例,这个类主要功能如下:

  • 保存有消息队列,负责消息的缓存
  • 保存有注册过的listener,负责消息的分发
    这是一个简单的监听器模型。

TaskScheduler

TaskScheduler是抽象类,目前Spark仅提供了TaskSchedulerImpl一种实现;其初始化是在SparkContext中

private[spark] class TaskSchedulerImpl(
    val sc: SparkContext,
    val maxTaskFailures: Int,
    isLocal: Boolean = false)
  extends TaskScheduler with Logging

TaskScheduler实际是SchedulerBackend(比如一种实现为YarnClientSchedulerBackend)的代理,本身处理一些通用逻辑,如不同Job间的调度顺序,将运行缓慢的task在空闲节点上重新提交(speculation)等

  override def submitTasks(taskSet: TaskSet) {
    val tasks = taskSet.tasks
    logInfo("Adding task set " + taskSet.id + " with " + tasks.length + " tasks")
    this.synchronized {
      val manager = createTaskSetManager(taskSet, maxTaskFailures)
      val stage = taskSet.stageId
      val stageTaskSets =
        taskSetsByStageIdAndAttempt.getOrElseUpdate(stage, new HashMap[Int, TaskSetManager])
      stageTaskSets(taskSet.stageAttemptId) = manager
      val conflictingTaskSet = stageTaskSets.exists { case (_, ts) =>
        ts.taskSet != taskSet && !ts.isZombie
      }
      if (conflictingTaskSet) {
        throw new IllegalStateException(s"more than one active taskSet for stage $stage:" +
          s" ${stageTaskSets.toSeq.map{_._2.taskSet.id}.mkString(",")}")
      }
      schedulableBuilder.addTaskSetManager(manager, manager.taskSet.properties)

      if (!isLocal && !hasReceivedTask) {
        starvationTimer.scheduleAtFixedRate(new TimerTask() {
          override def run() {
            if (!hasLaunchedTask) {
              logWarning("Initial job has not accepted any resources; " +
                "check your cluster UI to ensure that workers are registered " +
                "and have sufficient resources")
            } else {
              this.cancel()
            }
          }
        }, STARVATION_TIMEOUT_MS, STARVATION_TIMEOUT_MS)
      }
      hasReceivedTask = true
    }
    backend.reviveOffers()
  }

RDD

abstract class RDD[T: ClassTag](
    @transient private var _sc: SparkContext,
    @transient private var deps: Seq[Dependency[_]]
  ) extends Serializable with Logging {
  
  def map[U: ClassTag](f: T => U): RDD[U] = withScope {
    val cleanF = sc.clean(f)
    new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.map(cleanF))
  }
  def reduce(f: (T, T) => T): T = withScope {
    val cleanF = sc.clean(f)
    val reducePartition: Iterator[T] => Option[T] = iter => {
      if (iter.hasNext) {
        Some(iter.reduceLeft(cleanF))
      } else {
        None
      }
    }
    var jobResult: Option[T] = None
    val mergeResult = (index: Int, taskResult: Option[T]) => {
      if (taskResult.isDefined) {
        jobResult = jobResult match {
          case Some(value) => Some(f(value, taskResult.get))
          case None => taskResult
        }
      }
    }
    sc.runJob(this, reducePartition, mergeResult)
    // Get the final result out of our Option, or throw an exception if the RDD was empty
    jobResult.getOrElse(throw new UnsupportedOperationException("empty collection"))
  }

RDD的checkpoint机制

  /**
   * Mark this RDD for checkpointing. It will be saved to a file inside the checkpoint
   * directory set with `SparkContext#setCheckpointDir` and all references to its parent
   * RDDs will be removed. This function must be called before any job has been
   * executed on this RDD. It is strongly recommended that this RDD is persisted in
   * memory, otherwise saving it on a file will require recomputation.
   */
  def checkpoint(): Unit = RDDCheckpointData.synchronized {
    // NOTE: we use a global lock here due to complexities downstream with ensuring
    // children RDD partitions point to the correct parent partitions. In the future
    // we should revisit this consideration.
    if (context.checkpointDir.isEmpty) {
      throw new SparkException("Checkpoint directory has not been set in the SparkContext")
    } else if (checkpointData.isEmpty) {
      checkpointData = Some(new ReliableRDDCheckpointData(this))
    }
  }

checkpoint 的使用方式如下

val data = sc.textFile("/tmp/spark/1.data").cache() // 注意要cache 
sc.setCheckpointDir("/tmp/spark/checkpoint")
data.checkpoint 
data.count

使用很简单, 就是设置一下 checkpoint 目录,然后再rdd上调用 checkpoint 方法, action 的时候就对数据进行了 checkpoint当checkpoint为当前RDD设置检查点的时候,该函数将会创建一个二进制的文件,并存储到checkpoint目录中,该目录是用SparkContext.setCheckpointDir()设置的。在checkpoint的过程中,该RDD的所有依赖于父RDD中的信息将全部被移出。对RDD进行checkpoint操作并不会马上被执行,必须执行Action操作才能触发。当需要checkpoint的数据的时候,通过ReliableCheckpointRDD的readCheckpointFile方法来从file路径里面读出已经Checkpoint的数据。

Executor

  1. 在Worker Actor中,每次LaunchExecutor会创建一个CoarseGrainedExecutorBackend进程,一个Executor对应一个CoarseGrainedExecutorBackend
  2. 针对同一个App,每个Worker里只能有一个针对该App的Executor存在,切记。如果想让整个App的Executor变多,设置SPARK_WORKER_INSTANCES,让每个节点(机器上)的Worker变多。APP之间不公用Executor。
  3. Executor的资源分配有2种策略:
  • SpreadOut :一种以round-robin方式遍历集群所有可用Worker,分配Worker资源,来启动创建Executor的策略,好处是尽可能的将cores分配到各个节点,最大化负载均衡和高并行。
  • 非SpreadOut:会尽可能的根据每个Worker的剩余资源来启动Executor,这样启动的Executor可能只在集群的一小部分机器的Worker上。这样做对node较少的集群还可以,集群规模大了,Executor的并行度和机器负载均衡就不能够保证了。

在这里插入图片描述
在这里插入图片描述

Streaming

https://blog.youkuaiyun.com/define_us/article/details/83109337

JavaStreamingContext

http://spark.apache.org/docs/0.8.1/api/streaming/org/apache/spark/streaming/api/java/JavaStreamingContext.html
定义上下文后,您必须执行以下操作:

  • 通过创建输入DStreams定义输入源
  • 通过对DStreams应用转换操作(transformation)和输出操作(output)来定义流计算
  • 可以使用streamingContext.start()方法接收和处理数据
  • 可以使用streamingContext.awaitTermination()方法等待流计算完成(手动或由于任何错误),来防止应用退出
  • 可以使用streamingContext.stop()手动停止处理。
class JavaStreamingContext(val ssc: StreamingContext) extends Closeable {
  /**
   * Start the execution of the streams.
   */
  def start(): Unit = {
    ssc.start()
  }
Spark-2.3.1源码解读 Spark-2.3.1源码解读。 Spark Core源码阅读 Spark Context 阅读要点 Spark的缓存,变量,shuffle数据等清理及机制 Spark-submit关于参数及部署模式的部分解析 GroupByKey VS ReduceByKey OrderedRDDFunctions那些事 高效使用mappartitions standalone模式下executor调度策略 Spark Sql源码阅读 Spark Sql源码阅读 hive on spark调优 Spark SQL 多维聚合分析应用案例 Spark Streaming源码阅读 动态发现新增分区 Dstream join 操作和 RDD join 操作的区别 PIDController源码赏析及 back pressure 实现思路 Streaming Context重点摘要 checkpoint 必知必会 立即下载

相关推荐

告别混乱!用Cadence Capture CIS高效管理你的原理图库:以单逻辑器件K9F2G08U0M为例

本文以单逻辑器件K9F2G08U0M为例,详细介绍了如何使用Cadence Capture CIS高效管理原理图库。通过三级分类体系、工程化命名规范和智能检索技术,帮助工程师实现从混乱到有序的转变,提升团队协作效率和设计准确性。

aizhi0169的博客 402

Spark源码(一)-SparkRPC示例

RPC全称为远程过程调用(Remote Procedure Call),它是一种计算机通信协议,允许一个计算机程序调用另一个计算机上的子程序,而无需了解底层网络细节。通过RPC,一个计算机程序可以像调用本地程序一样调用远程程序,使得分布式应用程序的开发更加简单和高效。

weixin_37901366的博客 928

c++实现异步线程池并详细分析线程池析构流程

多线程编程是提高程序性能和响应能力的关键技术之一,异步线程池作为多线程编程的一种有效实现方式,能够管理和复用线程资源,避免频繁创建和销毁线程带来的开销。在本文中,我们将深入探讨如何实现一个异步线程池。

2301_76564925的博客 1599

2万字硬核spark源码精讲手册

spark源码精讲,结合企业级开发和面试实战重点关注内容

5092

音频DSP开发中的‘隐藏关卡’:那些SigmaStudio未公开的模块计算秘籍

本文深入探讨音频DSP开发中SigmaStudio未公开的模块计算秘籍,重点解析动态范围控制、均衡器参数映射和混响算法优化等核心模块计算公式。通过实际案例揭示如何利用这些非官方技巧提升音频质量与系统性能,为ADI DSP开发者提供宝贵的实战经验。

water的专栏 911

Ubuntu20.04下Intel AX201网卡驱动安装全攻略:从内核升级到固件更新

本文详细介绍了在Ubuntu 20.04系统上解决Intel AX201无线网卡驱动问题的完整方案。针对戴尔游匣G15等新硬件,通过升级内核至HWE版本、从官方仓库获取最新固件文件,并调整BIOS设置,彻底解决Wi-Fi无法识别或连接不稳定的问题,为开发者提供了一套从诊断到修复的实践指南。

gpt4scribbler的博客 690

Spark源码

spark源码

m0_67991849的博客 1366

【Python】解决 ERROR: Exception:Traceback (most recent call last):(亲测有效)

1、遇到问题2、问题解决

Fanjufei的博客 1万+

spark源码

sparkcontext初始化的流程 -sparkConf对象,也就是spark的配置对象,用来描述spark的配置信息,主要是以键值对的形式加载配置信息 -一旦通过newsparkconf()完成了对象的实例化,会默认加载spark.*配置文件 class SparkConf(loadDefaults:Boolean){ def this()=this(true) } 注意事项 -SparkContext对象的实例化,需要一个sparkconf对象作为参数, -在sparkcontext.

leezsj的博客 845

C#构建高精度预测模型:从数据预处理到模型部署的实战指南

【代码】C#构建高精度预测模型:从数据预处理到模型部署的实战指南。

墨夶的博客 1265

华为OD机试双机位C卷-AI面板识别(Py/Java/C/C++/Js/Go)

华为OD机试双机位C卷 AI面板识别,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解以及在线OJ模拟做题。华为OD机试 - AI面板识别。

qq_45776114的博客 1343

深入理解 Spark(二)SparkApplication 提交和运行源码分析

本章节结合 spark 源码介绍了 spark application 的提交与运行过程,可供大数据批处理从业者或感兴趣人员研究和学习。

weixin_44512041的博客 1543

提示词驱动的多智能体协作系统

《提示词驱动的多智能体协作系统》 关键词:人工智能、多智能体系统、协作机制、提示词驱动、系统设计与应用 摘要:本文深入探讨提示词驱动的多智能体协作系统,首先介绍其背景和核心概念,然后详细分析多智能体系统的基本原理和提示词驱动的协作机制,最

AI天才研究院 851

spark源码阅读之spark-shell

首先我们来看SPARK_HOME/bin/spark-shell脚本,内容: function main() { if $cygwin; then stty -icanon min 1 -echo > /dev/null 2>&1 export SPARK_SUBMIT_OPTS="$SPARK_SUBMIT_OPTS -Djline.terminal=unix" "

u011294077的专栏 2109

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

【Spark】配置Spark源码阅读环境

Scala构建工具(SBT)的使用SBT介绍SBT是Simple Build Tool的简称,如果读者使用过Maven,那么可以简单将SBT看做是Scala世界的Maven,虽然二者各有优劣,但完成的工作基本是类似的。 虽然Maven同样可以管理Scala项目的依赖并进行构建,但SBT的某些特性却让人如此着迷,比如: 使用Scala作为DSL来定义build文件(one language

Jason Ding的专栏 2090

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Spark源代码阅读笔记之DiskStore

Spark源代码阅读笔记之DiskStore BlockManager底层通过BlockStore来对数据进行实际的存储。BlockStore是一个抽象类,有三种实现:DiskStore(磁盘级别的持久化)、MemoryStore(内存级别的持久化)和TachyonStore(Tachyon内存分布式文件系统级别的持久化)。 DiskStore通过DiskBloc...

aoe41606的博客 178

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Windows下从源代码构建Spark

Windows下从源代码构建Spark 字数2081 阅读1515 评论1 喜欢4 综述 其实Spark的构建已经做得很好了,但是由于大家已知的原因,很多东西不能很顺利的拿到。估计你要给老外说花了很多时间在build Spark上面,他只有一个反应“unbelievable”。 在这里特别要感谢一下OSChina,它的Maven库的存在,使得在国内从源代码构建Spark

peter_zhao的专栏 1420

Mac上配置IntelliJ IDEA的Spark源码阅读环境

文章目录环境准备主要工具/软件Git 安装IntelliJ IDEA 下载及 Scala 插件安装sbt 安装基本步骤获取git目录在IDEA中构建spark 环境准备 主要工具/软件 git Intellij IDEA &amp;amp;amp; Scala Plugin sbt Git 安装 IntelliJ IDEA 下载及 Scala 插件安装 IJ IDEA 下载连接: https://www.je...

Lestat.Z.的博客 2331

1. Spark源代码阅读与调试环境搭建

1.修改maven默认仓库地址,选择阿里云仓库可以加速依赖包的下载速度,阿里云仓库地址为http://maven.aliyun.com/nexus/content/groups/public。注意:intellij idea依赖的scala sdk的版本一定要与spark 源代码包中依赖的scala版本一致,否则后面可能报错。intellj idea具有强大的代码编辑,阅读与调试功能,这里选择它作为代码阅读与调试工具。执行上述命令,会在dist目录中生成发布软件包,与在spark官网下载的软件包是一样的。

cl2010abc的专栏 390

Spark源码学习之IDEA源码阅读环境搭建

软件准备 (1)Java 1.8 (2)Scala 2.11.12(需要在IDEA中安装) (3)Maven 3.8.2(需要在IDEA中配置) (4)Git 2.33 以上软件需要安装好,并进行环境配置。 (5)spark 2.4.3 源码(官网可下载) 编译源码 (1)修改MAVEN_OPTS,增加Maven编译时内存的大小: 在Maven安装目录下找到bin/mvn.cmd文件,打开在文件中添加 MAVEN_OPTS="-Xmx2g -XX:MetaspaceSize=2G -XX:Reserve

一入大数据深似海?别怕!“数据极客圈”就是你的救生圈,走对圈子跟对人,趣析数据、畅聊趋势,快进圈子! 1352

Spark源码阅读之RDD

本文主要是注释RDD源代码,部分注释是翻译源代码中的英文注释。由于本人水平有限,如有错误的地方还请大家指出。 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed wi...

LMR的博客 7459

spark搭建源码阅读环境

如题: 怎样编译spark源码方便读呢?首先当然是先去官网或者github上下载spark源码包,这里附上官网地址spark-2.4.5下载 下载好spark源码包以后解压,然后编译一下导入IDEA就可以愉快的看源码了,怎样编译呢? 这里以windows 10举例。 环境准备 首先要搭建好需要的环境,比如scala,maven和java,我的环境是1.8的java,2.11.11的scala以及3...

斌躏天下的博客 830

spark源代码阅读用idea出现的问题

最近想用idea研读下spark的源代码,毕竟是研究这个,看看代码装装逼也不错。。 在网上都有很多用idea导入spark源码的教程,中间可能后出现找不到sparkflumeprotocol等等的问题 这个主要的原因是因为idea的sbt插件的不完整。在编译的过程中可能会被防火墙给咔掉。。我猜的。。 在windows下看源码就在spark目录下使用sbt gen-idea的命令编译,时间超级

gaoqida的专栏 795

用Windows7+IDEA+SBT搭建Spark源代码调试与阅读环境

Spark源码是有Scala语言写成的,目前,IDEA对Scala的支持要比eclipse要好,大多数人会选在在IDEA上完成Spark平台应用的开发。因此,Spark源码阅读的IDE理所当然的选择了IDEA。今天将与大家分型Windows7+IDEA+SBT搭建Spark源代码调试与阅读环境。   实验环境准备: l  JDK: Java 语言的软件开发工具包(SDK) 参考网址: ht

zhongwen7710的专栏 7704

Spark客户端源码阅读(一)

Spark客户端源码阅读 此Spark是基于XMPP协议的实现的客户端,与openfire、smack使用。而不是为大规模数据处理而设计的快速通用的计算引擎Apache Spark。 项目地址: https://github.com/igniterealtime/Spark 简述几个项目构建工具 make工具:用于Linux下构建C/C++代码,在makefile文件中指定源文件如何编译以及连接...

学而不思则罔,思而不学则殆。 368

Spark开发环境及源码阅读环境配置

源码阅读环境配置:参考如下博文:Windows + IDEA + SBT 打造Spark源码阅读环境上面是在windows环境的配置,比较耗时,而且由于网络原因,很有可能出错;在linux环境下就比较简单了: 进入spark源代码目录下,运行以下命令:./sbt/sbt gen-idea会自动生成idea项目文件; 然后进入idea,点击File->Open project即可。 使用intelli

yijichangkong的专栏 2178
上一篇: 数据库和databus
下一篇: PySpark的原理
define_us
博客等级 码龄14年 157粉丝 531原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值