賀釋千,張海濤,王宇賓,李可強(qiáng)
(河北科技師范學(xué)院數(shù)學(xué)與信息科技學(xué)院,河北 秦皇島,066004)
Spark是UC Berkeley AMP lab開(kāi)發(fā)的計(jì)算引擎[1],由Scala 語(yǔ)言編寫。處理大規(guī)模數(shù)據(jù)往往需要使用Spark,如大規(guī)模分布式機(jī)器學(xué)習(xí)[2],社交網(wǎng)絡(luò)分析及其相關(guān)算法[3,4]。該引擎的開(kāi)發(fā)和測(cè)試均是在Linux上完成的。雖然可以勉強(qiáng)在Windows上運(yùn)行,但使用中存在諸多問(wèn)題,如軟件包依賴問(wèn)題、防火墻問(wèn)題、端口沖突等。所以,無(wú)論是商業(yè)應(yīng)用還是科研工作大都是將Spark部署在Linux上運(yùn)行。但是,目前大多數(shù)學(xué)校實(shí)驗(yàn)室機(jī)器都使用Windows系統(tǒng),這為實(shí)際教學(xué)帶來(lái)了困難。而使用Docker可以解決這一難題。Docker是一個(gè)開(kāi)源的應(yīng)用容器引擎[5,6,7],類似一個(gè)輕量級(jí)的虛擬機(jī),但比虛擬機(jī)更輕??梢赃\(yùn)行在Linux和Windows 10(Windows 7通過(guò)虛擬機(jī)運(yùn)行)上。Docker支持將精心裁剪后的Linux及其軟件打包成為一個(gè)容器,然后將該容器的鏡像發(fā)布到網(wǎng)上(如DockerHub)供用戶下載。因?yàn)?,該容器的鏡像在發(fā)布前已經(jīng)將所有的運(yùn)行環(huán)境、軟件及依賴都打包完成。所以,用戶下載該容器的鏡像后,可以像運(yùn)行普通軟件一般,通過(guò)命令運(yùn)行該容器。這極大簡(jiǎn)化了軟件的部署。
雖然目前已經(jīng)有一些文獻(xiàn)介紹了基于Docker的應(yīng)用,如基于Docker的Hadoop平臺(tái)[8],但這不是針對(duì)實(shí)驗(yàn)教學(xué)。為此,筆者基于Docker為Spark搭建所需的Linux實(shí)驗(yàn)環(huán)境,并結(jié)合Jupyterhub,Anaconda等開(kāi)源項(xiàng)目搭建該實(shí)驗(yàn)平臺(tái),以期解決計(jì)算機(jī)實(shí)驗(yàn)面臨的一些實(shí)驗(yàn)困難問(wèn)題。
該平臺(tái)是B/S架構(gòu)的??蛻舳酥恍枰粋€(gè)瀏覽器訪問(wèn)服務(wù)器即可。服務(wù)器上平臺(tái)主要部分的架構(gòu)見(jiàn)圖1。
圖1 基于Docker的Spark云計(jì)算實(shí)驗(yàn)教學(xué)平臺(tái)的架構(gòu)
最下面是服務(wù)器操作系統(tǒng),其上是Docker,再其上是容器的操作系統(tǒng)Ubuntu,最上面兩層就是容器里主要安裝的軟件和庫(kù)。其中的JVM是Java虛擬機(jī),因?yàn)镾park的運(yùn)行需要Java虛擬機(jī)。Anaconda是一個(gè)包管理器,負(fù)責(zé)安裝和管理Python,Jupyterhub,PySpark。
PySpark是Spark官方支持的Python調(diào)用接口(庫(kù)),Jupyterhub是一個(gè)支持多用戶在瀏覽器中直接編寫Python代碼的項(xiàng)目。采用這樣的平臺(tái)架構(gòu)配置方案其原因有兩點(diǎn):(1)雖然Spark官方支持Scala,Java,Python和R等4種語(yǔ)言的API調(diào)用。但目前官方對(duì)Scala,Python兩種語(yǔ)言的API支持的最好。(2)現(xiàn)在學(xué)校大多開(kāi)設(shè)Python課程,學(xué)生對(duì)Python的接受程度更高。所以,接下來(lái)將搭建一個(gè)支持多用戶在瀏覽器中直接編寫Python代碼調(diào)用Spark的云計(jì)算實(shí)驗(yàn)教學(xué)平臺(tái)。
Docker的設(shè)計(jì)是將軟件的運(yùn)行環(huán)境,即操作系統(tǒng)OS(operating system),視為一個(gè)貨輪。每個(gè)在其基礎(chǔ)上的軟件或庫(kù)如同貨輪上的集裝箱。用戶可自行安裝軟件和配運(yùn)行環(huán)境,如同在貨輪上放置一個(gè)個(gè)集裝箱。最后,交付的成品包括軟件和運(yùn)行環(huán)境,就好像將整個(gè)貨輪及貨物一起交付。
使用Docker的過(guò)程中會(huì)遇到鏡像、容器和倉(cāng)庫(kù)這幾個(gè)概念,其中鏡像和容器的關(guān)系類似于面向?qū)ο缶幊讨械膶?duì)象與類。 鏡像是靜態(tài)的由上游開(kāi)發(fā)者提供的OS鏡像,包括已經(jīng)安裝的軟件或庫(kù)。容器是根據(jù)鏡像生成的,可以由用戶更改,比如更改安裝新軟件。但與面向?qū)ο缶幊滩煌氖?,由用戶更改后的容器可以生成新鏡像,供他人使用,而倉(cāng)庫(kù)則是這些鏡像的存放地。
一般的流程是:首先,由上游開(kāi)發(fā)者提供鏡像,并將其push到倉(cāng)庫(kù)中;然后用戶從倉(cāng)庫(kù)pull鏡像到本地并運(yùn)行;最后用戶可能會(huì)根據(jù)自己的需求安裝新軟件調(diào)試后運(yùn)行。
Docker可以在Windows或Linux上安裝,Windows上安裝Docker的過(guò)程極為簡(jiǎn)單,在此不贅述。
Linux的安裝較為復(fù)雜,下面以Linux的開(kāi)源免費(fèi)版centos 7為例安裝Docker,其中使用的是Docker CE (即社區(qū)免費(fèi)版)。
首先安裝一些必要的系統(tǒng)工具,命令為:
yum install -y yum-utils device-mapper-persistent-data lvm2
使用yum安裝軟件的過(guò)程中需要下載軟件包,如果發(fā)現(xiàn)下載的速度慢可以添加yum軟件源(命令為yum-config-manager --add-repo 一個(gè)yum源),然后更新 yum 緩存即可(命令為yum makecache fast)。
安裝 Docker命令為:yum -y install docker-ce
啟動(dòng)服務(wù)命令為:systemctl start docker
該教學(xué)平臺(tái)使用的是Jupyterhub開(kāi)源項(xiàng)目。該項(xiàng)目支持多用戶在瀏覽器中直接編寫Python代碼,Jupyterhub的依賴包括Python,Notejs,Jupyter等,如果從零開(kāi)始安裝,這些依賴都可以通過(guò)包管理器Anaconda(其命令為conda)安裝。但Jupyterhub開(kāi)源項(xiàng)目在Doucker倉(cāng)庫(kù)(DouckerHub)提供了一個(gè)鏡像(該鏡像是基于Ubuntu的)可以通過(guò)如下命令下載:
docker pull jupyterhub/jupyterhub
運(yùn)行該鏡像的命令如下:
docker run -t -i --name spark_ container -p 8000:8000 jupyterhub/jupyterhub /bin/bash
其中
run 是基于鏡像新建容器并運(yùn)行的意思。
-t選項(xiàng)是分配容器一個(gè)為總斷并綁定到當(dāng)前宿主機(jī)的標(biāo)準(zhǔn)輸入輸出上。
-i選項(xiàng)是保持容器的標(biāo)準(zhǔn)輸入輸出狀態(tài)為打開(kāi)。
--name spark_container 是新建容器名稱為spark_container。
-p 8000:8000 是映射端口,將宿主機(jī)器(centos)的8000端口和容器(Ubuntu)的8000端口映射。
jupyterhub/jupyterhub是要運(yùn)行的鏡像名稱。
/bin/bash是容器開(kāi)始運(yùn)行后要執(zhí)行的命令。
接下來(lái)會(huì)用包管理器Anaconda(其命令為conda)安裝軟件,過(guò)程中需要下載軟件包,如果發(fā)現(xiàn)下載的速度慢可以設(shè)置conda軟件源。設(shè)置conda的源(命令為conda config --add channels https://一個(gè)conda的url源)后要設(shè)置conda的url源狀態(tài)為yes(命令為conda config --set show_channel_urls yes)。
Jupyterhub依賴于jupyter 和notebook。更新jupyter和notebook的命令如下:
conda update jupyter
conda update notebook
某些Jupyterhub/Jupyterhub版本的鏡像可能沒(méi)有安裝jupyter 和notebook,這時(shí)需要通過(guò)下述命令安裝jupyter 和notebook:
conda install jupyter
conda install notebook
因?yàn)镴upyterhub使用了PAM(Pluggable authentication module)來(lái)管理用戶,所以需要用下屬命令和配置文件完成Jupyterhub的多用戶配置。
添加測(cè)試用戶命令如下:
adduser u1
adduser u2
輸入記住的用戶名和密碼,之后配置和登錄都需要。
用下屬命令可以生成Jupyterhub的配置文件jupyterhub_config.py:
jupyterhub--generate-config
生成配置文件jupyterhub_config.py后在文件里添加如下配置:
c.Authenticator.admin_users = {‘u1’}
c.Authenticator.whitelist = {′u2′ }
上述配置設(shè)置了u1為管理員,u2為普通用戶。
注意當(dāng)運(yùn)行jupyterhub -f jupyterhub_config.py命令時(shí),如果工作目錄中有名為jupyterhub_config.py的配置文件,則該命令會(huì)自動(dòng)讀取該配置文件,那么該命令可略寫為jupyterhub。因此,最好將該配置文件放到容器內(nèi)運(yùn)行的工作目錄中。
這樣做的主要原因是簡(jiǎn)化后面啟動(dòng)項(xiàng)目命令,否則在容器外很難用一條命令啟動(dòng)Jupyterhub。
啟動(dòng)后可以通過(guò)瀏覽器訪問(wèn),輸入管理員u1的用戶名和密碼后可以進(jìn)入Jupyterhub管理界面見(jiàn)圖2。
圖2 基于Docker的Spark云計(jì)算實(shí)驗(yàn)教學(xué)平臺(tái)的Jupyterhub管理界面
至此支持多用戶在瀏覽器中直接編寫Python代碼的Jupyterhub已經(jīng)配置完成,但如果在其中希望直接調(diào)用Spark還需要繼續(xù)安裝Spark及其依賴。
PySpark是一個(gè)Spark官方提供的庫(kù),該庫(kù)讓python 可以調(diào)用Spark。安裝命令如下:
conda install pyspark
上述命令可以將PySpark和Spark以及它們大多數(shù)依賴都會(huì)自動(dòng)安裝上,但jdk的不會(huì)自動(dòng)安裝。
因?yàn)镾park是運(yùn)行在JVM(Java Virtual Machine即Java虛擬機(jī))上,所以需要另外再安裝jdk。
但因?yàn)镴upyterhub 官網(wǎng)提供的Docker 鏡像是基于Ubuntu的,而該鏡像中沒(méi)有安裝jdk,所以需要另外安裝,安裝的命令如下:
apt-get install default-jdk
另外,為了加快下載軟件的速度,可以在安裝前添加apt軟件源到/etc/apt/sources.list中,然后更新apt緩存即可(更新的命令為:apt-get update)
需要說(shuō)明的是,目前Spark有如下幾種運(yùn)行模式:
Local模式,用于開(kāi)發(fā)調(diào)試Spark應(yīng)用程序。
Standalone模式,Spark自身進(jìn)行資源管理、任務(wù)調(diào)度和計(jì)算,采用Master/Slave結(jié)構(gòu)。
Mesos模式和Hadoop YARN模式,這兩個(gè)模式分別運(yùn)行在Mesos和Hadoop YARN資源管理框架基礎(chǔ)之上,將資源管理交給Mesos和Hadoop YARN,Spark只負(fù)責(zé)運(yùn)行任務(wù)調(diào)度和計(jì)算。
考慮到學(xué)生的接受程度和學(xué)校機(jī)器的負(fù)載能力,本平臺(tái)使用的是Local模式。
最后將spark_container保存成一個(gè)鏡像,命令如下:
docker commit spark_container spark_teaching_platform_img
該平臺(tái)的測(cè)試環(huán)境為centos7,平臺(tái)運(yùn)行使用如下命令:
docker run -it -p 8000:8000 spark_teaching_platform_img jupyterhub
啟動(dòng)后可以通過(guò)瀏覽器訪問(wèn)http://127.0.0.1:8000,進(jìn)入登錄界面,輸入用戶名和密碼后可以進(jìn)入編程界面(圖3)。
圖3 基于Docker的Spark云計(jì)算實(shí)驗(yàn)教學(xué)平臺(tái)的編程界面
實(shí)驗(yàn)課之前任課教師需要提前搭建好基于Docker的Spark云計(jì)算實(shí)驗(yàn)教學(xué)平臺(tái),在此平臺(tái)上學(xué)生就可以進(jìn)行Spark這門課程中的各個(gè)實(shí)驗(yàn)了。下面以“Spark數(shù)據(jù)讀取與查詢實(shí)驗(yàn)”這個(gè)內(nèi)容為例介紹一下整個(gè)實(shí)驗(yàn)。
實(shí)驗(yàn)題目:Spark數(shù)據(jù)讀取與查詢實(shí)驗(yàn)
實(shí)驗(yàn)?zāi)康模和ㄟ^(guò)Spark數(shù)據(jù)讀取與查詢實(shí)驗(yàn),使學(xué)生了解Spark數(shù)據(jù)讀取與查詢基本知識(shí),掌握 Spark的數(shù)據(jù)讀取與查詢方法。實(shí)驗(yàn)結(jié)合 Spark與SQL進(jìn)行編程,查詢數(shù)據(jù),培養(yǎng)和鍛煉學(xué)生編程能力,為進(jìn)一步的大數(shù)據(jù)分析學(xué)習(xí)做準(zhǔn)備。
實(shí)驗(yàn)環(huán)境:本實(shí)驗(yàn)所需要的實(shí)驗(yàn)環(huán)境為提前搭建好的Spark云計(jì)算實(shí)驗(yàn)教學(xué)平臺(tái),其中主要使用的軟件庫(kù)有Docker,Spark,PySpark。
實(shí)驗(yàn)教學(xué)內(nèi)容:(1)教師講解Spark 支持的文件格式,如最基本的 txt,csv,json等,介紹Spark 的讀取函數(shù)spark.read.csv() , spark.read.json(), spark.read.text()。(2)教師演示編程過(guò)程,使用Spark讀取文件得到DataFrame 對(duì)象,使用createOrReplaceTempView()函數(shù)創(chuàng)建臨時(shí)表 ,使用spark.sql()執(zhí)行查詢語(yǔ)句,使用show()顯示結(jié)果。
實(shí)驗(yàn)過(guò)程:(1)把參與實(shí)驗(yàn)的學(xué)生分為若干小組,每組 4~5 人。(2)要求每組學(xué)生下載實(shí)驗(yàn)數(shù)據(jù)和API文檔。(3)讓學(xué)生根據(jù)教師演示過(guò)程進(jìn)行基本的數(shù)據(jù)讀取與查詢實(shí)驗(yàn)。(4)讓學(xué)生結(jié)合學(xué)過(guò)的SQL語(yǔ)句,通過(guò)編程完成數(shù)據(jù)篩選。(5)讓學(xué)生總結(jié)實(shí)驗(yàn)的收獲以及應(yīng)當(dāng)改進(jìn)的地方。
實(shí)驗(yàn)效果:實(shí)驗(yàn)教學(xué)前教師先行搭建好基于Docker的Spark云計(jì)算實(shí)驗(yàn)教學(xué)平臺(tái),為學(xué)生完成實(shí)驗(yàn)做好了充分的準(zhǔn)備。學(xué)生完成上述實(shí)驗(yàn)項(xiàng)目后,對(duì)Spark數(shù)據(jù)讀取與查詢基本知識(shí)有了更加深入的了解,掌握了 Spark的數(shù)據(jù)讀取與查詢方法,鍛煉了學(xué)生的編程能力,為進(jìn)一步的大數(shù)據(jù)分析學(xué)習(xí)奠定了一定的基礎(chǔ)。
本次研究首先介紹了Spark云計(jì)算教學(xué)中遇到的問(wèn)題,其次介紹了如何通過(guò)Docker解決該問(wèn)題,并詳細(xì)介紹了通過(guò)Docker搭建Spark云計(jì)算實(shí)驗(yàn)教學(xué)平臺(tái)的方法,演示了該平臺(tái)的使用,最后在所搭建的基于Docker的Spark云計(jì)算實(shí)驗(yàn)教學(xué)平臺(tái)上順利進(jìn)行了“Spark數(shù)據(jù)讀取與查詢實(shí)驗(yàn)”的實(shí)驗(yàn)教學(xué)。
河北科技師范學(xué)院學(xué)報(bào)2020年4期