以下内容大约记于2015年6月,所以部分内容略有过时,但基本和最新的代码架构一致。
在看过上一篇文章
使用Zeppelin对Spark进行交互式数据查询和分析
之后,如果想对zeppelin的工作机制以及源代码结构有所了解,可以阅读本文。
总体来说,Zeppelin可以分为Web,Notebook以及Interpreter三个大部分。
Web
Web部分包含UI,REST API和Swagger三个子部分:
-
Web UI:即用户可见的网页,提供Note编辑以及图表显示功能,并且与后端的Notebook Server保持Websocket连接。
-
REST API:主要是
Notebook
以及
Interpreter
相关的REST API,Zeppelin现在的官网上已经有比较详细的描述,故不再赘述。
-
Swagger:是一个
RESTful API库
,有比较强的文档化能力,但是在最新版本的代码中已经被淘汰。
Notebook
Notebook部分有一些重要的概念是需要理解的:
-
Notebook Server:用于建立并维护前端网页与后端服务器之间的Websocket连接;它其实是一个job listener,接收并处理前端网页发来的Note执行请求,在后端生成并执行相应的job,并将job执行的状态信息广播到所有的前端页面。
-
Message:Message类是前端网页与后端Notebook Server之间的通信协议,传输在Websocket上,主要用于描述Note执行相关的信息,具体可见代码
Message.java
。
-
Notebook,Note,Paragraph,Job:
-
Notebook:Zeppelin认为整个运行实例是一个Notebook,其中可以用很多篇Note。
-
Note:每一篇Note就是一个具体的页面,其中可以有很多个Paragraph,就是代码段落。
-
Paragraph:每一个Paragraph就是一个代码段落,因此Paragraph是一个可执行单元,等同于一个Job。
-
Job:Job是Zeppelin后端调度和执行的单位,会在具体的Interpreter上运行。
Interpreter
InterpreterFactory主要有以下职能:
-
维护所有Interpreter的配置信息并存储在interpreter.json文件中。
-
管理所有的Interpreter:
-
InterpreterGroup:一个InterpreterGroup中包含多个Interpreter,同组内的Interperter共享相同的配置信息,例如Spark和SparkSQL interpreter在一个InterpreterGroup内。
-
InterpreterSetting:一个InterpreterGroup会有一个InterpreterSetting,其中包含着相应的配置信息,例如Spark Master。
-
所有的InterpreterSetting都被持久化在nterpreter.json文件里。
-
维护Note与InterpreterGroup直接的绑定关系,即每篇Note可以绑定不同的InterpreterGroup.
Interpreter
-
每一个Interpreter都有一个对应的Scheduler实例,Scheduler将Job的提交与执行变成了一个异步的过程,即Job在Scheduler处进入队列等待提交,用户可以定期收到Job执行相关的信息。Zeppelin内部有三种Scheduler:
-
FIFOScheduler: 适用于Paragraph只能顺序执行的Interpreter,如SparkInterpreter, ShellInterpreter等。
-
ParallelScheduler: 适用于Paragraph可并行执行的Interpreter,如SparkSqlInterpreter, MarkdownInterpreter等。
-
RemoteScheduler: 仅适用于RemoteInterpreter。
-
Local Interpreter和Remote Interpreter:
-
Local Interpreter:即ClassloaderInterpreter,运行在Zeppelin的主进程里。
-
Remote Interpreter:运行在一个单独的进程里,通过Thrift接口与Zeppelin主进程通信;其本质就是用一个新的进程来运行一个Local Interpreter(即ClassloaderInterpreter)。
-
InterpreterContext:用于存储Paragraph相关的信息,Interpreter在具体解析执行Paragraph时会用到InterpreterContext。
-
InterpreterResult:用于存储Job的状态信息以及执行结果,具体包括:
-
状态码:SUCCESS,INCOMPLETE,ERROR,KEEP_PREVIOUS_RESULT
-
类型:Text(Default),Table,Html,Angular等
-
内容:字符串数组
一次Query的执行过程
SparkInterpreter相关
SparkInterpreter的工作原理如下:
-
内部基于SparkILoop以及SparkIMain实现,功能类似于Spark-Shell,即逐行的解析代码。
-
用zeppelin-<Interpreter hash code>-<Paragraph Id>作为Spark中的Job Group Id,进而用Job Group Id来从SparkContext中获取执行进度信息。
-
将SparkInterpreter进程内创建的SparkContext绑定到SparkIMain里面,进而预定义一些环境配置以及语法糖,例如ZepplinContext。
-
用ByteArrayOutputStream来捕获SparkIMain的输出,并转化为可显示的输出结果。
SparkSqlInterpreter的工作原理如下:
-
运行在SparkInterpreter之上,即在SparkInterpreter中运行SqlContext或者HiveContest
-
SparkSqlInterpreter的执行结果都会以Table的类型返回给前端,因此前端页面会用相应的Angular JS代码将结果呈现为图表。
主要代码结构
从
github
上clone相应的代码,代码下载下来以后,可以着重看一下几个module:
-
zeppelin-display:定义了一些面向用户的显示相关的基础语法糖,例如可以在Note和Paragraph内实现一些自定义的交互式菜单对数据结果进行筛选过滤。
-
zeppelin-distribution:用于生成发布包。
-
zeppelin-interpreter:主要是Interpreter以及Scheduler的定义与实现。
-
zeppelin-server:定义了Zeppelin的主程序,包括Web Server,Notebook Server以及REST API的实现。
-
zeppelin-web:Zeppelin的前端页面,基于Angular JS的MVC架构。
-
zeppelin-zengine:Zeppelin engine,包含了InterpreterFactory,Notebook以及Notebook Search相关的定义。
|