美文网首页大数据玩转大数据大数据,机器学习,人工智能
【Zeppelin 以练促学】如何编写一个 Zeppelin 解

【Zeppelin 以练促学】如何编写一个 Zeppelin 解

作者: 大数据学徒 | 来源:发表于2019-11-22 07:47 被阅读0次

文章首发于公众号【大数据学徒】,感兴趣请搜索 dashujuxuetu 或者文末扫码关注。

这是我想深入研究 Apache Zeppelin 所做的一个尝试,毕竟如果想要了解内在的原理,有必要先将它暴露出来的功能都摸透,自己写一个 Zeppelin 解释器对于理解其它的解释器也非常有帮助,其实 官方文档 中已经给出了具体的方法,本文就是我 follow 官方文档的一次实践(虽然步骤并不完全一样),如果你也对 Zeppelin 感兴趣,就赶快和我一起来写吧。


内容提要

  1. 环境说明
  2. 傻瓜解释器
  3. 编写代码
  4. 安装解释器
  5. 创建解释器
  6. 使用解释器
  7. 总结(包含可能遇到的问题)

代码已经上传至 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:

  1. 添加 org.apache.zeppelin:zeppelin-interpreter 依赖;
  2. 添加 maven 插件:maven-enforcer-plugin maven-dependency-plugin maven-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. 安装解释器

安装分为以下几步:

  1. 将傻瓜解释器的代码打成 jar 包;

  2. 切换到 Zeppelin 的安装目录下,创建 interpreter/dummy 子目录:

    mkdir interpreter/dummy
    
  3. 将第 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
    
  4. 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"
          }
        }
      }
    ]
    
  5. 编辑 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 步中我为傻瓜解释器指定了两个配置参数,分别是 properties1properties2,当然这两个参数毫无用处,但是我们注意到每个 property 都有一个 envNamepropertyName,看起来应该是提供了两种配置方式,一种是在页面配置,另一种是通过环境变量,这样之前给 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

可以看到在配置文件里的两个配置项 properties1properties2,点击蓝色的 Save 按钮。

6. 使用解释器

回到首页,创建一个新的 note,选择默认解释器为 dummy,如下图所示:

image

(激动人心的时刻来了!)

在打开的笔记本中随意输入字符,然后运行,运行截图:

image

和预期的效果完全一致。注意,因为 dummy 是默认解释器,所以加不加 %dummy 都可以。

7. 总结

这次实验算是达到了预期,中途遇到的问题有:

  1. getFormType() 方法如果返回 null,会报错;
  2. interpreter/dummy 下的 json 配置文件名字必须叫做 interpreter-setting.json,否则找不到配置;
  3. 创建的解释器的名称和 interpreter 目录下的子目录名称需要保持一致,在本文中都是 dummy ,否则会报 ClassNotFound 的错。

希望本文对你有用。

欢迎交流讨论,吐槽建议,分享收藏。

勤学似春起之苗,不见其增,日有所长
辍学如磨刀之石,不见其损,日有所亏
关注【大数据学徒】,用技术干货助你日有所长

大数据学徒

相关文章

网友评论

    本文标题:【Zeppelin 以练促学】如何编写一个 Zeppelin 解

    本文链接:https://www.haomeiwen.com/subject/daqfwctx.html