From c15c67529902aefe4debce90cd821563c478e20f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E7=A5=A5?= <1366971433@qq.com> Date: Tue, 4 Jun 2019 13:18:17 +0800 Subject: [PATCH] =?UTF-8?q?spark=E5=BC=80=E5=8F=91=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E6=90=AD=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- notes/installation/Spark开发环境搭建.md | 87 ++++++++---------- pictures/scala-sdk.png | Bin 0 -> 14091 bytes 2 files changed, 38 insertions(+), 49 deletions(-) create mode 100644 pictures/scala-sdk.png diff --git a/notes/installation/Spark开发环境搭建.md b/notes/installation/Spark开发环境搭建.md index 386559b..c38229e 100644 --- a/notes/installation/Spark开发环境搭建.md +++ b/notes/installation/Spark开发环境搭建.md @@ -2,35 +2,18 @@ - - ## 一、安装Spark -### 1.1 下载安装包 +### 1.1 下载并解压 -官网下载地址:http://spark.apache.org/downloads.html - -因为Spark常常和Hadoop联合使用,所以下载时候需要选择Spark版本和对应的Hadoop版本后再下载 +官方下载地址:http://spark.apache.org/downloads.html,选择Spark版本和对应的Hadoop版本后再下载:
- - -### 1.2 解压安装包 +解压安装包: ```shell # tar -zxvf spark-2.2.3-bin-hadoop2.6.tgz @@ -38,7 +21,7 @@ -### 1.3 配置环境变量 +### 1.2 配置环境变量 ```shell # vim /etc/profile @@ -51,28 +34,30 @@ export SPARK_HOME=/usr/app/spark-2.2.3-bin-hadoop2.6 export PATH=${SPARK_HOME}/bin:$PATH ``` -使得配置的环境变量生效: +使得配置的环境变量立即生效: ```shell # source /etc/profile ``` -### 1.4 Local模式 +### 1.3 Local模式 Local 模式是最简单的一种运行方式,它采用单节点多线程(cpu)方式运行,不用部署,开箱即用,适合日常测试开发。 ```shell -# 启动命令 +# 启动spark-shell spark-shell --master local[2] ``` -- local:只启动一个工作线程; -- local[k]:启动k个工作线程; -- local[*]:启动跟cpu数目相同的工作线程数。 +- **local**:只启动一个工作线程; +- **local[k]**:启动k个工作线程; +- **local[*]**:启动跟cpu数目相同的工作线程数。
-采用这种模式创建后,你会进入Scala交互式命令行,并且程序已经自动创建了SparkContext,即Spark的应用上下文,等效于执行了下面的Scala代码: +
+ +进入spark-shell后,程序已经自动创建好了上下文`SparkContext`,等效于执行了下面的Scala代码: ```scala val conf = new SparkConf().setAppName("Spark shell").setMaster("local[2]") @@ -85,7 +70,7 @@ val sc = new SparkContext(conf) ## 二、词频统计案例 -安装完成后可以先做一个简单的词频统计例子,感受spark的魅力。准备一个词频统计的文件样本wc.txt,内容如下: +安装完成后可以先做一个简单的词频统计例子,感受spark的魅力。准备一个词频统计的文件样本`wc.txt`,内容如下: ```txt hadoop,spark,hadoop @@ -101,11 +86,11 @@ val wordCounts = file.flatMap(line => line.split(",")).map((word => (word, 1))). wordCounts.collect ``` -执行过程如下: +执行过程如下,可以看到已经输出了词频统计的结果:
-可以通过spark shell web-ui可以查看作业的执行情况,访问端口为4040 +同时还可以通过Web UI查看作业的执行情况,访问端口为`4040`:
@@ -117,43 +102,41 @@ wordCounts.collect Spark是基于Scala语言进行开发的,分别提供了基于Scala、Java、Python语言的API,如果你想使用Scala语言进行开发,则需要搭建Scala语言的开发环境。 -### 2.1 前置条件 +### 3.1 前置条件 -首先Scala的运行依赖于Java环境,目前最新的Scala 2.12.x要求你必须安装JDK 1.8或以上版本。 +Scala的运行依赖于JDK,所以需要你本机有安装对应版本的JDK,最新的Scala 2.12.x需要JDK 1.8+。 -### 2.2 安装Scala插件 +### 3.2 安装Scala插件 -首先需要安装Scala插件,使得IDEA支持scala语言的开发。打开 IDEA,依次点击**File** => **settings**=> **plugins**选项卡,搜索Scala插件(如下图)。找到插件后进行安装,并重启IDEA使得安装生效。 +IDEA默认不支持Scala语言的开发,需要通过插件进行扩展。打开 IDEA,依次点击 **File** => **settings**=> **plugins** 选项卡,搜索Scala插件(如下图)。找到插件后进行安装,并重启IDEA使得安装生效。
-### 2.3 创建Scala项目 +### 3.3 创建Scala项目 -在IDEA中依次点击 **File** => **New** => **Project**选项卡,然后选择创建Scala—IDEA工程: +在IDEA中依次点击 **File** => **New** => **Project** 选项卡,然后选择创建`Scala—IDEA`工程:
-### 2.4 下载Scala SDK +### 3.4 下载Scala SDK -#### 1.方式一 +#### 1. 方式一 -此时看到Scala SDK为空,依次点击`Create` => `Download` ,选择所需的版本后,点击`OK`按钮进行下载,下载完成点击`Finish`进入工程。 +此时看到`Scala SDK`为空,依次点击`Create` => `Download` ,选择所需的版本后,点击`OK`按钮进行下载,下载完成点击`Finish`进入工程。
-#### 2.方式二 +#### 2. 方式二 -方式一是Scala官方安装指南里使用的方式,但下载速度可能会比较慢,且这种安装下并没有直接提供Scala命令行工具。所以个人推荐使用方式二进行安装。 +方式一是Scala官方安装指南里使用的方式,但下载速度通常比较慢,且这种安装下并没有直接提供Scala命令行工具。所以个人推荐到官网下载安装包进行安装,下载地址:https://www.scala-lang.org/download/ -> 官方下载地址:https://www.scala-lang.org/download/ - -这里我的系统是Windows,下载msi版本的安装包后,一直点击下一步安装即可,安装完成后会自动配置好环境变量。 +这里我的系统是Windows,下载msi版本的安装包后,一直点击下一步进行安装,安装完成后会自动配置好环境变量。
@@ -165,9 +148,9 @@ Spark是基于Scala语言进行开发的,分别提供了基于Scala、Java、P -### 2.5 创建Hello World +### 3.5 创建Hello World -在工程 `src`目录上右击**New** => **Scala class**.创建`Hello.scala`。输入代码如下,完成后点击运行按钮,成功运行则代表搭建成功。 +在工程 `src`目录上右击 **New** => **Scala class** 创建`Hello.scala`。输入代码如下,完成后点击运行按钮,成功运行则代表搭建成功。
@@ -175,9 +158,9 @@ Spark是基于Scala语言进行开发的,分别提供了基于Scala、Java、P -### 2.6 切换Scala版本 +### 3.6 切换Scala版本 -在日常的开发中,由于Spark版本的切换,可能导致需要切换Scala版本,此时可以在`Project Structures`中的`Global Libraries`选项卡进行切换。 +在日常的开发中,由于对应软件(如Spark)的版本切换,可能导致需要切换Scala的版本,则可以在`Project Structures`中的`Global Libraries`选项卡中进行切换。
@@ -185,7 +168,13 @@ Spark是基于Scala语言进行开发的,分别提供了基于Scala、Java、P +### 3.7 可能出现的问题 + +在IDEA中有时候重新打开项目后,右击并不会出现新建`scala`文件的选项,或者在编写时没有Scala语法提示,此时可以先删除`Global Libraries`中配置好的SDK,之后再重新添加: + +
+**另外在IDEA中以本地模式运行Spark项目是不需要在本机搭建Spark和Hadoop环境的。** diff --git a/pictures/scala-sdk.png b/pictures/scala-sdk.png new file mode 100644 index 0000000000000000000000000000000000000000..eb275b429c7bd14e4ca26df343833a48cf865520 GIT binary patch literal 14091 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