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