以下內(nèi)容大約記于2015年6月,所以部分內(nèi)容略有過時,但基本和最新的代碼架構(gòu)一致。
在看過上一篇文章
使用Zeppelin對Spark進行交互式數(shù)據(jù)查詢和分析
之后,如果想對zeppelin的工作機制以及源代碼結(jié)構(gòu)有所了解,可以閱讀本文。
總體來說,Zeppelin可以分為Web,Notebook以及Interpreter三個大部分。
Web
Web部分包含UI,REST API和Swagger三個子部分:
-
Web UI:即用戶可見的網(wǎng)頁,提供Note編輯以及圖表顯示功能,并且與后端的Notebook Server保持Websocket連接。
-
REST API:主要是
Notebook
以及
Interpreter
相關(guān)的REST API,Zeppelin現(xiàn)在的官網(wǎng)上已經(jīng)有比較詳細的描述,故不再贅述。
-
Swagger:是一個
RESTful API庫
,有比較強的文檔化能力,但是在最新版本的代碼中已經(jīng)被淘汰。
Notebook
Notebook部分有一些重要的概念是需要理解的:
-
Notebook Server:用于建立并維護前端網(wǎng)頁與后端服務器之間的Websocket連接;它其實是一個job listener,接收并處理前端網(wǎng)頁發(fā)來的Note執(zhí)行請求,在后端生成并執(zhí)行相應的job,并將job執(zhí)行的狀態(tài)信息廣播到所有的前端頁面。
-
Message:Message類是前端網(wǎng)頁與后端Notebook Server之間的通信協(xié)議,傳輸在Websocket上,主要用于描述Note執(zhí)行相關(guān)的信息,具體可見代碼
Message.java
。
-
Notebook,Note,Paragraph,Job:
-
Notebook:Zeppelin認為整個運行實例是一個Notebook,其中可以用很多篇Note。
-
Note:每一篇Note就是一個具體的頁面,其中可以有很多個Paragraph,就是代碼段落。
-
Paragraph:每一個Paragraph就是一個代碼段落,因此Paragraph是一個可執(zhí)行單元,等同于一個Job。
-
Job:Job是Zeppelin后端調(diào)度和執(zhí)行的單位,會在具體的Interpreter上運行。
Interpreter
InterpreterFactory主要有以下職能:
-
維護所有Interpreter的配置信息并存儲在interpreter.json文件中。
-
管理所有的Interpreter:
-
InterpreterGroup:一個InterpreterGroup中包含多個Interpreter,同組內(nèi)的Interperter共享相同的配置信息,例如Spark和SparkSQL interpreter在一個InterpreterGroup內(nèi)。
-
InterpreterSetting:一個InterpreterGroup會有一個InterpreterSetting,其中包含著相應的配置信息,例如Spark Master。
-
所有的InterpreterSetting都被持久化在nterpreter.json文件里。
-
維護Note與InterpreterGroup直接的綁定關(guān)系,即每篇Note可以綁定不同的InterpreterGroup.
Interpreter
-
每一個Interpreter都有一個對應的Scheduler實例,Scheduler將Job的提交與執(zhí)行變成了一個異步的過程,即Job在Scheduler處進入隊列等待提交,用戶可以定期收到Job執(zhí)行相關(guān)的信息。Zeppelin內(nèi)部有三種Scheduler:
-
FIFOScheduler: 適用于Paragraph只能順序執(zhí)行的Interpreter,如SparkInterpreter, ShellInterpreter等。
-
ParallelScheduler: 適用于Paragraph可并行執(zhí)行的Interpreter,如SparkSqlInterpreter, MarkdownInterpreter等。
-
RemoteScheduler: 僅適用于RemoteInterpreter。
-
Local Interpreter和Remote Interpreter:
-
Local Interpreter:即ClassloaderInterpreter,運行在Zeppelin的主進程里。
-
Remote Interpreter:運行在一個單獨的進程里,通過Thrift接口與Zeppelin主進程通信;其本質(zhì)就是用一個新的進程來運行一個Local Interpreter(即ClassloaderInterpreter)。
-
InterpreterContext:用于存儲Paragraph相關(guān)的信息,Interpreter在具體解析執(zhí)行Paragraph時會用到InterpreterContext。
-
InterpreterResult:用于存儲Job的狀態(tài)信息以及執(zhí)行結(jié)果,具體包括:
-
狀態(tài)碼:SUCCESS,INCOMPLETE,ERROR,KEEP_PREVIOUS_RESULT
-
類型:Text(Default),Table,Html,Angular等
-
內(nèi)容:字符串數(shù)組
一次Query的執(zhí)行過程
SparkInterpreter相關(guān)
SparkInterpreter的工作原理如下:
-
內(nèi)部基于SparkILoop以及SparkIMain實現(xiàn),功能類似于Spark-Shell,即逐行的解析代碼。
-
用zeppelin-<Interpreter hash code>-<Paragraph Id>作為Spark中的Job Group Id,進而用Job Group Id來從SparkContext中獲取執(zhí)行進度信息。
-
將SparkInterpreter進程內(nèi)創(chuàng)建的SparkContext綁定到SparkIMain里面,進而預定義一些環(huán)境配置以及語法糖,例如ZepplinContext。
-
用ByteArrayOutputStream來捕獲SparkIMain的輸出,并轉(zhuǎn)化為可顯示的輸出結(jié)果。
SparkSqlInterpreter的工作原理如下:
-
運行在SparkInterpreter之上,即在SparkInterpreter中運行SqlContext或者HiveContest
-
SparkSqlInterpreter的執(zhí)行結(jié)果都會以Table的類型返回給前端,因此前端頁面會用相應的Angular JS代碼將結(jié)果呈現(xiàn)為圖表。
主要代碼結(jié)構(gòu)
從
github
上clone相應的代碼,代碼下載下來以后,可以著重看一下幾個module:
-
zeppelin-display:定義了一些面向用戶的顯示相關(guān)的基礎(chǔ)語法糖,例如可以在Note和Paragraph內(nèi)實現(xiàn)一些自定義的交互式菜單對數(shù)據(jù)結(jié)果進行篩選過濾。
-
zeppelin-distribution:用于生成發(fā)布包。
-
zeppelin-interpreter:主要是Interpreter以及Scheduler的定義與實現(xiàn)。
-
zeppelin-server:定義了Zeppelin的主程序,包括Web Server,Notebook Server以及REST API的實現(xiàn)。
-
zeppelin-web:Zeppelin的前端頁面,基于Angular JS的MVC架構(gòu)。
-
zeppelin-zengine:Zeppelin engine,包含了InterpreterFactory,Notebook以及Notebook Search相關(guān)的定義。
|