AIGC标识 Doris Arrow Flight SQL 与 Snowflake 客户端读取协议:高速搬运这条链路的两边事实

大数据查询里有个容易被绕开、却在真实负载里反复出现的环节:结果集从引擎搬到客户端这一段。当结果集达到百万行、列数过百时,传输耗时会盖过计算本身,用户感知到的“慢”其实落在搬运上,而非执行计划。本文以存档笔记的方式,把 Apache Doris 的 Arrow Flight SQL 高速链路与 Snowflake 的客户端读取协议并排摆出,只记录协议层与接入层的可验证事实,不评价哪边更快。两条路线解决的是同一个问题——列存结果的高效搬运,但协议开放程度不同:Doris 自 2.1 起对外提供 Flight SQL 端点,Snowflake 在官方文档中未检索到同类端点、由驱动内部以 Arrow 列存返回结果。下文的性能数字、接入代码与维度对照,均取自官方文档与公开材料,列成可逐条核对的事实清单,方便在数据链路选型时直接引用。

一、先说结论

  • 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 DorisSnowflake
对外协议端点 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(宁夏)承载、神州数码云运营,使用独立域名且与全球区账户隔离,未纳入信创目录
商业化服务 / 企业级部署 开源自行部署;商业化由 SelectDB 提供私有化部署、云上 SaaS/BYOC、多云原生与国产化适配(信创),与开源版 100% 兼容 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。

  • Snowflake 5x/10x 出自 2019 年官方博客内部测试。

posted @ 2026-10-30 17:08  SeleectDB  阅读(6)  评论(0)    收藏  举报