文章首发于公众号【大数据学徒】,感兴趣请搜索 dashujuxuetu 或者文末扫码关注。
这是我想深入研究 Apache Zeppelin 所做的一个尝试,毕竟如果想要了解内在的原理,有必要先将它暴露出来的功能都摸透,自己写一个 Zeppelin 解释器对于理解其它的解释器也非常有帮助,其实 官方文档 中已经给出了具体的方法,本文就是我 follow 官方文档的一次实践(虽然步骤并不完全一样),如果你也对 Zeppelin 感兴趣,就赶快和我一起来写吧。
内容提要:
- 环境说明
- 傻瓜解释器
- 编写代码
- 安装解释器
- 创建解释器
- 使用解释器
- 总结(包含可能遇到的问题)
代码已经上传至 github:https://github.com/iamabug/my-zeppelin-interpreter
1. 环境说明
操作系统:不限
JDK:1.8 以上
IDE:IntelliJ IDEA,并安装了 maven 插件
Zeppelin 版本:0.8.2,安装文档可以参考:如何安装启动Apache Zeppelin
2. 傻瓜解释器
因为我的目的只是了解相关的原理,所以只需要写一个“五脏俱全”的傻瓜解释器就行,所以我要写的解释器功能很简单,在用户的输入前加上调用次数和“hello”作为输出返回给用户,大概效果如下:
$ world
1. hello word
$ iamabug
2. hello iamabug
$ ...
3. 编写代码
在 IDEA 中新建一个 maven 项目,项目名为 my-zeppelin-interpreter,然后修改 pom.xml:
- 添加
org.apache.zeppelin:zeppelin-interpreter依赖; - 添加 maven 插件:
maven-enforcer-pluginmaven-dependency-pluginmaven-resources-plugin
截图如下:
然后新建一个 Class,名为 com.iamabug.DummyInterpreter,让它继承自 org.apache.zeppelin.interpreter.Interpreter,这时因为继承了一个抽象类,IDEA 会提示有错,使用快捷键 Alt + Enter 直接生成构造函数以及和需要重写的方法,共有 6 个方法:
// 初始化解释器
public void open();
// 关闭解释器,释放资源
public void close();
// 运行解释器并返回结果,s 是在 Zeppelin 里输入的代码,interpreterContext 是额外的运行上下文信息
public InterpreterResult interpret(String s, InterpreterContext interpreterContext);
// 取消运行,会中断 interpret 方法的执行
public void cancel();
// 动态表格的处理类型,关于动态表格可以参考:https://zeppelin.apache.org/docs/0.8.2/usage/dynamic_form/intro.html
public ForType getFormType();
// 获取运行进度,返回值为 0-100
public int getProgress();
我编写的解释器类 DummyInterpreter 如下所示:
public class DummyInterpreter extends Interpreter {
// 增加一个 int 成员变量,记录被调用的次数
private int count;
public DummyInterpreter(Properties properties) {
super(properties);
}
// 其实在构造方法里初始化 count 更合适
public void open() throws InterpreterException {
count = 0;
}
// close 方法不需要做什么
public void close(){}
// 对输入进行处理,其实就是拼接字符串
// 将结果封装成 InterpreterResult 类型
// 其中 InterpreterResult.Code 是枚举类型,表明解释器执行结果的状态
public InterpreterResult interpret(String s, InterpreterContext interpreterContext) {
count ++;
String res = count + ". " + "hello " + s;
return new InterpreterResult(InterpreterResult.Code.SUCCESS, res);
}
// 不考虑 cancel 的情况
public void cancel(InterpreterContext interpreterContext) {}
// 动态表格类型,返回 None 枚举类型即可
public FormType getFormType() {
return FormType.NONE;
}
// 执行进度永远是 100
public int getProgress(InterpreterContext interpreterContext) {
return 100;
}
}
4. 安装解释器
安装分为以下几步:
-
将傻瓜解释器的代码打成 jar 包;
-
切换到 Zeppelin 的安装目录下,创建
interpreter/dummy子目录:mkdir interpreter/dummy -
将第 1 步中的 jar 包拷贝到第 2 步创建的目录中:
# 这是在我机器上的路径,仅供参考 cp ~/workspace/Zeppelin/my-zeppelin-interpreter/target/my-zeppelin-interpreter-1.0-SNAPSHOT.jar ~/workspace/Zeppelin/zeppelin-0.8.2-bin-all/interpreter/dummy -
在
interpreter/dummy目录下创建解释器配置文件interpreter-setting.json,内容如下,group 和 name 都是dummy,className 是com.iamabug.DummyInterpreter:[ { "group": "dummy", "name": "dummy", "className": "com.iamabug.DummyInterpreter", "properties": { "properties1": { "envName": null, "propertyName": "properties1", "defaultValue": "old dummy", "description": "kidding", "type": "textarea" }, "properties2": { "envName": PROPERTIES2, "propertyName": null, "defaultValue": "little dummy", "description": "for fun", "type": "textarea" } } } ] -
编辑
conf/zeppelin-site.xml,给zepplin.interpreters增加com.iamabug.DummyInterpreter:<property> <name>zeppelin.interpreters</name> <value>com.iamabug.DummyInterpreter,org.apache.zeppelin.spark.SparkInterpreter,...</value> <description>Comma separated interpreter configurations. First interpreter become a default</description> </property>
在第 4 步中我为傻瓜解释器指定了两个配置参数,分别是
properties1和properties2,当然这两个参数毫无用处,但是我们注意到每个 property 都有一个envName和propertyName,看起来应该是提供了两种配置方式,一种是在页面配置,另一种是通过环境变量,这样之前给 Spark 解释器配置参数有两种方式也就解释的通了,可以查看interpreter/spark/interpreter-setting.json进行验证。
5. 创建解释器
为什么其它的解释器比如 Spark 不需要在页面上创建?我推测内置的解释器在启动时会通过代码创建,额外加的解释器做不到,所以只好在页面上手动创建了。
使用 bin/zeppelin-daemon.sh restart重启 Zeppelin,然后打开浏览器,点击右上角的 anonymous 菜单,选择 Interpreter 子菜单,然后在新页面中点击右上角的 Create 按钮,出现如下页面:
image
在 Interpreter Name 中输入 dummy,点击 Interpreter group 下拉菜单,选择 dummy,如下图所示:
image
可以看到在配置文件里的两个配置项 properties1 和 properties2,点击蓝色的 Save 按钮。
6. 使用解释器
回到首页,创建一个新的 note,选择默认解释器为 dummy,如下图所示:
image
(激动人心的时刻来了!)
在打开的笔记本中随意输入字符,然后运行,运行截图:
image
和预期的效果完全一致。注意,因为 dummy 是默认解释器,所以加不加 %dummy 都可以。
7. 总结
这次实验算是达到了预期,中途遇到的问题有:
-
getFormType()方法如果返回null,会报错; -
interpreter/dummy下的 json 配置文件名字必须叫做interpreter-setting.json,否则找不到配置; - 创建的解释器的名称和
interpreter目录下的子目录名称需要保持一致,在本文中都是dummy,否则会报ClassNotFound的错。
希望本文对你有用。
欢迎交流讨论,吐槽建议,分享收藏。
勤学似春起之苗,不见其增,日有所长
辍学如磨刀之石,不见其损,日有所亏
关注【大数据学徒】,用技术干货助你日有所长
大数据学徒










网友评论