Zeppelin 的一个 notebook 中有很多 paragraph 都是 spark 解释器类型。zeppelin 定时运行时,他们会在一个 spark session 中,所以 Zeppelin 支持上面已运行的 paragraph 中定义的变量在下面即将运行的 paragraph 中可用。
但上图情况局限于第一个看板运行成功时变量 a 才会被定义,否则下方第二个看板无法得知变量 a。具体情况如下:
- 上面未运行:变量未定义
- 上面运行过第一遍但失败或抛异常:变量未定义
- 上面运行成功:变量正常
- 同一个 session 第一次成功第二次失败(如 spark session 未失效期间看板重试):变量为第一次运行时定义的值
如上图就是上方看板运行失败导致变量未定义,下方看板无法使用的情况。
现在有这么一个场景:整个 notebook 配置了定时运行,Zeppelin 会在预期时刻从上自下的顺序依次运行每一个 paragraph,如果其中一个 paragraph 失败,Zeppelin 仍会继续执行该 notebook 剩下 paragraph。这里希望最后一个看板内通过代码判断出上方所有看板是否都运行成功,把失败的 paragraph 发消息告警出来,那么想到可以通过“每个 paragraph 定义一个状态变量,最后一个 paragraph 去判断每个 paragraph 定义的变量来完成”。但这就有个问题了,如果上面 paragraph 失败了,状态变量会是未定义的状态,最后一个 paragraph 会报上图编译时异常,而不会运行成功。
SparkZeppelinContext 是 Apache Zeppelin 中的一个类,它扩展了 org.apache.spark.repl.SparkIMain,并提供了一些额外的功能,以便在 Zeppelin 环境中更好地与 Spark 进行交互。以下是 SparkZeppelinContext 的主要功能和用途:
主要功能
- 变量管理:
SparkZeppelinContext 提供了方法来管理和共享变量,使得在不同的段落(paragraph)之间可以方便地传递和使用变量。 - 解释器集成:
它与 Zeppelin 的 Spark 解释器紧密集成,提供了对 Spark 会话的更细粒度的控制。 - 日志和输出管理:
提供了方法来管理日志和输出,使得在 Zeppelin 中运行 Spark 代码时能够更好地控制输出内容。 - 动态类加载:
支持动态加载类,这对于在 Zeppelin 中进行交互式开发非常有用。
主要方法
以下是一些 SparkZeppelinContext 中常用的方法:
- put(name: String, v: Any):
将一个变量放入上下文中,使其在其他段落中可用。z.put("myVariable", "Hello, World!")
- get(name: String): Option[Any]:
从上下文中获取一个变量。val myVariable = z.get("myVariable")
- remove(name: String):
从上下文中移除一个变量z.remove("myVariable")
- clear():
清除上下文中的所有变量。z.clear()
- …
通过 SparkZeppelinContext,可以在 Zeppelin 中更灵活地管理和使用变量,从而提高开发效率和代码的可维护性。如下图所示可完成我这里的需求
同时变量依旧仅在该 notebook 的 sparkSession 中有效。
除了 SparkZeppelinContext 外,还可以使用 Spark 的广播变量,不过它通常是在多个段落中共享一个较大的数据结构时使用。大致使用姿势如下:
// 第一个段落 %spark import org.apache.spark.broadcast.Broadcast val data = Array(1, 2, 3, 4, 5) val broadcastVar: Broadcast[Array[Int]] = sc.broadcast(data) // 第二个段落 %spark val data = broadcastVar.value println(data.mkString(", "))
有兴趣的同学可再做研究。。。
发表评论