Flink SQL Gateway简介
Flink SQL Gateway 是 Apache Flink 生态系统中的一个组件,主要用于提供统一的 SQL 查询接口,使得用户可以通过标准的 SQL 语句与 Flink 集群进行交互。它的核心目标是简化 Flink 的使用,特别是对于不熟悉 Flink API 但熟悉 SQL 的用户来说,提供了一种更便捷的方式来执行流处理和批处理任务。
以下是 Flink SQL Gateway 的主要功能和应用场景:
主要功能
-
SQL 查询接口:提供标准的 SQL 接口,用户可以通过 SQL 语句直接查询 Flink 中的数据流或批处理数据。
-
多租户支持:支持多个用户或应用程序同时提交 SQL 查询,并隔离各自的执行环境。
-
会话管理:支持会话管理,用户可以在一个会话中执行多个 SQL 查询,并保持上下文状态。
-
结果返回:将 SQL 查询的结果以标准格式(如 JSON、CSV)返回给客户端。
-
兼容性:兼容 Flink 的 Table API 和 SQL 功能,支持流处理和批处理任务。
应用场景
-
数据分析:数据分析师或业务人员可以通过 SQL 直接查询 Flink 中的实时数据流或历史数据,无需编写复杂的 Flink 程序。
-
数据探索:用户可以通过 SQL Gateway 快速探索数据,验证数据质量或执行临时查询。
-
系统集成:其他系统(如 BI 工具、报表系统)可以通过 Flink SQL Gateway 与 Flink 集成,直接获取实时或批处理结果。
-
多租户环境:在企业或云环境中,多个团队或用户可以共享同一个 Flink 集群,通过 SQL Gateway 提交各自的查询任务。
工作原理
Flink SQL Gateway 的核心工作原理如下:
-
接收 SQL 请求:通过 REST API 或其他接口接收客户端提交的 SQL 查询。
-
解析与优化:将 SQL 语句解析为 Flink 的逻辑计划,并进行优化。
-
提交任务:将优化后的任务提交到 Flink 集群执行。
-
返回结果:将执行结果返回给客户端。
Flink SQL Gateway的架构如下图,它由插件化的Endpoints和SqlGatewayService两部分组成。SqlGatewayService是可复用的处理客户端请求的服务。Endpoint是对外暴露的用户可以连接的接口。
4. 使用示例
以下是一个简单的 Flink SQL Gateway 使用示例:
启动 Flink SQL Gateway
./bin/sql-gateway.sh start
提交 SQL 查询
通过 REST API 提交 SQL 查询:
curl -X POST http://localhost:8083/v1/sql/query \
-H "Content-Type: application/json" \
-d '{
"query": "SELECT * FROM my_table"
}'
获取查询结果
查询结果会以 JSON 格式返回:
{
"results": [
{"column1": "value1", "column2": "value2"},
{"column1": "value3", "column2": "value4"}
]
}
优势:
-
易用性:用户无需学习 Flink 的编程 API,只需熟悉 SQL 即可使用。
-
灵活性:支持流处理和批处理任务,适用于多种场景。
-
集成性:可以与其他系统(如 BI 工具、数据可视化工具)无缝集成。
如果想了解flink sql gateway连接hiveserver2,参考:
Flink SQL Gateway的使用 - 知乎 (zhihu.com)
本质上就是把hive变成flink的一个catalog,就像doris外部表集成mysql一样,mysql就是doris的一个catalog,可以直接用doris语句操作mysql了。这里也一样,hive变成了flinksql的一个catalog。
怎么连接hive并直接可以用hive的代码(虽然这个需求我们是执行flink来跑hive数据),用hiveserver2最高效,下面有hiveserver2的介绍。
疑问1. 那为什么不直接使用 Flink SQL 而使用 flinksql Gateway 呢?
1. Flink SQL 的局限性
Flink SQL 是 Flink 提供的一种编程接口,用户可以通过 SQL 语句来定义流处理或批处理任务。然而,Flink SQL 的使用通常需要以下条件:
-
编程环境:用户需要在 Flink 程序中嵌入 SQL,或者通过 Flink 的 SQL Client 提交 SQL。
-
集群访问权限:用户需要直接访问 Flink 集群,并了解如何提交任务。
-
会话管理:Flink SQL 本身缺乏多会话管理能力,难以支持多用户并发查询。
这些问题使得 Flink SQL 在某些场景下(如多租户环境、临时查询、系统集成)不够灵活。
2. Flink SQL Gateway 的优势
Flink SQL Gateway 是为了弥补 Flink SQL 的上述局限性而设计的,它的核心优势包括:
(1) 提供统一的 SQL 服务
-
标准化接口:通过 REST API 或其他标准协议(如 JDBC)提供 SQL 查询服务,用户无需直接访问 Flink 集群。
-
多语言支持:任何支持 HTTP 或 JDBC 的客户端(如 Python、Java、BI 工具)都可以与 Flink SQL Gateway 交互。
(2) 多租户支持
-
会话隔离:支持多个用户或应用程序同时提交 SQL 查询,每个查询在独立的会话中运行,互不干扰。
-
资源管理:可以通过配置限制每个会话的资源使用,避免单个查询占用过多资源。
(3) 简化使用
-
无需编程:用户无需编写 Flink 程序或启动 SQL Client,直接通过 SQL Gateway 提交查询即可。
-
快速集成:其他系统(如 BI 工具、报表系统)可以通过 SQL Gateway 快速集成 Flink,无需复杂的开发工作。
(4) 增强的功能
-
结果返回:支持将查询结果以标准格式(如 JSON、CSV)返回,方便客户端处理。
-
异步查询:支持长时间运行的查询任务,客户端可以异步获取结果。
总结
Flink SQL Gateway 并不是为了替代 Flink SQL,而是为了扩展 Flink SQL 的使用场景,特别是在以下情况下:
-
需要提供标准化的 SQL 服务。
-
需要支持多用户并发查询。
-
需要与其他系统(如 BI 工具)快速集成。
如果你只是在自己的开发环境中使用 Flink SQL,那么直接使用 Flink SQL 或 SQL Client 就足够了。但如果你需要构建一个多租户的 SQL 服务或与其他系统集成,Flink SQL Gateway 是一个更好的选择。
疑问2:flinksql为什么不支持多并发
1. Flink 任务的并发类型
Flink 的并发可以从两个层面理解:
-
任务内部的并行度(Parallelism):单个 Flink 作业(Job)会被拆分成多个并行子任务(Subtask),通过设置
parallelism
参数,这些子任务可以并行处理数据。 -
多个独立作业的并发执行:多个独立的 Flink 作业(例如不同的 SQL 查询)可以同时提交到集群运行,共享集群资源(如 TaskManager 的 Slot)。
本次讨论第二种情况——多个独立作业的并发执行。
2. Flink 集群的资源管理机制
Flink 集群的资源管理基于 Slot 机制:
-
Slot 是 TaskManager 中的资源单元,每个 Slot 可以运行一个或多个任务(取决于 Slot Sharing 配置)。
-
默认情况下:所有作业共享集群的 Slot 资源。例如,如果集群共有 10 个 Slot,两个作业分别申请 5 个 Slot,则可以同时运行;但如果第三个作业申请 3 个 Slot,则需要等待前两个作业释放资源。
示例:多个作业并发运行
# 提交作业1(需要4个Slot)
flink run -p 4 -d job1.jar
# 提交作业2(需要4个Slot)
flink run -p 4 -d job2.jar
# 如果集群总Slot数为8,则两个作业可以同时运行。
# 如果总Slot数为6,第二个作业会因资源不足而等待。
3. 为什么说“直接运行多个 SQL 任务”可能存在瓶颈?
尽管 Flink 支持多作业并发提交,但在高并发场景下可能会遇到以下问题:
(1) 资源竞争
-
Slot 资源不足:如果多个作业同时申请大量 Slot,可能导致资源竞争,后续作业需要排队等待。
-
资源碎片化:不同作业的 Slot 需求可能不同,导致 Slot 无法高效分配(例如,剩余 Slot 不足以运行新作业)。
(2) 缺乏隔离性
-
资源干扰:一个资源消耗大的作业(如全表扫描)可能占用过多 CPU/内存,影响其他作业的性能。
-
配置冲突:不同作业可能对 Flink 配置(如状态后端、Checkpoint 间隔)有不同需求,但集群配置是全局的。
(3) 运维复杂度
-
作业管理:直接提交大量作业时,需要手动监控每个作业的状态、日志和资源使用情况,运维成本高。
-
故障恢复:如果某个作业失败,可能需要手动重启,缺乏统一的容错机制。
4. Flink SQL Gateway 如何优化多作业并发?
如果您直接运行多个独立的 Flink SQL 任务,虽然可以“并发”,但可能面临上述问题。而 Flink SQL Gateway 通过以下机制优化多作业并发场景:
(1) 会话级资源隔离
-
每个 SQL 查询在独立的会话(Session)中运行,会话之间资源隔离(如内存、CPU)。
-
示例:限制单个会话的最大并行度:
yaml
复制
sql-gateway: session: max-parallelism: 8
(2) 异步查询与资源回收
-
支持异步提交查询,避免客户端长时间阻塞。
-
自动回收空闲会话的资源,提高资源利用率。
(3) 统一接口与负载均衡
-
通过 REST API 或 JDBC 提供标准化接口,方便多客户端并发提交。
-
支持负载均衡,将查询分发到多个 Flink 集群(如果部署多个)。
(4) 动态资源调整
-
根据集群负载动态调整资源分配,避免资源浪费或不足。
5. 实际场景对比
假设您的公司同时运行 100 个独立的 Flink SQL 任务,以下是两种方案的对比:
场景 | 直接提交 Flink SQL 任务 | 通过 Flink SQL Gateway 提交 |
---|---|---|
资源竞争 | ❌ 高(Slot 资源全局共享,易冲突) | ✅ 低(会话级资源隔离) |
运维复杂度 | ❌ 高(需手动管理每个作业) | ✅ 低(通过 Gateway 统一管理) |
故障恢复 | ❌ 需手动处理 | ✅ 支持自动重试和状态恢复 |
多租户支持 | ❌ 弱(无用户隔离) | ✅ 强(支持多用户权限和资源配额) |
接口标准化 | ❌ 弱(依赖 Flink CLI 或自定义 API) | ✅ 强(提供 REST/JDBC 标准接口) |
总结:
说白了就是,在查询并发量很大(或者要集成报表平台)的情况下,flinksql gateway可能是更好的选择。
其他时候用flink sql也可以,就是并发大的时候不稳定,需要加资源。
本质上application模式就是一个job启一个flink集群(一个jm和多个tm)。作业之间也相互独立,但比较吃资源。
Hiveserver2介绍:
在启动Hive的时候,除了必备的MetaStore服务外 , 我们前面还有提到过2种方式使用Hive :
- bin/hive , 就是Hive Shell的客户端 , 直接写SQL
- bin/hive --service hiveserver2
HiveServer2是Hive的一个服务组件,它提供了一个多客户端访问的接口,允许用户通
过多种方式 (如JDBC、ODBC等) 连接Hive,并执行HiveQL语句。HiveServer2可以
独立于Hive运行,并且可以与其他应用程序进行集成,使得用户可以更加灵活地使用H
ive.
HiveServer2的主要作用有:
1.支持多客户端连接
HiveServer2可以同时处理多个客户端的连接请求,每个客户端可以独立地执行HiveQ
L语句。这使得多个用户可以同时访问Hive,并且不会相互影响。同时,HiveServer2
还支持连接池,可以有效地管理连接资源,提高系统的并发性能。
2.提供安全访问控制
HiveServer2支持基于Kerberos的认证和授权机制,可以对用户进行身份验证,并目可
以通过角色和权限管理来限制用户的访问权限。这样可以确保数据的安全性,并且可
以按需控制用户对数据的访问和操作
3.支持长连接和会话管理
HiveServer2支持长连接和会话管理,客户端可以通过保持连接的方式避免多次建立和
关闭连接的开销,提高了系统的性能和响应速度。同时,HiveServer2还提供了会话管
理功能,可以为每个用户分配一个独立的会话,可以在会话级别上进行状态管理和资
源隔离。
4.支持异步查询和结果集缓存
HiveServer2支持异步查询和结果集缓存,客户端可以提交一个查询请求后立即返回
然后通过轮询的方式获取查询结果。这样可以减少客户端的等待时间,并且可以利用
结果集缓存提高查询的性能
启动Hive后,
此时后台执行脚本 : nohup bin/hive --service hiveserver2 >> logs/hiveserver2.log 2>&1 &
bin/hive --service metastore , 启动的是元数据管理服务
bin/hive --service hiveserver2 , 启动的是hiveserver2服务
所以 , HiveServer2其实就是Hive内置的一个ThriftServer服务 , 提供Thrift端口供其他客户端连接
这时可以连接ThrifServer的客户端有 :
Hive内置的beeline客户端工具(命令行形式)
第三方的图形化工具 , 如DataGrip这些
下面就是它们之间的关系:
话不多说, 我们开始实际操作
在安装hive的服务器上, 首先启动metastore服务 , 然后启动hiveserver2服务
#启动metastore服务
nohup bin/hive --service metastore >> logs/metastore.log 2>&1 &
#启动hiveserver2服务
nohup bin/hive --service hiveserver2 >> logs/hiveserver2.log 2>&1 &
Beeline连接
在hive的服务器上可以直接使用beeline客户端进行连接 , Beeline是JDBC的客户端 , 通过JDBC和HiveServer2进行通信, 协议的地址是 :
jdbc:hive2://node:10000
这个10000端口是hiveserver2默认向外开发的端口
#进入beeline的连接界面
bin/beeline
#开始连接
!connect jdbc:hive2://node:10000
#接下来会开始输入hive的启动用户名密码,然后就可以开始连接了
这是beeline客户端界面
这时hive的原生界面
DataGrip连接
这种第三方的客户端页面美观大方 , 操作简洁 , 更重要的是sql编辑环境优雅 , sql语法智能提示补全 , 关键字高亮 , 查询结果智能显示 , 按钮操作大于命令操作
接下来是具体的连接步骤
打开DataGrip
选择Apach Hive进行连接
填写相关信息
连上后的操作就跟平常操作mysql一样了。
Hive on Spark
spark和hive本质上是没有关系的,两者可以互不依赖。但是在企业实际应用中,经常把二者结合起来使用。而业界spark和hive结合使用的方式,主要有以下三种:
-
hive on spark。在这种模式下,数据是以table的形式存储在hive中的,用户处理和分析数据,使用的是hive语法规范的 hql (hive sql)。 但这些hql,在用户提交执行时(一般是提交给hiveserver2服务去执行),底层会经过hive的解析优化编译,最后以spark作业的形式来运行。事实上,hive早期只支持一种底层计算引擎,即mapreduce,后期在spark 因其快速高效占领大量市场后,hive社区才主动拥抱spark,通过改造自身代码,支持了spark作为其底层计算引擎。目前hive支持了三种底层计算引擎,即mr, tez和spark.用户可以通过set hive.execution.engine=mr/tez/spark来指定具体使用哪个底层计算引擎。
-
spark on hive。上文已经说到,spark本身只负责数据计算处理,并不负责数据存储。其计算处理的数据源,可以以插件的形式支持很多种数据源,这其中自然也包括hive。当我们使用spark来处理分析存储在hive中的数据时,这种模式就称为为 spark on hive。这种模式下,用户可以使用spark的 java/scala/pyhon/r 等api,也可以使用spark语法规范的sql ,甚至也可以使用hive 语法规范的hql 。而之所以也能使用hql,是因为 spark 在推广面世之初,就主动拥抱了hive,通过改造自身代码提供了原生对hql包括hive udf的支持(其实从技术细节来将,这里把hql语句解析为抽象语法书ast,使用的是hive的语法解析器,但后续进一步的优化和代码生成,使用的都是spark sql 的catalyst),这也是市场推广策略的一种吧。
-
spark + spark hive catalog。这是spark和hive结合的一种新形势,随着数据湖相关技术的进一步发展,这种模式现在在市场上受到了越来越多用户的青睐。其本质是,数据以orc/parquet/delta lake等格式存储在分布式文件系统如hdfs或对象存储系统如s3中,然后通过使用spark计算引擎提供的scala/java/python等api或spark 语法规范的sql来进行处理。由于在处理分析时针对的对象是table, 而table的底层对应的才是hdfs/s3上的文件/对象,所以我们需要维护这种table到文件/对象的映射关系,而spark自身就提供了 spark hive catalog来维护这种table到文件/对象的映射关系。注意这里的spark hive catalog,其本质是使用了hive 的 metasore 相关 api来读写表到文件/对象的映射关系(以及一起其他的元数据信息)到 metasore db如mysql, postgresql等数据库中。(由于spark编译时可以把hive metastore api等相关代码一并打包到spark的二进制安装包中,所以使用这种模式,我们并不需要额外单独安装hive);
-
Hive 2.0 之后,MR执行引擎已经出于deprecated 状态,“It may be removed without further warning.”,hive官方推荐使用的是 hive on tez 或 hive on spark; Hiv3.0 之后, hive官方推荐使用的是 hive on tez,并在Hive4.0中,移除了 hive on spark;
概括起来,SparkOnHive和 HiveOnSpark的核心区别:
- 不在于是否访问HIVE数仓中的数据(二者都访问);
- 也不在于客户端的SQL语法规范是 HIVE SQL 还是 SPARK SQL(Spark支持绝大部分HiveSqly语法);
- 二者的核心区别在于,客户端的 SQL 是否提交给了服务角色 HiveServer2 (org.apache.hive.service.server.HiveServer2),且该hs2配置了 hive.execution.engine=spark;
Spark SQL gateway 的解决方案-Kyuubi
•HiveServer2 本质上是 HIVE 提供的 SQL gateway服务;
•Spark原生提供的 SQL gateway 服务,只有 spark thrift Server($SPARK_HOME/sbin/start-thriftserver.sh) ,但因为功能和稳定性等各种原因,不推荐在生产环境使用($SPARK_HOME/bin/spark-sql 只是一个spark 应用,不是服务);
•网易的开源组件 Kyuubi,起到了 Spark SQL gateway服务的角色,该项目目前已经是 Apache 顶级开源项目,可以在生产环境使用;