共计 6923 个字符,预计需要花费 18 分钟才能阅读完成。
本文整顿自网易互娱资深开发工程师、Apache Kyuubi Committer 林小铂的《基于 Kyuubi 实现分布式 Flink SQL 网关》分享,内容次要分为以下四局部:
- Kyuubi 是什么
- Kyuubi 架构设计
- Flink x Kyuubi 劣势
- 将来瞻望
一. Kyuubi 是什么
1.1. Kyuubi 简介
简略来说,Kyuubi 是一个分布式、多租户的 SQL 网关。置信大家先会想到的问题是,Flink 曾经提供 SQL Gateway,为什么还须要 Kyuubi 呢?其实答案就是分布式和多租户两个关键词,两者相辅相成,Kyuubi 很多高级性能都是从分布式和多租户衍生而来的。
1.2. Kyuubi 的倒退历程
- 2018-2020 0.x 版本
Kyuubi 在 2018 年立项,最后目标次要为解决 Hive 用户迁徙到 Spark SQL (Spark Thrift Server) 的痛点,比方租户间隔离和服务稳定性的问题。2018-2020 年是 Kyuubi 的 0.x 版本阶段,这个期间次要定位为 Spark Thrift Server 的升级版,用户次要来自 Spark 社区。
- 2020-2021 1.x 版本
在 Kyuubi 倒退过程中,咱们逐步意识到 Kyuubi 解决的问题并不是 Spark 独有,而是不同引擎都会遇到的共性问题。于是 2021 年 Kyuubi 进行了架构降级,将通用解决方案形象成通用的 Kyuubi Server,而后对接不同引擎逻辑则成为 Kyuubi Engine。这是 Kyuubi 的 1.x 版本阶段,定位演变为通用的分布式多租户 SQL 网关。
- 2021 Apache 孵化
2021 年 9 月 Kyuubi 进入 Apache 孵化器,在 Flink 1.16 引入 SQL Gateway 后,Kyuubi Flink Engine 进行重构将底层改为基于 Flink SQL Gateway。
- 2023 Apache TLP
2023 年初 Kyuubi 从孵化器顺利毕业成为 Apache 顶级我的项目。
1.3. 支流计算引擎发展趋势
Kyuubi 的倒退历程和开源大数据的计算引擎发展趋势是密不可分的。
业界最早的开源计算引擎是 MapReduce,这时编程 API 是 Java 不反对 SQL,所以也没有 SQL 网关一说。
在 2014 年左右,随同着 SQL on Hadoop 潮流,Hive 代替 MapReduce 成为支流引擎。Hive 提供 Hive Server2 负责将 SQL 翻译成底层的 MapReduce,能够说是 SQL 网关的鼻祖。
后续 Spark 呈现,其内存计算性能比起 Hive 大大晋升,不少用户从 Hive 迁徙至 Spark。Spark 提供了 SparkSQL 编程 API,而后对应的 SQL 服务组件为 Spark Thrift Server。
在最近几年,Flink 在实时计算和流批一体上的劣势又吸引不少用户从 Spark 或者 Hive 迁徙过去。Flink 提供 FlinkSQL,对应的 SQL 服务组件为 Flink SQL Gateway。
在这几轮技术浪潮中,每个引擎有本人的 SQL 服务组件(咱们能够统称他们为 SQL Gateway),但它们的性能其实并没有齐全对齐,很多企业级的个性是缺失的,而 Kyuubi 的指标则是作为对立标准化的 SQL 网关来屏蔽掉这些差别。
1.4. SQL Gateway 比照
上图是不同 SQL 网关的要害个性比照。
1.4.1. 多租户
多租户包含认证和资源隔离两个要害规范。
- 在这方面,Hive Server 反对是最好的;
- 相对而言,Spark Thrift Server 因为自身会绑定一个 Spark 集群,而 Spark 集群是单用户的,所以仅能在 Driver 端做到 DDL 假装,而在集群端执行的 DQL 和 DML 其实都是以 Spark Thrift Server 自身的用户来执行的;
- Flink SQL Gateway 则是受限于 Flink 自身不反对多租户;
- 最初是 Kyuubi,Kyuubi 是 Server 和 Engine 拆散的架构,所以至多能在引擎粒度反对多租户
1.4.2. 程度拓展和高可用
程度拓展和高可用这两个个性通常和分布式的架构绑定,因而分布式架构的 Hive Server2 和 Kyuubi 都是反对的,而 Spark Thrift Server 和 Flink SQL Gateway 暂不反对。
1.4.3. 动静资源配置
- Hive Server 是能够在每条 SQL 的粒度上独自指定资源;
- Spark Thrift Server 会绑定一个 Application,所以资源是全局的,集群资源在 Spark Thrift Server 启动时就曾经确定;
- Flink SQL Gateway 没有和 Flink Cluster 强绑定,所以资源还是集群粒度的;
- Kyuubi 能够在引擎粒度去执行资源。
1.4.4. 多版本能力
SQL 网关能够承受一些低版本的 Client 的申请,但通常要求和集群的计算引擎的版本是保持一致的。这会导致降级集群版本的时候可能要开多个 SQL 网关的实例,Kyuubi 对这方面做了兼容解决。Kyuubi 的一个实例,是能够兼容多个版本的计算引擎。比方 Kyuubi 的最新版本 Flink Engine,它兼容 Flink 1.16 到 1.18 三个版本。
二. Kyuubi 的架构设计
2.1. Kyuubi 架构
Kyuubi 从部署架构上分为 Kyuubi Client、Kyuubi Server 和 Kyuubi Engine 三层:
- Kyuubi Client 次要是将用户 SQL 提交给 Kyuubi Server。Client 能够是和 Hive 兼容的 Beeline 或者反对 JDBC 或者 REST 的任意客户端。
- Kyuubi Server 负责 Session / Operation / Engine 的治理。Server 会接管 Client 连贯,并将申请通过 RPC 传递给 Engine 执行。
- Kyuubi Engine 承载理论计算。Engine 会针对不同的引擎有对应的实现,比方 Flink Engine、Spark Engine、Trino Engine。Engine 个别会运行在引擎的 master 节点,对于 Spark 来说就是 Spark Driver,对 Flink 来说就是 JobManager。
2.2. Kyuubi 会话路由
在 Kyuubi 架构中 Client 与 Server、Server 与 Engine 之间的通信均有基于 Zookeeper 的服务发现和负载平衡,这意味着不同模块之间是十分松耦合的。在同一个 Zookeeper namespace 下,Client 能够连到任意一个 Server 上,Server 也能拜访任意一个 Engine。
一个申请最终落到哪个 Engine 上由 Kyuubi Server 自动控制。Kyuubi Server 会依据多租户隔离策略的主动抉择一个适合的 Engine,如果满足要求的 Engine 不存在,那么 Kyuubi Server 会即时启动一个。绝对地,当一个 Engine 闲置一段时间后,Engine 会主动退出来节俭资源,当然也能够通过 Kyuubi Server 被动敞开 Engine。能够说 Kyuubi Engine 是按需启动的,而后生命周期也是由 Server 治理。
2.3. Kyuubi 引擎隔离级别
那么 Kyuubi Server 如何决定是否启动一个新的 Engine 呢?这很大水平上是由 Kyuubi 引擎隔离级别决定的。
Kyuubi 提供 4 种引擎隔离级别:
- CONNECTION 级别意味着每个连贯独占一个 Engine,这是最高的隔离级别,比拟适宜离线的大作业、Ad-hoc 查问或者实时作业的状况
- USER 级别意味着每个用户独占一个 Engine,适宜大部分场景
- GROUP 级别则是每个用户组共享一个 Engine,适宜小数据量的场景
- SERVER 级别则是全副用户共享全局的一个 Engine,这是最低的隔离级别,个别是管理员执行治理操作时应用
在引擎隔离级别之上,Kyuubi 还提供细粒度的路由设定,也就是 Subdomain。比方一个用户可能心愿用一个 Flink Engine 做实时计算,另外一个 Flink Engine 做 OLAP 查问。针对这种状况,Kyuubi 提供 subdomain 配置项。subdomain 容许在一个 namespace 再做划分。比方上述场景,用户能够别离在连贯时指定 kyuubi.engine.share.level.subdomain=realtime 或 kyuubi.engine.share.level.subdomain=olap,这样 Kyuubi Server 就会启动两个 Flink Engine。
2.4. Kyuubi Server 状态共享
大部分状况下 Kyuubi Server 是没有状态的,但也会有例外。例如当用户批量提交大量的 SQL 到 Kyuubi,Kyuubi Server 会将申请放入队列,但这个队列是在内存的,其余 Kyuubi Server 实例并不知道这批申请。如果用户前后两个申请被路由到不同的 Kyuubi Server,那么可能会产生状态不统一的问题。用户可能会说我刚刚提交了一批作业,为什么当初查不到。
为此,Kyuubi 针对不同场景进行了优化。首先取决于 Client 类型,如果是基于 JDBC,JDBC 是长连贯比较稳定,所以个别不会出问题。但如果是基于 REST,那么都是 HTTP 短链接,负载均衡器很可能把申请路由到不同实例上。
Kyuubi 的解决方案是引入了数据库来长久化 Server 的状态,包含申请的内容、Server ID 和 Client ID。如果其余 Kyuubi Server 接管到不属于本人的申请,能够通过 REST Fronted 将申请转发给正确的 Kyuubi 实例。
三. Flink x Kyuubi 劣势
3.1. 劣势一:分布式多租户
这是 Kyuubi 的一个规范劣势:程度拓展、多租户、高可用、多版本和动静资源配置。
值得一提的是,在以前主打实时计算的背景下,其实 Flink 对 SQL 网关的需要不是很高,通常咱们可能单实例的 SQL 网关就能解决问题。
然而随着 Flink 往流批一体和 OLAP 的方向倒退,咱们对 SQL 网关的需要越来越高,无论是连接数还是申请量都有可能翻一个数量级,甚至两个数量级。那么这时 Kyuubi 分布式的解决方案就会成为一个必需品。
3.2. 劣势二:优化 Application 模式
Kyuubi 的 Flink Application 模式其实和规范的 Application 模式是有肯定差异的。Flink 是提供了四种部署的模式,能够分成两类:
- Session 和 Standalone 模式。这类是单集群能够运行多作业,然而集群的生命周期须要手动管控,须要在申请之前启动一个集群,不必了再手动关掉。
- Application 和 PerJob 模式。这类是单集群只容许单作业,然而长处是集群的生命周期能够间接绑定作业的生命周期,作业完结集群就会退出,开释资源。
以上这两类的部署模式是互有优缺点的。而 Kyuubi 的 Application 模式联合了两者的长处。它容许单集群多作业,而集群的生命周期由 Kyuubi 管控,用户是不必去操心的。为理解这点,咱们上面先简略回顾一下 Flink SQL 的翻译流程。
3.2.1. Flink SQL 工作流程
从用户提交的 Flink SQL 到变成 Flink Runtime 能够去执行的作业,会有一个 SQL 翻译的过程。这个过程能够分成四步。
- 解析。用户提交的 SQL,会被 Parser 解析成逻辑执行打算。
- 优化。逻辑执行打算会被 Optimizer 优化,生成物理执行打算。
- 编译。物理执行打算会被 Planner 编译成 Java 代码。
- 部署。构建 JobGraph , 提交给 JobManager。
通常来说,这四步都会在一个 TableEnvironment 外面去实现。
3.2.2. Flink SQL Gateway PerJob 架构
在 PerJob 架构下 Flink SQL Gateway 会在外部开启 TableEnvironment,SQL 翻译的四步全副做完后,生成 JobGraph 提交给 JobManager。
这是很规范的一个应用制式,当然是没什么问题,当下 PerJob 的部署模式曾经过期了,咱们要迁徙到 Application 的模式下。
3.2.3. Flink SQL Gateway Application 架构
在规范的一个 Application 模式下,会要求用户的 main 函数在 JobManager 下来执行,那么这意味着 SQL 翻译至多最初一步的部署,会在 JobManager 下来实现。
针对这个问题,社区提出一个计划 FLIP-316,就是 Flink SQL Gateway 去反对 Application 的一个模式。在这个议案外面 Flink SQL Gateway 会在本地外部的 TableEnvironment 实现 SQL 翻译的前两步,也就是解析优化。生成两头的物理执行打算能够被序列化为 JsonPlan,而后与其余资源文件一起提交给 JobManager,JobManager 会启一个 main 函数去实现编译和部署这两步。通过这种形式 Flink SQL Gateway 就能够去反对 Application 模式。
然而这个计划有一个毛病,就是 JsonPlan 目前是只反对 DML,这意味着在一些 OLAP 场景,罕用的 Select 查问没有方法间接通过 Application 来反对。
3.2.4. Kyuubi Flink Application 架构
Kyuubi 的 Flink Application 架构模式是怎么解决这些问题的。
首先,Kyuubi 的 Flink Engine 是运行在 JobManager 外面的,它能够通过 RPC 的形式去接管到用户提交的 SQL,他在外部的 Table Environment,就能够像 Flink SQL Gateway 里的 PerJob 模式,一次性实现上述四步工作。
最初失去的作业,通过 JobManager 外部的 Dispatcher API 去提交。通过这种形式就能够绕开 Application 模式下 JobManager 要求每个集群只有一个作业的限度,也没有 JsonPlan 带来的问题。
对于 JobManager 来说,Kyuubi Flink Engine 相当于是始终在运行,没有退出的用户 main 函数。Flink Engine 什么时候退出,JobManager 就会 Shutdown 把资源给开释掉。
3.3. 劣势三:多引擎反对
这能够分成对立入口和引擎插件两个方面。
3.3.1. 对立入口
- 流批一体敌对,它能够作为一个多引擎的对立入口,这样不便不同引擎的相互之间迁徙。像从 Hive、Spark 迁徙到流批一体的 Flink,能够间接用 Kyuubi 来实现。如果是 Spark SQL 的用户,那很可能也是 Kyuubi 的用户,就只有新增一个 Flink Engine 就能够。
- Kyuubi 能够做混合负载的复用网关,反对多种计算引擎,不须要为每一种计算引擎保护 SQL Gateway。
- Kyuubi Server 能够作为对立平安认证的入口,它能够在认证结束当前把用户的凭证,比方 Kerberos TGT,通过 RPC 形式传递给 Engine,而后 Server 会负责定时 renew 凭证。
3.3.2. 引擎插件
另一方面,Kyuubi 提供灵便的插件机制反对满足平台治理需要,例如 SQL 血统提供、集成 Ranger 提供列级的访问控制或者监听事件。局部插件会依赖于引擎自身的反对,例如 Kyuubi Spark Engine 的血统提取是通过 Spark 提供的 QueryExecutionListener 接口实现,而 Flink 的血统反对也在 1.18 版本有了接口,后续 Kyuubi 这边也会跟进。
3.4. 劣势四:可观测性
Kyuubi 的 Metric 零碎是很欠缺的。
- Reporter 罕用的有 JMX、Prometheus 和打印到日志的 Log Reporter。
- Metric 纬度十分丰盛,包含 Connection、Operation、Server 的线程池、Engine 的状态、不同 RPC 申请的时长、频率等等。
同时,Kyuubi Server 提供内嵌的 Web UI,能够很直观的看到各项指标。
四. 将来瞻望
这是 Kyuubi 的 Flink Engine 的一些 Roadmap,其中很多工作依赖 Flink 自身裸露的能力,须要两个社区独特推动。
- 欠缺 on K8s 的 Flink Application 模式,这点其实和 Flink SQL Gateway 遇到的阻塞点是一样的,这点会依赖于 FLIP-316。
- 目前 Kyuubi 的 Application Mode 不足多作业的 JM HA 反对,这点咱们会推动社区去摸索解决方案。
- Flink 引擎插件的反对,咱们会不断完善 Flink Engine 的插件反对,包含审计、血统等插件。
- 最初是 SQL 粒度的资源管理,目前 Flink 细粒度资源只反对 DataStream API,而 Flink SQL 只能通过调整并行度来设置资源,咱们会摸索把它裸露到 SQL API 的形式。
Flink Forward Asia 2023
本届 Flink Forward Asia 更多精彩内容,可微信扫描图片二维码观看全副议题的视频回放及 FFA 2023 峰会材料!
更多内容
流动举荐
阿里云基于 Apache Flink 构建的企业级产品 - 实时计算 Flink 版现开启流动:
59 元试用 实时计算 Flink 版(3000CU* 小时,3 个月内)
理解流动详情:https://free.aliyun.com/?pipCode=sc