第3章〓Spark开发基础 3.1Spark概述 3.1.1Spark简介 Spark最初由美国加州大学伯克利分校(UC Berkeley)的AMP实验室(AMPLab,现在称为RISELab)于2009年开发,是基于内存计算的大数据并行计算框架,可用于构建大型的、低延迟的数据分析应用程序。研究人员之前曾从事Hadoop MapReduce的工作,他们承认MapReduce对于交互式或迭代计算作业和复杂的学习框架是低效、难以处理的,因此从一开始,他们就有了使Spark更简单、更快、更容易使用的想法。 Spark在诞生之初属于研究性项目,其诸多核心理念均源自学术研究论文。Spark项目的核心是借用Hadoop MapReduce的思想,但强于后者。Spark的改进包括: 提高容错性和并行性,支持内存存储以在迭代和交互式Map和Reduce之间减少中间计算,提供支持多种编程语言、且简单易用的API,并以统一的方式支持其他工作负载。2013年,Spark加入Apache孵化器项目后,开始迅猛发展,目前已成为使用最多的大数据开源项目之一。 Apache Spark是为大规模、分布式数据处理而设计的一个分析引擎,为中间计算提供了内存存储,运行速度较Hadoop MapReduce快若干倍。Spark包括用于机器学习的库MLlib、用于交互式查询的SQL(Spark SQL)、用于与实时数据交互的流处理(Structured Streaming)以及用于图形处理的GraphX库,如图31所示。 图31Spark的组件与API接口 Spark具有如下主要特点。 (1) 运行速度快: Spark框架经过优化,可以充分利用多核CPU和内存资源,高效利用操作系统的多线程和并行处理机制。其次,Spark将其查询计算构建为有向无环图 (Directed Acyclic Graph,DAG),执行引擎将其优化为高效的计算图,分解为可以在集群上多个工作线程之间并行执行的任务。此外,所有中间结果都保留在内存中(尽量减少磁盘I/O),也极大地提高了性能。 (2) 容易使用: Spark支持使用Scala、Java、Python和R语言进行编程,简洁的API设计有助于用户轻松构建并行应用程序,并且可以通过Spark Shell进行交互式编程。 (3) 通用性强: Spark可以应用于多种类型的工作任务,提供了支持多种编程语言接口的、统一的API库,可以将不同的工作负载组合在一个引擎下运行。其核心组件(或模块),如Spark SQL、Structured Streaming、MLlib和GraphX等,可以无缝地整合在同一个应用中,足以应对复杂的计算。 (4) 扩展性强: Spark专注于其快速的并行计算引擎,而不是存储。使用Spark可以读取存储在多种数据源中的数据,如Apache Hadoop、Cassandra、HBase、Hive、MongoDB,以及各种关系数据库等。Spark的DataFrame Reader和Writer可以扩展以支持其他数据源(如Apache Kafka、Kinesis、Azure Storage和Amazon S3等)。 3.1.2Spark架构设计 Spark是一个分布式数据处理引擎,其组件在集群机器上协同工作。在探讨Spark编程之前,需要了解Spark分布式架构的所有组件,以及组件之间是如何协同工作和通信的。Spark的运行架构包括集群管理器、应用程序的任务驱动程序Driver和运行作业任务的工作节点(Worker Node),其中,每个工作节点的程序执行器Executor负责具体任务的执行。集群管理器可以是Spark自带的资源管理器,也可以是YARN等资源管理框架。 与Hadoop MapReduce相比,Spark采用Executor的优点体现在两个方面: 一是利用多线程执行任务(Hadoop MapReduce采用的是进程模型),减少任务的启动开销; 二是Executor中的BlockManager模块会将中间结果存到内存中,当迭代计算需要时,可以直接从内存读数据,而无须读写HDFS等文件系统,减少了I/O开销。另外,在交互式查询场景下,通过预先将数据表缓存到BlockManager中,从而提高I/O读写性能。 如图32所示,Spark应用程序包含一个Driver程序,该程序负责协调Spark集群上的并行操作。Driver程序通过SparkSession访问集群中的分布式组件,包括Spark程序执行器Executor和集群管理器Cluster Manager。 图32Spark组件与运行架构 Spark Driver是Spark应用程序的一部分,负责实例化SparkSession。Driver程序与集群管理器通信,请求Executor(JVM)运行需要的资源(CPU、内存等); 将所有Spark操作转换为DAG(计算、计划),并将任务分发到Executor。分配资源后,Driver将直接与Executor通信。 在Spark 2.0及其后版本中,SparkSession成为所有数据访问Spark操作的统一入口,不仅包含了Spark以前的入口点,如SparkContext、SQLContext、HiveContext、SparkConf和StreamingContext等,还使Spark更简单、易用。通过这个入口,可以创建JVM运行时参数、定义数据帧和数据集、从数据源读取、访问目录元数据,以及执行Spark SQL查询等。 集群管理器负责为运行Spark应用程序的集群节点管理和分配资源。目前,Spark支持4类分布式集群管理器,分别是内置的独立集群管理器Standalone、Apache Hadoop YARN、Apache Mesos和Kubernetes。 程序执行器Executor运行在集群中的工作节点上。Executor与Driver程序通信,并负责在工作节点上执行任务。在大多数部署模式下,每个节点仅运行一个Executor。 3.2Spark安装及部署 3.2.1安装Spark 1. 下载Spark Spark可在官方网站(或镜像网站)下载,选择合适的稳定版本,下载页面如图33所示。 图33Spark下载页面 进入下载页面后,即可选择合适的Spark版本。本书使用了Scala 2.13.x版本,因此,这里选择下载 Prebuilt for Apache Hadoop 3.3 and later。也可以从镜像站点下载: $ wget -c https://mirrors.tuna.tsinghua.edu.cn/apache/spark/spark-3.3.0/spark-3.3.0-bin-hadoop3-scala2.13.tgz 2. 安装 1) 安装JDK Spark运行需要设置Java环境,确保系统已安装Java。具体可参考2.1.2节的相关内容。确保已设置JAVA_HOME环境变量,如,直接在当前终端窗口设置: $ export JAVA_HOME=~/jdk-17 注意: 请以本地实际安装的路径为准(即替换上述命令的路径~/jdk17)。 可以根据实际需要,将JAVA_HOME设置为用户环境变量或系统环境变量。设置方法与设置PATH环境变量类似,具体可参考2.1.2节的 相关内容,或参考其他资料。 2) 安装Spark 将下载的Spark压缩包解压,并根据需要将解包的路径换成容易识记的路径名称,设置必要的用户权限等(注: 解包到用户主目录Home,通常不需要特别设置权限): $ tar -zxf ./Downloads/spark-3.3.0-bin-hadoop3-scala2.13.tgz $ mv ./spark-3.3.0-bin-hadoop3-scala2.13 ./spark-3.3.0 3) 验证Spark安装 如图34所示,执行以下命令,可以查看Spark版本等信息: $ ./spark-3.3.0/bin/spark-shell --version 图34查看Spark版本信息 运行Spark自带的例子程序,如计算圆周率π近似值,结果如图35所示。 $ ./spark-3.3.0/bin/run-example SparkPi 4 2>&1 | grep "Pi " 图35运行Spark自带的例子程序 说明: 执行例子程序时会输出较多的运行信息,因此,这里使用了grep命令对输出信息进行过滤(上述命令中的 2>&1 可以将所有的信息都输出到标准控制台中,否则日志信息还是会输出到屏幕)。具体命令、管道等用法,请参考Linux相关文档。 提示: Spark安装包中附带有一些例子程序,如,基于RDD API的Word Count、圆周率π估计程序SparkPi、基于DataFrame API的文本搜索Text search以及机器学习等例子程序。这些例子程序的源代码位于examples/src/main目录下。学习例子程序对Spark开发有极大的帮助。 3.2.2Spark部署方式 Spark支持多种部署模式,能够运行在不同的配置和环境中。由于集群管理器与它的运行位置无关(只要可以管理Spark Executor,并满足资源请求),所以Spark可以部署在一些最流行的环境中,如Apache Hadoop YARN和Kubernetes,并且可以在不同的模式下运行。 Local模式是本地模式,常用于本地开发或测试。Standalone模式使用Spark框架自带的资源调度管理服务,可以独立部署到一个集群中。在Spark on YARN/Kubernetes/Mesos模式中,Spark应用程序所需要的各种资源,由相应的资源管理服务器负责调度。表31给出了可用的部署方式。 表31Spark部署方式 模式 Spark Driver Spark Executor Cluster Manager Local 单个JVM中运行,单节点 与Driver相同的JVM 同一台机器 Standalone 集群中的任一节点 每个Executor有自己独立的JVM 集群中的任一主机 Spark Master YARN (client) 客户机,非集群一部分 Container on YARN’s NodeManager Resource Manager Application Master YARN (cluster) Application Master 同上 同上 Kubernetes 运行于Kubernetes pod 每个节点自己的pod Kubernetes Master Mesos Framework Scheduler Mesos Agent Mesos Master 3.3配置Spark访问HDFS数据源 Spark可以独立使用,也可以与Hadoop配合使用。通常情况下,Spark基于Hadoop HDFS的高容错特性来处理大规模数据集。Spark可以和Hadoop HDFS同时安装使用,Spark可以直接使用HDFS存取数据。 Spark访问HDFS数据源,需要部署相应的服务。为保持内容的完整性,本节简要介绍Hadoop的安装部署过程,更详细的内容请参考Hadoop用户手册或其他相关资料。 3.3.1Hadoop部署 1. Hadoop下载 Hadoop当前的发行版本是 3.3.4。相比3.2.x版本,3.3.x版本支持ARM架构,对Java 11/17的支持更全面,且修复了Guava包的版本冲突等问题。Hadoop可以通过官方网站下载,也可以选择镜像下载。如图36所示,对下载文件进行解压: $ tar -zxf ./Downloads/hadoop-3.3.4.tar.gz 图36Hadoop下载过程 2. Hadoop伪分布式部署 1) 依赖环境 (1) Hadoop集群(单节点)、伪分布部署依赖于Java、SSH等。应确保已安装Java。设置Java环境变量,验证Hadoop版本信息: $ export JAVA_HOME=~/jdk-17 $ ./hadoop-3.3.4/bin/hadoop version 说明: Hadoop 3.3.4不完全支持Java 17。根据官方文档,Hadoop 3.3.x版本完全支持Java 8/Java 11,Hadoop 3.0.x ~ 3.2.x仅支持Java 8。 (2) 安装SSH: $ sudo apt-get install ssh $ sudo apt-get install pdsh (3) Hadoop使用SSH登录时,没有提供输入密码的界面,因此需要设置为免密登录(见图37): $ ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa $ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys $ chmod 0600 ~/.ssh/authorized_keys 图37设置SSH免密登录 2) 伪分布配置 (1) 修改Hadoop配置文件中的环境变量设置,首先运行命令: $ gedit ./hadoop-3.3.4/etc/hadoop/hadoop-env.sh 打开文件后,可将其中的JAVA_HOME设置为正确的路径,具体如图38所示。 图38配置JAVA_HOME环境变量 提示: 系统中设置JAVA_HOME环境变量后,如果未修改配置文件中的JAVA_HOME环境变量设置,那么启动Hadoop时,仍会报错“ERROR: JAVA_HOME is not set and could not be found”。 思考: Hadoop 3.3.x读取hadoopenv.sh中设置的JAVA_HOME环境变量,而不是系统中的JAVA_HOME环境变量,这样设计的目的是什么? (2) 修改Hadoop配置文件etc/hadoop/coresite.xml,设置默认的文件系统,示例如下: fs.defaultFS <--! default HDFS server URL, 请根据实际修改 --> hdfs://localhost:9000 (3) 修改配置文件etc/hadoop/hdfssite.xml,设置默认的文件副本数量等。示例如下: dfs.replication 1 dfs.namenode.name.dir file:/home/o/hadoop-3.3.4/tmp/dfs/name dfs.datanode.data.dir file:/home/o/hadoop-3.3.4/tmp/dfs/data 说明: 在伪分布模式下,Hadoop会使用临时目录存储名字服务、数据服务的临时文件,默认的临时文件存放路径是系统/tmp目录。该路径下的文件在Linux系统重启时可能会被清理,导致namenode启动失败。建议将该临时目录修改为不会被自动清理的路径。 3. 启动 1) 文件系统初始化 首次使用HDFS服务时,需要格式化文件系统。使用如下命令进行格式化,并等待格式化完成: $ ./hadoop-3.3.4/bin/hdfs namenode -format 格式化成功后会有“successfully formatted”提示字样,如图39 所示。 注意: 文件系统格式化仅需要在系统初始化时执行一次,以后使用时不再格式化; 否则已有数据会丢失。 图39HDFS格式化成功提示信息 2) 启动HDFS 执行脚本命令,启动HDFS: $ ./hadoop-3.3.4/sbin/start-dfs.sh 注意: 脚本命令位于sbin目录,而不是bin目录下。 正常启动后,可以看到NameNode、DataNode等服务进程,也可通过浏览器浏览NameNode或DataNode的相关信息,如图310 所示。NameNode的默认Web服务地址是: http://localhost:9870/。 图310监测HDFS服务 4. HDFS操作 如图311所示,执行创建目录、上传文件、执行程序、查看结果等命令,实现多种HDFS操作。具体可参考HDFS用户手册,示例代码如下: $ ./hadoop-3.3.4/bin/hdfs dfs -mkdir -p /user/o/input $ ./hadoop-3.3.4/bin/hdfs dfs -put ./hadoop-3.3.4/etc/hadoop/*.xml input $ ./hadoop-3.3.4/bin/hadoop jar ./hadoop-3.3.4/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.4.jar grep input output 'dfs[a-z.]+' $ ./hadoop-3.3.4/bin/hdfs dfs -cat output/* 图311HDFS操作命令 5. 停止HDFS服务 如果有必要,则可执行脚本命令,停止HDFS服务: $ ./hadoop-3.3.4/sbin/stop-dfs.sh 3.3.2配置Spark访问HDFS 由于下载使用的Spark安装包中已经包含Hadoop相关的依赖包,所以这里无须进行特殊配置,即可直接访问HDFS中的数据。如图312所示,启动Spark shell后,在交互环境中加载HDFS中的文件(请确保HDFS服务已经启动,且文件路径正确): val xml2 = sc.textFile("hdfs://localhost:9000/user/o/input/core-site.xml") xml2.take(5) 图312Spark shell中访问HDFS文件 说明: Spark对本地文件与HDFS文件的访问方法是一致的。HDFS路径以“hdfs://”修饰,本地文件则以“file://”修饰。如果未指明访问协议,则默认是本地文件。 3.4使用Spark shell Spark shell是一个交互方式的数据分析工具,也是Spark API学习环境,包括Scala(在JVM上运行)版及Python版。 3.4.1启动Spark shell 输入如下命令,启动Spark shell: # Scala 环境 $ ./spark-3.3.0/bin/spark-shell # Python 环境 $ ./spark-3.3.0/bin/pyspark Scala版本提供Scala交互shell,可以直接执行Scala代码(参见第2章的 有关内容)。以下以Scala环境(版本)的Spark shell为例介绍。 3.4.2使用Spark shell Spark的主要抽象是称为数据集(Dataset)的分布式数据项的集合。数据集可以从本地文件、Hadoop Input Formats(如HDFS文件)创建,也可通过转换其他数据集来创建。 Spark shell启动时,会创建Spark环境(context)以及会话(Session)对象,可直接用于后续的数据分析或交互。 在Spark shell中加载文本数据,并查看文件首行内容,可使用类似下面的命令(输入命令以加粗形式表示。由于是交互式环境,每行命令输入后会获得相应的反馈): scala> val textFile = spark.read.textFile("README.md") val textFile: org.apache.spark.sql.Dataset[String] = [value: string] scala> textFile.first() val res0: String = #Apache Spark 注意: “scala>”是Scala Spark shell的提示符,不是输入内容。 注意: Spark采用惰性机制。对RDD而言,直到执行RDD动作(Action)命令时,才真正触发对数据集的加载、转换等一系列操作。因此,即使加载一个不存在的文件,在加载时也不会报错(加载时不报错,查看内容时报错),如图 313所示。 图313Spark中动作操作触发实际计算 数据集的转换(Transformation)和动作可用于更复杂的计算,执行命令及结果如图314所示,示例代码如下: // 统计文件中包含"Spark"的行数: scala> textFile.filter(line => line.contains("Spark")).count() // 最长行所包含的单词数 scala> textFile.map(line => line.split(" ").size) .reduce((a, b) => if (a > b) a else b) // 大数据经典例子 Word Count scala> val wordCounts = textFile.flatMap( line => line.split("[ ,.]+")).groupByKey(identity).count().collect() 图314执行数据转换和动作 3.4.3退出Scala Spark shell 在Spark shell中执行“:quit”命令(简写为“:q”),或按组合键Ctrl+D退出: scala> :quit 3.4.4Spark shell常用选项 启动Spark shell时,使用“help”(或“h”)选项,可列出shell命令选项(参数),如图315所示。常用选项如下: (1) “master”用于指定连接的服务器地址(默认为本地模式,“local[*]”)。 (2) “deploymode”用于指定客户应用启动模式(默认为client)。 (3) “conf”用于设置相关配置项(如内存负载、Shuffle分区数等)。 (4) “jars”用于导入依赖的jar包等。 各选项的具体用法,请参考Spark用户手册。 图315Spark shell命令选项 3.5Spark开发环境 本书基于Scala编程语言进行Spark应用开发。因此,所介绍的开发环境主要考虑Spark的Scala开发环境,包括命令行工具、IDE环境等。 3.5.1SBT SBT全称是 Simple Build Tool,是Scala、Java构建工具,与Maven或Gradle类似。SBT依赖于Java 8(1.8)或以上版本。 官方推荐的安装方式是使用cs setup(参考2.1.2节的有关内容)。本节仅介绍Linux环境下的SBT的手动安装、部署过程。 1. 安装SBT (1) 可到官方网站(或镜像网站)选择合适的稳定版本的SBT进行下载,当前版本是SBT 1.7.2,镜像下载命令如图316所示。 图316SBT的镜像下载 说明: 考虑网络等原因,建议使用断点续传(wget)“c”选项; 为便于管理可下载到指定路径(使用“P”选项)。 Ubuntu用户也可以下载安装包安装,或直接在线安装。具体请参考相关资料。 (2) SBT依赖于Java环境,所以需要确保系统已安装Java。支持SBT 1.7.2的Java版本包括8、11、17等。下载完成后,对压缩包进行解压: $ tar -zxf ./Downloads/sbt-1.7.2.tgz -C ./scala-2.13.8 可以根据实际需要,将SBT添加到搜索路径(设置为PATH环境变量),具体可参考2.1.2节的相关内容。 (3) 如图317所示,运行sbt shell命令(请确保Java安装正确),查看SBT版本信息: $ ./scala-2.13.8/sbt/bin/sbt --version 图317查看SBT版本信息 注意: 在SBT交互环境中,可以使用help命令查看SBT shell的相关命令,使用exit命令退出SBT shell。 2. SBT使用示例 1) 最小SBT构建 最小SBT构建使用默认设置,仅需要一个空的SBT文件,创建的build.sbt文件如下: $ mkdir ./scala-examples $ cd ./scala-examples $ touch build.sbt# 创建空的SBT文件 2) 启动SBT shell 如图318所示,运行命令启动SBT shell。 图318启动SBT shell 3) 编译 启动SBT编译命令,运行结果如图319所示,可以看到编译成功的提示信息。 图319SBT编译 SBT shell支持即时编译模式,即在修改代码的同时进行编译,运行结果如图320所示。 图320即时编译模式 3. 使用SBT shell进行构建 1) 编写项目Scala代码 创建SBT构建所需的目录结构,并编写源代码(Hello.scala): $ mkdir -p ./src/main/scala/example $ gedit ./src/main/scala/example/Hello.scala 在源文件(Hello.scala)中输入如下示例代码: package example object Hello { def main(args: Array[String]): Unit = { println("Hello") println("Welcome to Wenzhou University!") println("Welcome to AI School,Wenzhou University!") } } 2) 编译项目 运行SBT shell的compile命令,对项目进行编译(或即时编译),如图321所示。 图321编译项目 如果源代码有错误,则根据提示信息进行修改后再编译。 3) 运行代码 运行SBT shell的run命令,执行编译后的项目,如图322所示。 图322代码运行 4) 项目属性设置 (1) 运行SBT shell的set命令,设置构建版本信息,运行结果如图323所示,代码如下: sbt:sbt-examples> set ThisBuild / scalaVersion := "2.13.8" sbt:sbt-examples> scalaVersion# 验证设置 图323构建版本信息 (2) 运行SBT shell的session save命令,将交互环境中的会话设置信息保存到build.sbt文件中: sbt:sbt-examples> session save (3) 编辑build.sbt文件,对项目进行命名,设置版本,添加依赖或设置其他属性,如: $ gedit ./build.sbt 文件内容参考如下: // project version ThisBuild / version := "0.1.0" ThisBuild / scalaVersion := "2.13.8" ThisBuild / organization := "cn.edu.wzu.example" lazy val hello = (project in file(".")) .settings( // project name name := "Hello", // project dependency libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.7" % Test, ) (4) 运行SBT shell的reload命令,重新加载属性更新后的项目,如图324所示。 图324重新加载项目 注意: 重新加载项目后,SBT shell的提示符发生了变化(更新后的项目名)。 (5) 在SBT shell中执行exit命令,或按Ctrl+D组合键退出: sbt:sbt-examples> exit 4. 使用SBT构建Spark应用程序 用Spark API 编写的独立应用程序,可以使用SBT构建。 首先,按照SBT构建目录结构要求创建相应的目录,并编写源代码文件。例如,创建一个Simple Spark App项目,其目录结构如下: $ find . . ./build.sbt ./src ./src/main ./src/main/scala ./src/main/scala/SimpleSparkApp.scala 代码SimpleSparkApp.scala的内容示例如下: /** * SimpleSparkApp.scala * * @author Rujun Cao * @date 2022/10/00 */ package cn.edu.wzu.SparkExample import org.apache.spark.sql.SparkSession // This example illustrates Spark session / Dataset // Counting the number of lines with 's' or 't' object SimpleSparkApp { def main(args: Array[String]): Unit = { // A file from command-line, or default = "README.md" val logFile = if (args.length > 0) args(0) else "README.md" val spark = SparkSession.builder .appName("Simple Spark Application").getOrCreate() val logData = spark.read.textFile(logFile).cache() val numSs = logData.filter(line => line.contains("s")).count() val numTs = logData.filter(line => line.contains("t")).count() println(s"Lines with s: $numSs, Lines with t: $numTs") spark.stop() } } 构建文件build.sbt的内容示例如下: name := "Simple Spark Project" version := "0.1.0" scalaVersion := "2.13.8" libraryDependencies += "org.apache.spark" %% "spark-sql" % "3.3.0" 创建好项目结构及内容后,使用SBT程序进行打包: $ ~/scala-2.13.8/sbt/bin/sbt package 打包过程中SBT会自动下载相关依赖包。初次打包时需要下载的内容较多,下载时间稍长,后续打包速度相对较快。打包完成后,会有success的提示字样。如果源代码有错误,则根据提示信息进行修改后,再次编译、打包。 说明: SBT程序打包的输出路径为./target/scala2.xx。 打包完成后即可将应用程序提交给Spark执行,如图325所示。 $ ../bin/spark-submit ./target/scala-2.13/simple-spark-project_2.13-0.1.0.jar ../README.md 图325执行打包程序 程序执行后,可以查看运行结果(例子程序的结果类似于图325的“Lines with ...”)。 说明: 对简单的应用程序,也可以直接使用scalac进行编译、打包。如对于上述例子可以使用下面的命令: $ ~/scala-2.13.8/bin/scalac -classpath ../jars/spark-core_2.13-3.3.0.jar:../jars/scala-library-2.13.8.jar:../jars/spark-sql_2.13-3.3.0.jar ./src/main/scala/SimpleSparkApp.scala -d SimpleSparkProj.jar 5. 使用SBT镜像服务器 使用SBT会自动下载依赖包,默认会使用官方服务器地址。由于网络等原因,默认的官方服务器下载速度较慢。这时,可以使用国内镜像站点或镜像仓库。 使用镜像仓库,需要编辑SBT的仓库配置文件repositories,该文件位于~/.sbt目录(隐藏目录,如果目录不存在则需要创建) $ gedit ~/.sbt/repositories 其内容参考如下: [repositories] local # 设置华为云镜像仓库 huaweicloud-maven: https://repo.huaweicloud.com/repository/maven/ 具体镜像仓库地址等可以查找相关资料。 3.5.2IntelliJ IDEA IntelliJ IDEA是由JetBrains创建的集成开发环境(Integrated Development Environment,IDE),其社区版(Community)是基于Apache v2许可协议的开源版本。IntelliJ集成了许多构建工具(包括SBT),可以用来导入项目。 1. 安装IntelliJ IDEA 可在JetBrains官方网站下载IntelliJ IDEA社区版。下载后进行解包、安装。Ubuntu用户也可以通过软件中心(Software Center)直接搜索、安装,安装界面如图326所示。 图326安装IDEA 说明: IntelliJ IDEA 教育版(Educational)是针对学生或教师提供的免费旗舰版(Ultimate),学生或教师用户可根据需要选用。 2. 安装Scala插件 启动IDEA后,选择插件页面(Plugins Tab),在可用插件列表中选择Scala后(如果未列出Scala,那么可以用搜索框搜索),单击Install按钮,如图327所示。 图327在IDEA中安装Scala插件 插件安装完成后,根据提示重启IDE。 3. 导入Spark项目 启动IDEA后,依次选择Projects→Open,在弹出的窗口中选择已创建的Spark/Scala项目(目录中包含build.sbt)后,单击OK按钮,如图328所示。 提示: 也可以通过选择“从已有代码创建项目”的方式导入项目,具体操作步骤是: 依次选择File→New→Project from Existing Sources菜单项,再选择项目目录中的build.sbt文件。 说明: IntelliJ Scala插件使用自己的轻量级编译引擎来检测错误,速度快但可能有错误。可以将IntelliJ配置为使用Scala编译器,以突出错误显示。 4. 代码交互调试 使用IDEA便于交互式调试程序。在IDEA中打开需要调试的代码,在适当位置设置断点(Break point)后,即可启动程序调试模式,进入交互调试过程,如图329所示。 当测试达到断点时,可以检查变量的值等信息。 提示: IDEA中设置/取消断点的组合键是Ctrl+F8,也可以在编辑窗口左侧的代码行提示位置处,用鼠标单击设置/取消断点。进入调试模式的组合键是Shift+F9。 图328导入Spark项目 图329在IDEA中调试代码