在使用 Spark 的过程中,Kylin 用户经常面临任务提交缓慢及构建节点不稳定的问题。为了解决这些问题,部分用户选择使用 Livy 作为与 Spark 交互的接口。Apache Kylin 3.0 版本引入了通过 Apache Livy 提交 Spark 任务的新功能,这得益于滴滴公司的靳国卫同学对该功能的贡献。
Apache Livy 是一个基于 Spark 的开源 REST 服务,它允许用户通过 REST 接口将代码片段或二进制代码提交到 Spark 集群执行。其主要功能包括: - 提交 Scala、Python 或 R 代码片段到远程 Spark 集群执行。 - 提交 Java、Scala、Python 编写的 Spark 作业到远程 Spark 集群执行。
Spark 目前支持两种交互方式:
- 交互式:用户通过 spark-shell
或 pyspark
脚本启动 Spark 应用程序,应用程序启动时,Spark 会在当前终端启动 REPL 接收用户的代码输入。
- 批处理:用户完成批处理程序逻辑并编译打包成 JAR 包,使用 spark-submit
脚本启动 Spark 应用程序,批处理程序在执行过程中不与 Spark 交互。
这两种方式都需要用户登录到网关节点并通过脚本启动 Spark 进程,但存在以下问题: - 增加网关节点的资源负担和故障风险。 - 网关节点的故障会导致单点问题,影响 Spark 程序运行。 - 难以管理和审计,且难以与现有的权限管理工具集成。 - 网关节点的部署细节和配置信息可能会被登录用户无意间暴露。
Livy 通过 REST 接口提供了一系列功能: - 实时提交代码片段与 Spark 的 REPL 进行交互。 - 提交 Scala、Java、Python 编写的二进制包以执行批处理任务。 - 支持多用户共享同一个服务器(支持用户模拟)。 - 可以在任何设备上通过 REST 接口提交任务、查看任务执行状态和结果。
Kylin 在 v2.0 版本中引入了 Spark,主要用于构建 Cube。以下是 Kylin 使用本地命令提交 Spark 任务的一部分代码示例:
java
@Override
protected ExecuteResult doWork(ExecutableContext context) throws ExecuteException {
// 获取 Spark job 的路径
String jobJar = config.getKylinJobJarPath();
// 构建本地命令
final String cmd = String.format(Locale.ROOT, stringBuilder.toString(), hadoopConf, KylinConfig.getSparkHome(), jars, jobJar, formatArgs());
// 创建命令执行线程
Callable<Pair<Integer, String>> callable = () -> {
Pair<Integer, String> result;
try {
result = exec.execute(cmd, patternedLogger);
} catch (Exception e) {
logger.error("error run spark job:", e);
result = new Pair<>(-1, e.getMessage());
}
return result;
};
// 提交命令执行线程
try {
Future<Pair<Integer, String>> future = executorService.submit(callable);
Pair<Integer, String> result = null;
while (!isDiscarded() && !isPaused()) {
if (future.isDone()) {
result = future.get();
break;
} else {
Thread.sleep(5000);
}
}
} catch (Exception e) {
logger.error("Error run spark job:", e);
return ExecuteResult.createError(e);
}
}
Kylin 通过 Livy 提交任务有两种方式:Session 和 Batch。Kylin 主要使用 Batch 方式,需要提前构建好 Spark 任务对应的 JAR 包并上传到 HDFS 中。配置项 kylin.engine.livy-conf.livy-key.file=hdfs:///path-to-kylin-job-jar
需要添加到 kylin.properties
文件中。
Kylin 通过 LivyRestBuilder
读取配置文件获取 Spark 任务的路径,然后通过 restClient
向 Livy 发送 HTTP 请求。在提交任务后,每隔 10 秒查询一次任务的执行状态,直到任务的状态变为 shutting_down
, error
, dead
, success
之一。
spark-submit
的地方为 Livy 的 Batch API。在启用 Livy 之前,确保 Livy 正常工作。在 Kylin.properties
文件中添加相关配置并重启 Kylin。选择使用 Spark 作为 Cube 构建引擎。
以下问题通常是因为使用不当或配置错误导致的,而非 Kylin 本身的问题,仅供参考:
Livy 本质上是一个基于 REST 的 Spark 服务,对于 Kylin Cube 的构建没有本质上的功能提升,但它使 Kylin 可以直接通过 Spark SQL 替代 Hive 构建扁平化表,并且管理 Spark 任务变得更加方便。不过,Livy 当前也存在一些问题,例如低版本或高版本的 Spark 可能无法正常工作,以及单点故障等问题。用户可以根据实际需求选择是否在 Kylin 中使用 Livy。