賀釋千,張海濤,王宇賓,李可強
(河北科技師范學院數學與信息科技學院,河北 秦皇島,066004)
Spark是UC Berkeley AMP lab開發的計算引擎[1],由Scala 語言編寫。處理大規模數據往往需要使用Spark,如大規模分布式機器學習[2],社交網絡分析及其相關算法[3,4]。該引擎的開發和測試均是在Linux上完成的。雖然可以勉強在Windows上運行,但使用中存在諸多問題,如軟件包依賴問題、防火墻問題、端口沖突等。所以,無論是商業應用還是科研工作大都是將Spark部署在Linux上運行。但是,目前大多數學校實驗室機器都使用Windows系統,這為實際教學帶來了困難。而使用Docker可以解決這一難題。Docker是一個開源的應用容器引擎[5,6,7],類似一個輕量級的虛擬機,但比虛擬機更輕。可以運行在Linux和Windows 10(Windows 7通過虛擬機運行)上。Docker支持將精心裁剪后的Linux及其軟件打包成為一個容器,然后將該容器的鏡像發布到網上(如DockerHub)供用戶下載。因為,該容器的鏡像在發布前已經將所有的運行環境、軟件及依賴都打包完成。所以,用戶下載該容器的鏡像后,可以像運行普通軟件一般,通過命令運行該容器。這極大簡化了軟件的部署。
雖然目前已經有一些文獻介紹了基于Docker的應用,如基于Docker的Hadoop平臺[8],但這不是針對實驗教學。為此,筆者基于Docker為Spark搭建所需的Linux實驗環境,并結合Jupyterhub,Anaconda等開源項目搭建該實驗平臺,以期解決計算機實驗面臨的一些實驗困難問題。
該平臺是B/S架構的。客戶端只需要一個瀏覽器訪問服務器即可。服務器上平臺主要部分的架構見圖1。

圖1 基于Docker的Spark云計算實驗教學平臺的架構
最下面是服務器操作系統,其上是Docker,再其上是容器的操作系統Ubuntu,最上面兩層就是容器里主要安裝的軟件和庫。其中的JVM是Java虛擬機,因為Spark的運行需要Java虛擬機。Anaconda是一個包管理器,負責安裝和管理Python,Jupyterhub,PySpark。
PySpark是Spark官方支持的Python調用接口(庫),Jupyterhub是一個支持多用戶在瀏覽器中直接編寫Python代碼的項目。采用這樣的平臺架構配置方案其原因有兩點:(1)雖然Spark官方支持Scala,Java,Python和R等4種語言的API調用。但目前官方對Scala,Python兩種語言的API支持的最好。(2)現在學校大多開設Python課程,學生對Python的接受程度更高。所以,接下來將搭建一個支持多用戶在瀏覽器中直接編寫Python代碼調用Spark的云計算實驗教學平臺。
Docker的設計是將軟件的運行環境,即操作系統OS(operating system),視為一個貨輪。每個在其基礎上的軟件或庫如同貨輪上的集裝箱。用戶可自行安裝軟件和配運行環境,如同在貨輪上放置一個個集裝箱。最后,交付的成品包括軟件和運行環境,就好像將整個貨輪及貨物一起交付。
使用Docker的過程中會遇到鏡像、容器和倉庫這幾個概念,其中鏡像和容器的關系類似于面向對象編程中的對象與類。 鏡像是靜態的由上游開發者提供的OS鏡像,包括已經安裝的軟件或庫。容器是根據鏡像生成的,可以由用戶更改,比如更改安裝新軟件。但與面向對象編程不同的是,由用戶更改后的容器可以生成新鏡像,供他人使用,而倉庫則是這些鏡像的存放地。
一般的流程是:首先,由上游開發者提供鏡像,并將其push到倉庫中;然后用戶從倉庫pull鏡像到本地并運行;最后用戶可能會根據自己的需求安裝新軟件調試后運行。
Docker可以在Windows或Linux上安裝,Windows上安裝Docker的過程極為簡單,在此不贅述。
Linux的安裝較為復雜,下面以Linux的開源免費版centos 7為例安裝Docker,其中使用的是Docker CE (即社區免費版)。
首先安裝一些必要的系統工具,命令為:
yum install -y yum-utils device-mapper-persistent-data lvm2
使用yum安裝軟件的過程中需要下載軟件包,如果發現下載的速度慢可以添加yum軟件源(命令為yum-config-manager --add-repo 一個yum源),然后更新 yum 緩存即可(命令為yum makecache fast)。
安裝 Docker命令為:yum -y install docker-ce
啟動服務命令為:systemctl start docker
該教學平臺使用的是Jupyterhub開源項目。該項目支持多用戶在瀏覽器中直接編寫Python代碼,Jupyterhub的依賴包括Python,Notejs,Jupyter等,如果從零開始安裝,這些依賴都可以通過包管理器Anaconda(其命令為conda)安裝。但Jupyterhub開源項目在Doucker倉庫(DouckerHub)提供了一個鏡像(該鏡像是基于Ubuntu的)可以通過如下命令下載:
docker pull jupyterhub/jupyterhub
運行該鏡像的命令如下:
docker run -t -i --name spark_ container -p 8000:8000 jupyterhub/jupyterhub /bin/bash
其中
run 是基于鏡像新建容器并運行的意思。
-t選項是分配容器一個為總斷并綁定到當前宿主機的標準輸入輸出上。
-i選項是保持容器的標準輸入輸出狀態為打開。
--name spark_container 是新建容器名稱為spark_container。
-p 8000:8000 是映射端口,將宿主機器(centos)的8000端口和容器(Ubuntu)的8000端口映射。
jupyterhub/jupyterhub是要運行的鏡像名稱。
/bin/bash是容器開始運行后要執行的命令。
接下來會用包管理器Anaconda(其命令為conda)安裝軟件,過程中需要下載軟件包,如果發現下載的速度慢可以設置conda軟件源。設置conda的源(命令為conda config --add channels https://一個conda的url源)后要設置conda的url源狀態為yes(命令為conda config --set show_channel_urls yes)。
Jupyterhub依賴于jupyter 和notebook。更新jupyter和notebook的命令如下:
conda update jupyter
conda update notebook
某些Jupyterhub/Jupyterhub版本的鏡像可能沒有安裝jupyter 和notebook,這時需要通過下述命令安裝jupyter 和notebook:
conda install jupyter
conda install notebook
因為Jupyterhub使用了PAM(Pluggable authentication module)來管理用戶,所以需要用下屬命令和配置文件完成Jupyterhub的多用戶配置。
添加測試用戶命令如下:
adduser u1
adduser u2
輸入記住的用戶名和密碼,之后配置和登錄都需要。
用下屬命令可以生成Jupyterhub的配置文件jupyterhub_config.py:
jupyterhub--generate-config
生成配置文件jupyterhub_config.py后在文件里添加如下配置:
c.Authenticator.admin_users = {‘u1’}
c.Authenticator.whitelist = {′u2′ }
上述配置設置了u1為管理員,u2為普通用戶。
注意當運行jupyterhub -f jupyterhub_config.py命令時,如果工作目錄中有名為jupyterhub_config.py的配置文件,則該命令會自動讀取該配置文件,那么該命令可略寫為jupyterhub。因此,最好將該配置文件放到容器內運行的工作目錄中。
這樣做的主要原因是簡化后面啟動項目命令,否則在容器外很難用一條命令啟動Jupyterhub。
啟動后可以通過瀏覽器訪問,輸入管理員u1的用戶名和密碼后可以進入Jupyterhub管理界面見圖2。

圖2 基于Docker的Spark云計算實驗教學平臺的Jupyterhub管理界面
至此支持多用戶在瀏覽器中直接編寫Python代碼的Jupyterhub已經配置完成,但如果在其中希望直接調用Spark還需要繼續安裝Spark及其依賴。
PySpark是一個Spark官方提供的庫,該庫讓python 可以調用Spark。安裝命令如下:
conda install pyspark
上述命令可以將PySpark和Spark以及它們大多數依賴都會自動安裝上,但jdk的不會自動安裝。
因為Spark是運行在JVM(Java Virtual Machine即Java虛擬機)上,所以需要另外再安裝jdk。
但因為Jupyterhub 官網提供的Docker 鏡像是基于Ubuntu的,而該鏡像中沒有安裝jdk,所以需要另外安裝,安裝的命令如下:
apt-get install default-jdk
另外,為了加快下載軟件的速度,可以在安裝前添加apt軟件源到/etc/apt/sources.list中,然后更新apt緩存即可(更新的命令為:apt-get update)
需要說明的是,目前Spark有如下幾種運行模式:
Local模式,用于開發調試Spark應用程序。
Standalone模式,Spark自身進行資源管理、任務調度和計算,采用Master/Slave結構。
Mesos模式和Hadoop YARN模式,這兩個模式分別運行在Mesos和Hadoop YARN資源管理框架基礎之上,將資源管理交給Mesos和Hadoop YARN,Spark只負責運行任務調度和計算。
考慮到學生的接受程度和學校機器的負載能力,本平臺使用的是Local模式。
最后將spark_container保存成一個鏡像,命令如下:
docker commit spark_container spark_teaching_platform_img
該平臺的測試環境為centos7,平臺運行使用如下命令:
docker run -it -p 8000:8000 spark_teaching_platform_img jupyterhub
啟動后可以通過瀏覽器訪問http://127.0.0.1:8000,進入登錄界面,輸入用戶名和密碼后可以進入編程界面(圖3)。

圖3 基于Docker的Spark云計算實驗教學平臺的編程界面
實驗課之前任課教師需要提前搭建好基于Docker的Spark云計算實驗教學平臺,在此平臺上學生就可以進行Spark這門課程中的各個實驗了。下面以“Spark數據讀取與查詢實驗”這個內容為例介紹一下整個實驗。
實驗題目:Spark數據讀取與查詢實驗
實驗目的:通過Spark數據讀取與查詢實驗,使學生了解Spark數據讀取與查詢基本知識,掌握 Spark的數據讀取與查詢方法。實驗結合 Spark與SQL進行編程,查詢數據,培養和鍛煉學生編程能力,為進一步的大數據分析學習做準備。
實驗環境:本實驗所需要的實驗環境為提前搭建好的Spark云計算實驗教學平臺,其中主要使用的軟件庫有Docker,Spark,PySpark。
實驗教學內容:(1)教師講解Spark 支持的文件格式,如最基本的 txt,csv,json等,介紹Spark 的讀取函數spark.read.csv() , spark.read.json(), spark.read.text()。(2)教師演示編程過程,使用Spark讀取文件得到DataFrame 對象,使用createOrReplaceTempView()函數創建臨時表 ,使用spark.sql()執行查詢語句,使用show()顯示結果。
實驗過程:(1)把參與實驗的學生分為若干小組,每組 4~5 人。(2)要求每組學生下載實驗數據和API文檔。(3)讓學生根據教師演示過程進行基本的數據讀取與查詢實驗。(4)讓學生結合學過的SQL語句,通過編程完成數據篩選。(5)讓學生總結實驗的收獲以及應當改進的地方。
實驗效果:實驗教學前教師先行搭建好基于Docker的Spark云計算實驗教學平臺,為學生完成實驗做好了充分的準備。學生完成上述實驗項目后,對Spark數據讀取與查詢基本知識有了更加深入的了解,掌握了 Spark的數據讀取與查詢方法,鍛煉了學生的編程能力,為進一步的大數據分析學習奠定了一定的基礎。
本次研究首先介紹了Spark云計算教學中遇到的問題,其次介紹了如何通過Docker解決該問題,并詳細介紹了通過Docker搭建Spark云計算實驗教學平臺的方法,演示了該平臺的使用,最后在所搭建的基于Docker的Spark云計算實驗教學平臺上順利進行了“Spark數據讀取與查詢實驗”的實驗教學。