背景

Spark提供了两种方式来处理数据:
一是交互式处理,比如用户使用spark-shell或是pyspark脚本启动Spark应用程序,伴随应用程序启动的同时Spark会在当前终端启动REPL(Read–Eval–Print Loop)来接收用户的代码输入,并将其编译成Spark作业提交到集群上去执行。
二是批处理,批处理的程序逻辑由用户实现并编译打包成jar包,spark-submit脚本启动Spark应用程序来执行用户所编写的逻辑,与交互式处理不同的是批处理程序在执行过程中用户没有与Spark进行任何的交互。
两种处理交互方式虽然看起来完全不一样,但是都需要用户登录到Gateway节点上通过脚本启动Spark进程。这样的方式会有什么问题吗?
首先将资源的使用和故障发生的可能性集中到了这些Gateway节点。由于所有的Spark进程都是在Gateway节点上启动的,这势必会增加Gateway节点的资源使用负担和故障发生的可能性,同时Gateway节点的故障会带来单点问题,造成Spark程序的失败。
其次难以管理、审计以及与已有的权限管理工具的集成。由于Spark采用脚本的方式启动应用程序,因此相比于Web方式少了许多管理、审计的便利性,同时也难以与已有的工具结合,如Apache Knox。
同时也将Gateway节点上的部署细节以及配置不可避免地暴露给了登陆用户。
为了避免上述这些问题,同时提供原生Spark已有的处理交互方式,并且为Spark带来其所缺乏的企业级管理、部署和审计功能,本文将介绍一个新的基于Spark的REST服务:Livy。

Livy是一个基于Spark的开源REST服务,它能够通过REST的方式将代码片段或是序列化的二进制代码提交到Spark集群中去执行。它提供了以下这些基本功能:

  • 提交Scala、Python或是R代码片段到远端的Spark集群上执行;
  • 提交Java、Scala、Python所编写的Spark作业到远端的Spark集群上执行;
  • 提交批处理应用在集群中运行。

从Livy所提供的基本功能可以看到Livy涵盖了原生Spark所提供的两种处理交互方式。与原生Spark不同的是,所有操作都是通过REST的方式提交到Livy服务端上,再由Livy服务端发送到不同的Spark集群上去执行。

Livy基本架构

image.png
livy建立的每一个session会维护一个spark-context。
用户可以以REST请求的方式通过Livy启动一个新的Spark集群,Livy将每一个启动的Spark集群称之为一个会话(session),一个会话是由一个完整的Spark集群所构成的,并且通过RPC协议在Spark集群和Livy服务端之间进行通信。根据处理交互方式的不同,Livy将会话分成了两种类型:

  • 交互式会话(interactive session),这与Spark中的交互式处理相同,交互式会话在其启动后可以接收用户所提交的代码片段,在远端的Spark集群上编译并执行;
  • 批处理会话(batch session),用户可以通过Livy以批处理的方式启动Spark应用,这样的一个方式在Livy中称之为批处理会话,这与Spark中的批处理是相同的。

参考

【1】:https://www.jianshu.com/p/f5b12275d0e8