版權聲明:原創(chuàng)作品,謝絕轉載!否則將追究法律責任。
楔子
我是在2013年底第一次聽說Spark,當時我對Scala很感興趣,而Spark就是使用Scala編寫的。一段時間之后,我做了一個有趣的數據科學項目,它試著去預測在泰坦尼克號上幸存。對于進一步了解Spark內容和編程來說,這是一個很好的方式。對于任何有追求的、正在思考如何著手 Spark 的程序員,我都非常推薦這個項目。
今天,Spark已經被很多巨頭使用,包括Amazon、eBay以及Yahoo!。很多組織都在擁有成千上萬節(jié)點的集群上運行Spark。根據Spark FAQ,已知的最大的Spark集群擁有超過8000個節(jié)點。Spark確實是一個值得好好考慮和學習的技術。
Apache Spark是什么?一個簡單介紹
Spark是一個Apache項目,它被標榜為“快如閃電的集群計算”。它擁有一個繁榮的開源社區(qū),并且是目前最活躍的Apache項目。
Spark提供了一個更快、更通用的數據處理平臺。和Hadoop相比,Spark可以讓你的程序在內存中運行時速度提升100倍,或者在磁盤上運行時速度提升10倍。去年,在100 TB Daytona GraySort比賽中,Spark戰(zhàn)勝了Hadoop,它只使用了十分之一的機器,但運行速度提升了3倍。Spark也已經成為針對 PB 級別數據排序的最快的開源引擎。
Spark Core
Spark Core是一個基本引擎,用于大規(guī)模并行和分布式數據處理。它主要負責:
內存管理和故障恢復
在集群上安排、分布和監(jiān)控作業(yè)
和存儲系統(tǒng)進行交互
Spark引入了一個稱為彈性分布式數據集(RDD,Resilient Distributed Dataset)的概念,它是一個不可變的、容錯的、分布式對象集合,我們可以并行的操作這個集合。RDD可以包含任何類型的對象,它在加載外部數據集或者從驅動應用程序分發(fā)集合時創(chuàng)建。
RDD支持兩種操作類型:
轉換是一種操作(例如映射、過濾、聯接、聯合等等),它在一個RDD上執(zhí)行操作,然后創(chuàng)建一個新的RDD來保存結果。
行動是一種操作(例如歸并、計數、第一等等),它在一個RDD上執(zhí)行某種計算,然后將結果返回。
在Spark中,轉換是“懶惰”的,也就是說它們不會立刻計算出結果。相反,它們只是“記住”要執(zhí)行的操作以及要操作的數據集(例如文件)。只有當行為被調用時,轉換才會真正的進行計算,并將結果返回給驅動器程序。這種設計讓Spark運行得更有效率。例如,如果一個大文件要通過各種方式進行轉換操作,并且文件被傳遞給第一個行為,那么Spark只會處理文件的第一行內容并將結果返回,而不會處理整個文件。
默認情況下,當你在經過轉換的RDD上運行一個行為時,這個RDD有可能會被重新計算。然而,你也可以通過使用持久化或者緩存的方法,將一個RDD持久化從年初在內存中,這樣,Spark就會在集群上保留這些元素,當你下一次查詢它時,查詢速度會快很多。
SparkSQL
SparkSQL是Spark的一個組件,它支持我們通過SQL或者Hive查詢語言來查詢數據。它最初來自于Apache Hive項目,用于運行在Spark上(來代替MapReduce),現在它已經被集成到Spark堆中。除了針對各種各樣的數據源提供支持,它還讓代碼轉換與SQL查詢編織在一起變得可能,這最終會形成一個非常強大的工具。下面是一個兼容Hive的查詢示例:
Spark Streaming
Spark Streaming支持對流數據的實時處理,例如產品環(huán)境web服務器的日志文件(例如Apache Flume和HDFS/S3)、諸如Twitter的社交媒體以及像Kafka那樣的各種各樣的消息隊列。在這背后,Spark Streaming會接收輸入數據,然后將其分為不同的批次,接下來Spark引擎來處理這些批次,并根據批次中的結果,生成最終的流。
MLlib
MLlib是一個機器學習庫,它提供了各種各樣的算法,這些算法用來在集群上針對分類、回歸、聚類、協同過濾等(可以在 machine learning 上查看Toptal的文章,來獲取更過的信息)。其中一些算法也可以應用到流數據上,例如使用普通最小二乘法或者K均值聚類(還有更多)來計算線性回歸。Apache Mahout(一個針對Hadoop的機器學習庫)已經脫離MapReduce,轉而加入Spark MLlib。
GraphX
GraphX是一個庫,用來處理圖,執(zhí)行基于圖的并行操作。它針對ETL、探索性分析和迭代圖計算提供了統(tǒng)一的工具。除了針對圖處理的內置操作,GraphX還提供了一個庫,用于通用的圖算法,例如PageRank。
如何使用Apache Spark:事件探測用例
既然我們已經回答了“Apache Spark是什么?”這個問題,接下來讓我們思考一下,使用Spark來解決什么樣的問題或者挑戰(zhàn)最有效率。
最近,我偶然看到了一篇關于 通過分析Twitter流的方式來探測地震 的文章。它展示了這種技術可以比日本氣象廳更快的通知你日本哪里發(fā)生了地震。雖然那篇文章使用了不同的技術,但我認為這是一個很好的示例,可以用來說明我們如何通過簡單的代碼片段,在不需要”膠水代碼“的情況下應用Spark。
首先,我們需要處理tweet,將那些和”地震“或”震動“等相關的內容過濾出來。我們可以使用Spark Streaming的方式很容易實現這一目標,如下所示:
2TwitterUtils.createStream(...)
.filter(_.getText.contains("earthquake")||_.getText.contains("shaking"))
然后,我們需要在tweets上運行一些語義分析,來確定它們是否代表當前發(fā)生了地震。例如,像“地震!”或者“現在正在震動”這樣的tweets,可能會被認為是正向匹配,而像“參加一個地震會議”或者“昨天的地震真可怕”這樣的tweets,則不是。這篇文章的作者使用了一個支持向量機(support vector machine, SVM)來實現這一點。我們在這里使用同樣的方式,但也可以試一下流版本。一個使用了MLlib的代碼示例如下所示:
1.實戰(zhàn)文檔如下
Spark下載
為了方便,我直接是進入到了/usr/src文件夾下面進行下載spark-2.1.1
wget https://d3kbcqa49mib13.cloudfront.net/spark-2.2.0-bin-hadoop2.7.tgz
Spark安裝之前的準備
文件的解壓與改名
tar-zxfspark-2.1.1-bin-hadoop2.7.tgz
rm-rfspark-2.1.1-bin-hadoop2.7.tgz
為了我后面方便配置spark,在這里我把文件夾的名字給改了
mvspark-2.1.1-bin-hadoop2.7spark-2.1.1
配置環(huán)境變量
vi/etc/profile
在最尾巴加入
exportSPARK_HOME=/usr/src/spark-2.1.1
exportPATH=$PATH:$SPARK_HOME/bin
配置Spark環(huán)境
打開spark-2.1.1文件夾
cdspark-2.1.1
此處需要配置的文件為兩個
spark-env.sh和slaves
首先我們把緩存的文件spark-env.sh.template改為spark識別的文件spark-env.sh
cp conf/spark-env.sh.templateconf /spark-env.sh
修改spark-env.sh文件
viconf/spark-env.sh
注意!變量按照個人條件情況路徑配置
在最尾巴加入
exportJAVA_HOME=/usr/java/jdk1.7.0_141
exportSCALA_HOME=/usr/scala-2.1.1
exportHADOOP_HOME=/usr/local/hadoop-2.7.2
exportHADOOP_CONF_DIR=/usr/local/hadoop-2.7.2/etc/hadoop
exportSPARK_MASTER_IP=SparkMaster
exportSPARK_WORKER_MEMORY=4g
exportSPARK_WORKER_CORES=2
exportSPARK_WORKER_INSTANCES=1
變量說明
JAVA_HOME:Java安裝目錄
SCALA_HOME:Scala安裝目錄
HADOOP_HOME:hadoop安裝目錄
HADOOP_CONF_DIR:hadoop集群的配置文件的目錄
SPARK_MASTER_IP:spark集群的Master節(jié)點的ip地址
SPARK_WORKER_MEMORY:每個worker節(jié)點能夠最大分配給exectors的內存大小
SPARK_WORKER_CORES:每個worker節(jié)點所占有的CPU核數目
SPARK_WORKER_INSTANCES:每臺機器上開啟的worker節(jié)點的數目
修改slaves文件
viconf/slaves或者
在最后面修成為
SparkWorker1
SparkWorker2
注意!如果是dan臺PC可以不用同步rsync
同步SparkWorker1和SparkWorker2的配置
在此我們使用rsync命令
rsync -av/usr/src/spark-2.1.1/SparkWorker1:/usr/src/spark-2.1.1/
rsync -av/usr/src/spark-2.1.1/SparkWorker2:/usr/src/spark-2.1.1/
啟動Spark集群
因為我們只需要使用hadoop的HDFS文件系統(tǒng),所以我們并不用把hadoop全部功能都啟動。
啟動hadoop的HDFS文件系統(tǒng)
start-dfs.sh
但是在此會遇到一個情況,就是使用start-dfs.sh,啟動之后,在SparkMaster已經啟動了namenode,但在SparkWorker1和SparkWorker2都沒有啟動了datanode,這里的原因是:datanode的clusterID和namenode的clusterID不匹配。是因為SparkMaster多次使用了hadoop namenode -format格式化了。
==解決的辦法:==
在SparkMaster使用
cat/usr/src/hadoop-2.7.2/hdfs/name/current/VERSION
查看clusterID,并將其復制。
在SparkWorker1和SparkWorker2上使用
vi/usr/src/hadoop-2.7.2/hdfs/name/current/VERSION
將里面的clusterID,更改成為SparkMasterVERSION里面的clusterID
做了以上兩步之后,便可重新使用start-dfs.sh開啟HDFS文件系統(tǒng)。
啟動之后使用jps命令可以查看到SparkMaster已經啟動了namenode,SparkWorker1和SparkWorker2都啟動了datanode,說明hadoop的HDFS文件系統(tǒng)已經啟動了。
啟動Spark
因為hadoop/sbin以及spark/sbin均配置到了系統(tǒng)的環(huán)境中,它們同一個文件夾下存在同樣的start-all.sh文件。最好是打開spark-2.2.0,在文件夾下面打開該文件。
./sbin/start-all.sh
成功打開Spark集群之后可以進入Spark的WebUI界面,可以通過
SparkMaster_IP:8080例:192.168.1.186:8080
訪問,可見有兩個正在運行的Worker節(jié)點。
打開Spark-shell
使用
spark-shell? and? ./bin/spark-shell
便可打開Spark的shell
同時,因為shell在運行,我們也可以通過
SparkMaster_IP:4040
訪問WebUI查看當前執(zhí)行的任務。
結言
到此我們的Spark集群就搭建完畢了。搭建spark集群原來知識網絡是挺龐大的,涉及到Linux基本操作,設計到ssh,設計到hadoop、Scala以及真正的Spark。在此也遇到不少問題,通過翻閱書籍以及查看別人的blog得到了解決。在此感謝分享知識的人。希望自己越努力越幸運!
本文出自 “李世龍” 博客,謝絕轉載!