統一配置環境:
zk:3.4.9
jdk:1.8
IDEA:2019.1.x64
目錄標題
Spark概述
spark主要用在計算機集羣上進行並行數據處理
集羣搭建
(1)下載spark安裝包
# 下載 Spark
cd /export/softwares
wget https://archive.apache.org/dist/spark/spark-2.2.0/spark-2.2.0-bin-hadoop2.7.tgz
(2)上傳並解壓
使用ssh工具上傳安裝包到/export/softwore
tar -zxvf
(3)配置spark-env.sh
//拷貝配置文件模板,在對模板進行修改
cp spark-env.sh.templat spark-env.sh
使用Notepad++連接node01進行修改配置文件
# 指定 Java Home
export JAVA_HOME=/export/servers/jdk1.8.0
# 指定 Spark Master 地址
export SPARK_MASTER_HOST=node01
export SPARK_MASTER_PORT=7077
(5)修改slaves
1.使用場景環境
- 修改配置文件 slaves, 的ip映射可以實現從在使用 sbin/start-all.sh 啓動集羣的時候, 可以一鍵啓動整個配置映射的集羣,的所有的 Worker
2.配置流程
進入配置目錄, 並複製一份新的配置文件, 以供在此基礎之上使用Notepad++連接node01進行修改
//拷貝配置文件模板,在對模板進行修改
cp slaver.templat slaver
//配置從節點地址
node01
node02
node03
(4)配置HistoryServe
1.使用場景
默認情況下, Spark 程序運行完畢後, 就無法再查看運行記錄的 Web UI 了, 通過 HistoryServer 可以提供一個服務, 通過讀取日誌文件, 使得我們可以在程序運行結束後, 依然能夠查看運行過程
2.配置流程
- 進入配置目錄, 並複製一份新的配置文件, 以供在此基礎之上使用Notepad++連接node01進行修改
cp spark-defaults.conf.template spark-defaults.conf
- 將以下內容複製到
spark-defaults.conf
末尾處, 通過這段配置, 可以指定 Spark 將日誌輸入到 HDFS 中
spark.eventLog.enabled true
spark.eventLog.dir hdfs://node01:8020/spark_log
spark.eventLog.compress true
將以下內容複製到spark-env.sh
的末尾, 配置 HistoryServer 啓動參數, 使得 HistoryServer 在啓動的時候讀取 HDFS 中寫入的 Spark 日誌
# 指定 Spark History 運行參數
export SPARK_HISTORY_OPTS="-Dspark.history.ui.port=4000 -Dspark.history.retainedApplications=3 -Dspark.history.fs.logDirectory=hdfs://node01:8020/spark_log"
爲 Spark 創建 HDFS 中的日誌目錄
hdfs dfs -mkdir -p /spark_log
(5)分發
將 Spark 安裝包分發給集羣中其它機器
cd /export/servers
scp -r spark root@node02:$PWD
scp -r spark root@node03:$PWD
啓動 Spark Master 和 Slaves, 以及 HistoryServer
cd /export/servers/spark
sbin/start-all.sh
sbin/start-history-server.sh
(6)高可用配置
1.使用場景
對於 Master 來說, 是會出現單點失敗的, 爲了避免可能出現的單點失敗問題
解決辦法:
- 使用 Zookeeper 實現 Masters 的主備切換
2.實現流程
- 停止spark集羣
cd /export/servers/spark
sbin/stop-all.sh
- 修改配置文件,指定zookeeper位置
- 編輯 spark-env.sh, 添加 Spark 啓動參數, 並去掉 SPARK_MASTER_HOST 地址
# 指定 Java Home
export JAVA_HOME=/export/servers/jdk1.8.0_141
# 指定 Spark Master 地址
# export SPARK_MASTER_HOST=node01
export SPARK_MASTER_PORT=7077
# 指定 Spark History 運行參數
export SPARK_HISTORY_OPTS="-Dspark.history.ui.port=4000 -Dspark.history.retainedApplications=3 -Dspark.history.fs.logDirectory=hdfs://node01:8020/spark_log"
# 指定 Spark 運行時參數
export SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=node01:2181,node02:2181,node03:2181 -Dspark.deploy.zookeeper.dir=/spark"
3.分發配置到整個集羣
cd /export/servers/spark/conf
scp spark-env.sh node02:$PWD
scp spark-env.sh node03:$PWD
4.啓動
- 在 node01 上啓動整個集羣
cd /export/servers/spark
sbin/start-all.sh
sbin/start-history-server.sh
- 在 node02 上單獨再啓動一個 Master
cd /export/servers/spark
sbin/start-master.sh
Service | port |
---|---|
Master WebUI | node01:8080 |
Worker WebUI | node01:8081 |
History Server | node01:4000 |
(7)配置spark環境
1.修改配置文件
vim /etc/profile
export SPARK_BIN=/export/servers/spark/bin
export PATH=$PATH:$SPARK_BIN //將SPARK_BIN目錄添加到PATH的查找路徑中
2.使得配置生效
source /etc/profile
spark shell
1.使用場景
- 數據集的探索
- 測試
2.讀取本地文件
(1)準備文件
在 Node01 中創建文件 /export/data/wordcount.txt
//文件內容
hadoop spark flume
spark hadoop
flume hadoop
(2)啓動 Spark shell
cd /export/servers/spark
bin/spark-shell --master local[2]
Master地址可用有以下幾種設置方式
地址 | 解釋 |
---|---|
local[N] | 使用 N 條 Worker 線程在本地運行 |
spark://host:port | 在 Spark standalone 中運行, 指定 Spark 集羣的 Master 地址, 端口默認爲 7077 |
mesos://host:port | 在 Apache Mesos 中運行, 指定 Mesos 的地址 |
yarn | 在 Yarn 中運行, Yarn 的地址由環境變量 HADOOP_CONF_DIR 來指定 |
讀取本地文件進行詞頻統計流程
- 讀取文件
val rdd1 = sc.textFile("file:///export/data/wordcount.txt")
- 拆分文件
val rdd2 = rdd1.flatMap(item => item.split(" "))
- 給與每個單詞的詞頻爲1
val rdd3 = rdd2.map(word => word -> 1)
- 安裝單詞進行詞頻聚合
val rdd4 = rdd3.reduceByKey((curr,agg) => curr+agg)
rdd4.collect()
2.讀取HDFS文件進行詞頻統計
(1)上傳文件到 HDFS 中
cd /export/data
hdfs dfs -mkdir /dataset
hdfs dfs -put wordcount.txt /dataset/
(2)在 Spark shell 中訪問 HDFS
val sourceRdd = sc.textFile("hdfs://node01:8020/dataset/wordcount.txt")
val flattenCountRdd = sourceRdd.flatMap(_.split(" ")).map((_, 1))
val aggCountRdd = flattenCountRdd.reduceByKey(_ + _)
val result = aggCountRdd.collect
spark 採用IDEA編寫WordCount案例
1.創建maven
<properties>
<scala.version>2.11.8</scala.version>
<spark.version>2.2.0</spark.version>
<slf4j.version>1.7.16</slf4j.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>${spark.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/scala</sourceDirectory>
<testSourceDirectory>src/test/scala</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
<configuration>
<args>
<arg>-dependencyfile</arg>
<arg>${project.build.directory}/.scala_dependencies</arg>
</args>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass></mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
在main和text下分別創建scala的目錄.在目錄被編寫scala代碼
2.wordcount實現並本地運行
package cn.ityuge.spark.rdd
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
object WordCount {
def main(args: Array[String]): Unit = {
//1,創建sparkContext
val conf = new SparkConf().setMaster("local[6]").setAppName("word_count")
val sc = new SparkContext(conf)
//2.加載文件
//2.1準備文件
//2.2讀取文件
val rdd1: RDD[String] = sc.textFile("./data/wordcount.txt")
//3.處理
//3.1把整句話拆分爲多個單詞
val rdd2: RDD[String] = rdd1.flatMap(x=>x.split(" "))
//3.2把每個單詞指定詞頻1
val rdd3: RDD[(String, Int)] = rdd2.map(x=>(x,1))
println(rdd3)
//3.3聚合操作
val rdd4 = rdd3.reduceByKey((curr,agg)=>curr+agg) //curr當前值,agg局部結果
//4.獲得結果
val result = rdd4.collect()
result.foreach(item => println(item))
}
}
3.提交到集羣運行
先把idea編寫的代碼通過maven插件打成jar包通過ssh傳輸到node01節點上
spark-submit --master spark://node01:7077 \
--class cn.itcast.spark.WordCounts \
original-spark-0.1.0.jar
RDD編程模型
spark並行計算(RDD)的五個特性
-
有一個分片列表.只有當數據可以進行切分,分發到每臺計算節點上纔可以實現並行計算
-
有一個函數計算每一個分片
-
key-value型的RDD是根據哈希來分區的,類型於mapreduce當中的Paritioner接口,控制key分到哪個reduce
RRD代碼
1.程序入口
程序入口一個方法叫SparkContext(conf), conf是一個配置用SparkConf()方法來進行設置
2.mapflat算子
先是使用map令一個字符串變爲以指定方式進行分割,生成一個數組,在通過flat打開數組得到每一個元素
2.reduceByKey
curr 是獲取的一個k對應的值,agg的一個累加的結果,來一個Hello,獲取到值爲1和agg相加,就更新了agg的值從0到1了
在來一個Hello,獲取其值爲1,和agg相加,就是從1到2.