首先,我們來了解一下這款工具的背景及用途。Zeppelin 目前已托管于 Apache 基金會,但并未列為頂級項目,可以在其公布的 官網訪問。它提供了一個非常友好的 WebUI 界面,操作相關指令。它可以用于做數據分析和可視化。其后面可以接入不同的數據處理引擎。包括 Flink,Spark,Hive 等。支持原生的 Scala,Shell,Markdown 等。
對于 Zeppelin 而言,并不依賴 Hadoop 集群環境,我們可以部署到單獨的節點上進行使用。首先我們使用以下地址獲取安裝包:
http://zeppelin.apache.org/download.html
這里,有2種選擇,
其一,可以下載原文件,自行編譯安裝。
其二,直接下載二進制文件進行安裝。這里,為了方便,筆者直接使用二進制文件進行安裝使用。
這里有些參數需要進行配置,為了保證系統正常啟動,
確保的 zeppelin.server.port 屬性的端口不被占用,默認是8080,其他屬性大家可按需配置即可。
在完成上述步驟后,啟動對應的進程。定位到 Zeppelin 安裝目錄的bin文件夾下,使用以下命令啟動進程:
./zeppelin-daemon.sh start若需要停止,可以使用以下命令停止進程:
./zeppelin-daemon.sh stop另外,通過閱讀 zeppelin-daemon.sh 腳本的內容,可以發現,我們還可以使用相關重啟,查看狀態等命令。內容如下:
case "${1}" in start) start ;; stop) stop ;; reload) stop start ;; restart) stop start ;; status) find_zeppelin_PRocess ;; *) echo ${USAGE}
在啟動相關進程后,可以使用以下地址在瀏覽器中訪問:
http://<Your_<ip/Host>:Port>啟動之后的界面如下所示:
該界面羅列出插件綁定項。如圖中的 spark,md,sh 等。那我如何使用這些來完成一些工作。在使用一些數據引擎時,如 Flink,Spark,Hive 等,是需要配置對應的連接信息的。在 Interpreter 欄處進行配置。這里給大家列舉一些配置示例:
3.1 Flink
可以找到 Flink 的配置項,如下圖所示:
然后指定對應的 IP 和地址即可。
3.2 Hive
這里 Hive 配置需要指向其 Thrift 服務地址,如下圖所示:
另外,其他的插件,如 Spark,Kylin,phoenix等配置類似,配置完成后,記得點擊 “restart” 按鈕。
3.3 Use md and sh
下面,我們可以創建一個 Notebook 來使用,我們拿最簡單的 Shell 和 Markdown 來演示,如下圖所示:
3.4 SQL
當然,我們的目的并不是僅僅使用 Shell 和 Markdown,我們需要能夠使用 SQL 來獲取我們想要的結果。
3.4.1 Spark SQL
下面,我們使用 Spark SQL 去獲取想要的結果。如下圖所示:
這里,可以將結果以不同的形式來可視化,量化,趨勢,一目了然。
3.4.2 Hive SQL
另外,可以使用動態格式來查詢分區數據,以"${partition_col=20160101,20160102|20160103|20160104|20160105|20160106}"的格式進行表示。如下圖所示:
3.5 Video Guide
另外,官方也給出了一個快速指導的入門視頻,觀看地址:[入口]
4.總結
在使用的過程當中,有些地方需要注意,必須在編寫 Hive SQL 時,%hql 需要替換為 %hive.sql 的格式;另外,在運行 Scala 代碼時,如果出現以下異常,如下圖所示:
解決方案,在 zeppelin-env.sh 文件中添加以下內容:
export ZEPPELIN_MEM=-Xmx4g該 BUG 在 0.5.6 版本得到修復,參考碼:[ZEPPELIN-305]
編譯和啟動完Zeppelin相關的進程之后,我們就可以來使用Zeppelin了。我們進入到頁面,我們可以在頁面上直接操作Zeppelin,依次選擇Notebook->Create new note,然后會彈出一個對話框,我們在Note Name里面隨便輸入一個名字,這里我輸入blog,然后點擊Create Note就可以創建一個新的Notebook了。我們可以在新建的Notebook里面輸入相關的代碼進行測試:
[python] view plain copy
sc.version
sqlc
res26: String = 1.5.2
res27: org.apache.spark.sql.SQLContext = org.apache.spark.sql.SQLContext@48806d6c
和Spark%20Shell一樣,Zeppelin會初始化好SparkContext和SQLContext對象,分別命名為sc和sqlc,我們可以直接在里面使用到它。接下來我們來在Zeppelin里面加載HDFS上面的數據,如下:
[python] view%20plain copy
sc.textFile("hdfs://ip/tmp/json").count
res29: Long = 200
Took 0 seconds (outdated)
我們再來使用sqlc對象讀取上面的json文件來創建一個DataFrame:
[python] view plain copy
val profilesJsonRdd =sqlc.jsonFile("hdfs://www.iteblog.com/tmp/json")
val profileDF=profilesJsonRdd.toDF()
val iteblog = profileDF.selectExpr("_id", "address", "age", "email")
iteblog.show()
profileDF.registerTempTable("profiles")
profilesJsonRdd: org.apache.spark.sql.DataFrame = [_id: string, about: string, address: string, age: bigint, company: string, email: string, eyeColor: string, favoriteFruit: string, gender: string, name: string, phone: string, registered: string, tags: array<string>]
profileDF: org.apache.spark.sql.DataFrame = [_id: string, about: string, address: string, age: bigint, company: string, email: string, eyeColor: string, favoriteFruit: string, gender: string, name: string, phone: string, registered: string, tags: array<string>]
root
|-- _id: string (nullable = true)
|-- about: string (nullable = true)
|-- address: string (nullable = true)
|-- age: long (nullable = true)
|-- company: string (nullable = true)
|-- email: string (nullable = true)
|-- eyeColor: string (nullable = true)
|-- favoriteFruit: string (nullable = true)
|-- gender: string (nullable = true)
|-- name: string (nullable = true)
|-- phone: string (nullable = true)
|-- registered: string (nullable = true)
|-- tags: array (nullable = true)
| |-- element: string (containsNull = true)
iteblog: org.apache.spark.sql.DataFrame = [_id: string, address: string, age: bigint, email: string]
+--------------------+--------------------+---+--------------------+
| _id| address|age| email|
+--------------------+--------------------+---+--------------------+
|55578ccb0cc5b350d...|694 Oriental Cour...| 30|tracynguyen@endip...|
|55578ccb6975c4e2a...|267 Amber Street,...| 23|leannagarrett@war...|
|55578ccb33399a615...|243 Bridgewater S...| 24|blairwhite@imperi...|
|55578ccb0f1d5ab09...|647 Loring Avenue...| 24|andrearay@beadzza...|
|55578ccb591a45d4e...|721 Bijou Avenue,...| 27|penningtongilbert...|
|55578ccb9f0cd20c4...|694 Llama Court, ...| 21|shelleyburns@pyra...|
|55578ccb8d0accc28...|498 Perry Terrace...| 40|nicolefigueroa@ed...|
|55578ccbd682cca21...|243 Stillwell Ave...| 32|galealvarado@sing...|
|55578ccb0d9025ddd...|649 Beard Street,...| 36|melindaparker@fur...|
|55578ccb5be70de0d...|972 Marconi Place...| 36|byerscarson@digia...|
|55578ccbc5a1050a5...|483 Hanson Place,...| 31|kristiemckinney@a...|
|55578ccb07fa02369...|540 Woodpoint Roa...| 40|salazarburks@micr...|
|55578ccb809e55bf0...|442 Ainslie Stree...| 32|hopkinspatterson@...|
|55578ccb204ff8ee6...|444 Argyle Road, ...| 23|maysrosario@imkan...|
|55578ccb4b062fc61...|571 Sunnyside Ave...| 38|atkinshancock@hel...|
|55578ccba5ff361a9...|385 Meeker Avenue...| 40|edwinarobertson@s...|
|55578ccb386940ac3...|936 Cheever Place...| 37|elsienoel@fleetmi...|
|55578ccbfc41ff7fe...|406 Lake Place, M...| 36|mirandamarsh@even...|
|55578ccbfa6b6c300...|364 Metropolitan ...| 31|sharronmcconnell@...|
|55578ccbdd6650d81...|113 Applegate Cou...| 29|mcdowellwelch@eur...|
+--------------------+--------------------+---+--------------------+
only showing top 20 rows
Took 1 seconds
需要注意的是,因為Zeppelin會自動地初始化好SparkContext和SQLContext,所以我們不能再顯示地創建SparkContext和SQLContext。如果你顯示地創建了SQLContext,而且使用它來注冊一張臨時表,當你下一次使用這個臨時表的時候將會出現以下的異常信息:
[python] view%20plain copy
no such table List ([blog])
下面我們來使用上面注冊的臨時表,Zeppelin自帶了SQL%20Interpreter,所以我們可以直接在上面編寫SQL語句:
[python] view%20plain copy
%sql select eyeColor, count(eyeColor) as count from profiles where
gender='male' group by eyeColor
運行上面的SQL我們就可以得到圖形化顯示的結果,而且我們可以根據自己的需要選擇餅型、條型、表格,線型等方式展現我們需要的結果!上面的SQL已經我們已經將查詢的gender寫死成male了,其實我們可以將這個值設置成參數的形式,然后我們可以在頁面上輸入相關的查詢參數:
[python] view plain copy
%sql select eyeColor, count(eyeColor) as count from profiles where
gender='male' group by eyeColor
然后我們運行這個sql,我們可以看到下圖的運行結果:
可以看出這里出現了一個文本框gender,我們可以輸入需要查詢的條件比如:male,然后再運行就可以得到上面sql一樣的結果。大家可能看到了,文本框里面是沒有輸入限制的,我們可以隨便輸入數據,而且你也不清楚到底有幾種值可以輸入。值得高興的是,我們可以將這個值設置成只固定可選的:
[python] view plain copy
%sql select eyeColor, count(eyeColor) as count from profiles where gender
="${gender=male,male|female}" group by eyeColor
這里限制了gender的值只能選擇male和female,而且默認male是選中的,如下:
有時候我們需要在SQL中使用自定義的函數,我們可以直接在Zeppelin中定義函數,然后在SQL使用它,如下:
[python] view plain copy
def ageGroup(age: Long) = {
val buckets = Array("0-10", "11-20", "20-30", "31-40",
"41-50", "51-60", "61-70", "71-80", "81-90", "91-100", ">100")
buckets(math.min((age.toInt - 1) / 10, buckets.length - 1))
}
ageGroup: (age: Long)String
為了能夠在Spark%20SQL中使用這個函數,我們必須先注冊這個函數:
[python] view%20plain copy
sqlc.udf.register("ageGroup", (age:Long)=>ageGroup(age.toInt))
res44: org.apache.spark.sql.UserDefinedFunction = UserDefinedFunction(<function1>,StringType,List())
然后我們就可以在Spark%20SQL中使用這個自定義函數:
[python] view%20plain copy
%sql select ageGroup(age) as iteblogAgeGroup,
count(1) as total
from profiles
where gender='${gender=male,male|female}' group by ageGroup(age)
order by iteblogAgeGroup
運行的結果如下:
2、 安裝
版本: Zeppelin 0.6.0 + 自建Spark集群(1.6.1)
感覺Zeppelin還是不太成熟,并開箱就用,還需要不少人工調整才能正常工作
解壓之后,首先需要從模板創建一個新的zeppelin-env.sh, 并設置SPARK_HOME. 比如:
exportSPARK_HOME=/usr/lib/sparkexport SPARK_MASTER_IP=127.0.0.1export SPARK_LOCAL_IP=127.0.0.1export ZEPPELIN_MEM="-Xms1024m -Xmx16384m -XX:MaxPermSize=16384m"如果是基于Hadoop 或者 Mesos 搭建的Spark 集群,還需要進行另外的設置。
從模板創建一個新的zeppelin-site.xml,并將之前的8080端口改到比如8089,避免與Tomcat等端口沖突
<property>
<name>zeppelin.server.port</name>
<value> 8089 </value>
<description>Server port.</description>
</property>
替換jackson相關類庫
jackson-annotations-2.4.4.jar
jackson-core-2.4.4.jar
jackson-databind-2.4.4.jar
默認自帶的是2.5.*, 但是實際使用的時候指定的是2.4.4
并且可能2.4.4 與 2.5.* 并不完全兼容。
因此需要使用2.4.4 替換2.5.* , 有下面3個jar需要替換:
這真的是非常坑人的一個地方。。。
做完上訴幾步之后,就可以啟動啦:
啟動/停止命令: bin/zeppelin-daemon.sh stop/start
啟動之后,打開http://localhost:8089 就可以看到Zeppelin的主界面啦
3. 配置Spark解釋器
Spark Interpreter的配置非常簡單,可以直接參考下圖的配置方式:
4. 幾點使用經驗
Zeppline自帶比較詳細的Tutorial, 各位看自帶的notebook tutorial 可能效果更好。 但是我在第一次使用的時候,遇到了不少坑,在此記錄下來,給大家做個參考:
(1) 任務提交之后不會自動停止
當Zeppelin 提交任務之后,可以看到Spark Master UI 上面,當前任務即使執行完成了,也不會自動退掉
這是因為,Zeppelin 默認就像人手工運行了spark-shell spark://master-ip:7077 一樣, 除非手動關閉shell命令,否則會一直占用著資源
解決辦法就是將spark 解釋器(interpreter) 重啟
手動的重啟辦法:
打開Interpreter界面,搜索到Spark部分并點擊重啟
推薦: 調用Restful API 進行重啟。
可以通過Chrome的Network 監控看一下點擊restart之后具體調用的API的情況。如下圖:
這個ID(2BUDQXH2R)在各自的環境可能各不相同。另外這個API是PUT的方式,可以直接使用下面的python代碼在UI上自動重啟
%python importrequests r = requests.put("http://IP:8089/api/interpreter/setting/restart/2BUDQXH2R") print r.text(2) 異常提示:Cannot call methods on a stopped SparkContext
比如我們在Spark Master UI 上面將當前job kill 之后,在Zeppelin這邊重啟執行任務就會遇到這個異常信息。
解決辦法很簡單: 重啟解析器
(3) 不要主動調用 sc.stop()
這是官方明確說明的:scala 的spark-shell 自動初始化了SparkContext / SqlContext 等等
不能自己調用sc.stop() 之后重啟創建一個SparkContext
可能筆者水平原因,嘗試自己創建新的sc 之后,各種奇奇怪怪的問題
(4) 關于python module
Python Interpreter可以使用當前Zeppelin所在機器的python 所有的model
同時支持python 2 與 python 3
這是一個很有用的功能,比如我使用spark將數據計算完成之后,生成了一個并不太大的csv文件。這個時候完全可以使用Pandas強大的處理能力來進行二次處理,并最終使用Zeppelin的自動繪圖能力生成報表
與Tableau之類的BI工具相比功能差了一些,不過各有所長。Zeppelin 對程序員來說可以算是非常方便的一個工具了。 對日常的一些簡單報表的工作量大大減小了
(5) 可以設置自動運行時間
在整個Note的最上端,可以設置當前notebook 定期執行。 而且注意: 還可以設置執行完成之后自動重啟interpreter 參考下圖:
X. 使用Zeppelin Hub 實現協作共贏
官方網址: http://help.zeppelinhub.com/
新聞熱點
疑難解答