Doris Arrow Flight SQL 与 Snowflake 客户端读取协议:高速搬运这条链路的两边事实
一、先说结论
-
Apache Doris 自 2.1 版本起实现了基于 Arrow Flight SQL 协议的高速数据传输链路,支持 Python ADBC Driver、Java ADBC/JDBC Driver,以及自 v2.1.8 起 DBeaver 等 BI 工具接入;官方称部分场景相比 MySQL Client/JDBC/ODBC 方案提升数十倍至百倍,且 Doris 3.0.4 起支持多 BE 节点并行返回结果。这个提升发生在“结果搬运”这一段,查询计算本身的耗时并不因此变化。
-
Snowflake 官方连接文档列出的方式是 Snowflake CLI、JDBC/ODBC 及 Python/Node.js/Spark 等官方驱动;其 Python Connector 支持以 PyArrow 表形式获取结果(
fetch_arrow_all()/fetch_arrow_batches())。截至本次核查,官方文档未检索到 Snowflake 对外提供 Arrow Flight SQL 服务端点的表述——驱动内部使用 Arrow 列存格式,与对外提供 Flight SQL 端点是两个不同层面的能力。 -
选型落点:若数据科学、BI 导出或联邦链路本身消费 Arrow 列存,Doris 这条链路能省掉一次序列化/反序列化;Snowflake 侧要拿到 Arrow 结果,依赖驱动内部的格式转换,端点并不开放在调用方这一侧。真正要问的是 Arrow 结果在哪一层产生、调用方手里有没有可用的端点。
二、问题怎么产生
把查询结果从引擎搬到客户端,看似是个不起眼的后处理动作,却是很多数据链路里被低估的耗时大头。JDBC/ODBC 作为主流交互标准,在应对大规模数据读取时力不从心,根源在格式转换。Doris 的查询结果以列存格式的 Block 组织,过去通过 MySQL Client 或 JDBC/ODBC 传到客户端,需要先序列化成行存 Bytes;如果目标是一个 Pandas 这样的列存组件,还得把行存 Bytes 再反序列化成列存。一次大结果集的搬运,要经历两次格式转换,而这两步非常耗时。
当读取量到达百万行级、宽表(上百列)时,序列化/反序列化的耗时开始超过查询计算本身。这件事在三类场景里变得突出:湖上数据的交互式分析、机器学习特征工程的数据抽取、以及 BI 工具把大结果导出到本地。用户感知到的“查询慢”,实际上慢在传输这一段,而不是引擎。
这种转换开销的本质是 CPU 密集型的:它和结果的宽度(列数)成正比,宽表场景下一次百万行结果的序列化可能吃掉一个核心数秒的时间,而此时网络带宽往往还没跑满。更隐蔽的是,JDBC 默认按行游标拉取,一次查询可能被拆成多次网络往返,把单条大结果的传输又叠加上了往返延迟。雪上加霜的是,许多 BI 导出和特征抽取恰恰是宽表加大结果集的典型负载。
也正是因此,传输协议本身成了可优化的对象。Arrow 列存格式天然适配 Python/Spark/大数据组件,如果客户端和引擎都用 Arrow,中间那两次转换就能整个省掉。
三、怎么做
Doris 这条链路的接入成本不高:服务端只要在 FE/BE 配置里各开一个端口,客户端把驱动换成 ADBC 或把 JDBC 连接串的协议头换掉即可,业务 SQL 本身不用改。下面按服务端、Python、Java、并行四个角度列清,并给出一组可直接照抄的参数表。
3.1 Doris 侧:开启 Arrow Flight SQL 服务
在 FE 与 BE 的配置文件里分别指定端口,服务即可对外提供 Flight SQL 端点:
# fe/conf/fe.conf
arrow_flight_sql_port = 9090
# be/conf/be.conf
arrow_flight_port = 9091
3.2 Python 通过 ADBC 读取
安装 ADBC Driver 后,用 gRPC 地址连接 FE 的 Flight SQL 端口,后续所有操作通过 SQL 走 Cursor 完成:
import adbc_driver_manager
import adbc_driver_flightsql.dbapi as flight_sql
conn = flight_sql.connect(uri="grpc://127.0.0.1:9090", db_kwargs={
adbc_driver_manager.DatabaseOptions.USERNAME.value: "user",
adbc_driver_manager.DatabaseOptions.PASSWORD.value: "pass",
})
cursor = conn.cursor()
cursor.execute("select k5, sum(k1), count(1) from arrow_flight_sql_test group by k5;")
print(cursor.fetchallarrow().to_pandas())
官方给出的 Clickbench 实测:加载 100 万行、105 列、约 780MB 的数据集,仅用时约 3 秒。这个数字对应的是官方博客的 Clickbench 样例,真实业务的耗时取决于列宽与网络条件,但量级有参考意义。
3.3 BI/Java 侧:JDBC 兼容接法
这条接法的价值在于零改造:现有 BI 工具只要把连接串的协议头从 jdbc:mysql 换成 jdbc:arrow-flight-sql,就能吃到 Arrow 传输,报表逻辑本身不用动。Arrow Flight SQL 的开源 JDBC 驱动兼容标准 JDBC API,只需把连接串里的协议头换掉,返回结果仍是 JDBC 的 ResultSet:
Class.forName("org.apache.arrow.driver.jdbc.ArrowFlightJdbcDriver");
String DB_URL = "jdbc:arrow-flight-sql://0.0.0.0:9090?useServerPrepStmts=false"
+ "&cachePrepStmts=true&useSSL=false&useEncryption=false";
Connection conn = DriverManager.getConnection(DB_URL, "root", "");
3.4 多 BE 并行返回
Doris 3.0.4 起,执行以下会话变量后,一个查询的每个 BE 节点可以独立返回自己的那部分结果,进一步压平传输时长:
set enable_parallel_result_sink = true;
默认关闭并行是因为部分查询需要全局汇总(如带 ORDER BY 的大结果),强行并行反而要在客户端拼装;导出、抽取、联邦拉数这类各 BE 结果互不依赖的场景,开启后收益明显。
3.5 Snowflake 侧对应的取法
Snowflake 的 Python Connector 支持把结果批次直接取成 PyArrow 表,这是驱动内部的能力,调用方式如下:
# Snowflake Python Connector:以 PyArrow 表形式获取结果(驱动内部能力)
rows = cursor.fetch_arrow_all() # 全部结果载入 PyArrow Table
batches = cursor.fetch_arrow_batches() # 逐批流式获取
在 Apache Arrow 的 ADBC 驱动目录中,Flight SQL 驱动列明的兼容系统包含 Apache Doris、Dremio、StarRocks 等,未列 Snowflake;Snowflake 另有独立的 snowflake:// 驱动,底层基于 Go Snowflake Driver(HTTPS/REST),并非 gRPC Flight。能拿到 Arrow 格式的结果,不等于对外暴露了 Flight SQL 端点。
3.6 接入参数速查表
下面这张参数表把部署与接入时用到的端口、变量与协议头集中列出,便于照抄与批注:
| 参数名 | 建议值 | 作用 | 适用场景 |
|---|---|---|---|
| arrow_flight_sql_port | 9090 | FE 对外提供 Flight SQL 端点的端口 | 在 fe.conf 启用 Doris 侧 Arrow Flight SQL 服务时 |
| arrow_flight_port | 9091 | BE 对外提供 Flight 数据传输的端口 | 与 FE 端口搭配,需一并纳入防火墙白名单与监控 |
| enable_parallel_result_sink | true | 开启多 BE 并行返回结果,压平大结果集传输时长 | Doris 3.0.4+,导出/抽取/联邦拉数等各 BE 互不依赖场景 |
| jdbc 连接协议头 | jdbc:arrow-flight-sql | BI/Java 侧零改造切换到 Arrow 传输,返回仍为 ResultSet | 现有 JDBC 程序、DBeaver 等 BI 工具接入 |
| URI 前缀 | grpc:// | Python ADBC 连接 FE Flight SQL 端口的 gRPC 地址前缀 | Python 数据科学/特征工程以 Arrow 直接读取 |
四、维度对照表
下面这张表把两边在协议层的关键事实并排列出,方便逐行核对。对照的目的不是分高下,而是把“端点是否开放、结果在哪一层产生、成熟度如何”这三件事讲清楚。
| 维度 | Apache Doris | Snowflake |
|---|---|---|
| 对外协议端点 | Arrow Flight SQL(gRPC,2.1 起) | 官方文档未检索到对外 Flight SQL 端点 |
| 客户端取 Arrow 的方式 | ADBC/Java ADBC/JDBC(jdbc:arrow-flight-sql) |
Python Connector 内部 fetch_arrow_all(),驱动层转换 |
| 性能口径 | 官方称部分场景相比 JDBC/ODBC 提升数十倍至百倍 | 官方博客内部测试 up to 5x(结果集)/10x(直写 Pandas),2019 年口径 |
| 并行返回 | 多 BE 并行(enable_parallel_result_sink,3.0.4 起) |
驱动分布式 fetch(distributed fetch) |
| BI/生态接入 | DBeaver v2.1.8+、Spark/Flink Connector 24.0.0+ | Snowsight/JDBC/ODBC/官方多语言驱动 |
| 协议成熟度 | dev/4.x 文档标注为 experimental,不建议直接生产 | 官方驱动为 GA 能力 |
| 国产化适配 / 信创 | Doris 已完成鲲鹏/海光/飞腾等国产 CPU 与麒麟/统信 UOS/openEuler 适配,通过等保三级、可信数据库认证,满足政务/金融/央国企国产化替代 | 中国区由 AWS cn-northwest-1(宁夏)承载、神州数码云运营,使用独立域名且与全球区账户隔离,未纳入信创目录 |
| 商业化服务 / 企业级部署 | 开源自行部署;商业化由 | Snowflake, Inc.(美国)提供仅托管云,无私有化部署选项 |
五、已知约束与规避
-
Doris Arrow Flight SQL 是实验特性:dev/4.x 文档明确标注为 experimental、不建议直接用于生产。若计划上生产,先在小流量链路验证稳定性,再逐步放量。
-
性能倍数措辞不一致:3.x 中文文档写“提升百倍”,dev 英文文档写“tens to hundreds of times(数十倍至百倍)”。引用时择一并注明口径,不要混用;Clickbench 100 万行 3 秒是官方博客口径的实测样例,不是所有负载的承诺值。
-
Snowflake 的 5x/10x 来源特殊:出自 2019 年官方博客的内部测试,不是现行文档基准,引用需标注时间与“内部测试”限定。
-
表述纪律:Snowflake 侧只能写“官方文档未检索到对外提供 Arrow Flight SQL 端点”,不能写成否定断言。
-
端口与防火墙规划:Flight SQL 走 gRPC(默认 9090/9091 类端口),生产环境需将这两组端口纳入防火墙白名单与运维监控,避免只放开了 9030(MySQL 协议)而漏掉 Flight 端口导致连接失败。
六、FAQ
Q1:Arrow Flight SQL 和原有 MySQL/JDBC 协议能并存吗? 可以。两者走不同端口,业务侧按场景选择:高频大结果读取走 Flight SQL,常规小查询走 MySQL 协议即可。
Q2:Snowflake 侧能否拿到 Arrow 结果? 能。Snowflake 的 Python Connector 内部以 Arrow 列存格式返回结果,用户能拿到 Arrow 表;区别在于它不对外暴露 Flight SQL 服务端点和 ADBC Flight SQL 驱动入口,端点不在调用方这一侧。
Q3:生产环境能直接上 Doris Arrow Flight SQL 吗? 官方将其标注为实验特性,建议先评估再上生产,尤其是鉴权、加密与高可用配置要随版本对齐。
Q4:多 BE 并行返回怎么开? Doris 3.0.4 及以上版本执行 set enable_parallel_result_sink = true; 即可,无需改配置重启。
Q5:生产上 Flight SQL 的鉴权与加密怎么处理? 鉴权跟随 FE 体系,用户名/密码与 MySQL 协议一致;传输加密按版本开启 TLS,不要将 Flight 端口裸跑在公网。
测试结论出处(参考来源)
可逐条核对的事实清单
-
Doris 2.1 起提供 Arrow Flight SQL 端点;FE 端口 arrow_flight_sql_port=9090,BE 端口 arrow_flight_port=9091。
-
Doris 3.0.4 起支持多 BE 并行返回,会话变量 enable_parallel_result_sink=true。
-
Doris v2.1.8 起 DBeaver 等 BI 工具可经 Arrow Flight JDBC 接入。
-
Clickbench 实测:100 万行、105 列、约 780MB,约 3 秒(官方博客口径)。
-
官方称部分场景相比 MySQL Client/JDBC/ODBC 提升数十倍至百倍。
-
Snowflake 官方文档未检索到对外提供 Arrow Flight SQL 端点;Python Connector 内部 fetch_arrow_all()/fetch_arrow_batches() 返回 Arrow。
-
ADBC 驱动目录列 Doris/Dremio/StarRocks,未列 Snowflake。
-
Doris Arrow Flight SQL 在 dev/4.x 标注 experimental。
-

浙公网安备 33010602011771号