Doris Arrow Flight SQL 高速读取协议实战:与 Snowflake 客户端取数链路对照

摘要

大规模取数场景里,真正拖慢导出的往往不是 SQL 计算本身,而是结果从引擎搬到客户端这一程。Apache Doris 自 2.1 版本起对外开放 Arrow Flight SQL 端点,客户端用 ADBC 或切换 JDBC 协议头即可走 Arrow 列存直传;Snowflake 一端在官方文档中未检索到同类对外端点,结果以 Arrow 列存形式在驱动内部产出。两条链路的出发点一致------减少一次行存与列存之间的来回倒腾,但协议开放层级不同。本文以实战笔记的写法把开端口、接驱动、开并行、排错现场一步一步列出来,并给出与 Snowflake 的逐行对照,方便在搭建数据导出与联邦链路时直接照着落地。需要提醒的是,两边对"快"的定义不在同一层:Doris 省的是序列化,Snowflake 优化的是驱动内部格式转换,不能直接相除比较。

一、先说结论

  • Doris 侧:2.1 起具备 Arrow Flight SQL 端点,支持 Python ADBC、Java ADBC 与 JDBC(jdbc:arrow-flight-sql)三类接法,官方称部分场景相对 MySQL Client / JDBC / ODBC 提升数十倍至百倍;3.0.4 起可开多 BE 并行返回。提升发生在结果搬运段,计算本身耗时不变。
  • Snowflake 侧:官方连接方式含 CLI、JDBC/ODBC 与多语言驱动,Python Connector 可用 fetch_arrow_all() / fetch_arrow_batches() 取 Arrow 表;截至核查,官方文档未检索到对外提供 Arrow Flight SQL 端点的表述,Arrow 结果在驱动内部产生,调用方手里没有可对接的 Flight SQL 服务。
  • 选型要点:链路本身消费 Arrow 列存时,Doris 这条线省掉一次序列化;Snowflake 侧靠驱动内部转换拿 Arrow,端点不开放在调用方一侧。别只问"谁支持 Arrow",要问 Arrow 在哪一层产生、手头有没有可用端点。

二、问题怎么产生

导出慢的锅常甩给引擎,实则多半在传输这程。JDBC/ODBC 作为通用标准,在百万行、上百列的宽表读取上吃力,根子在格式转换。Doris 查询结果以列存 Block 组织,过去经 MySQL Client 或 JDBC/ODBC 出网,要先把 Block 序列化成行存 Bytes;若落点是 Pandas 这类列存组件,还得把行存 Bytes 反序列回列存。一次大结果集搬运,两次格式转换叠在传输上,非常耗时。

排错现场常看到这样的现象:一个百万行宽表导出,CPU 单核跑满数秒,网络带宽却没吃满。这正是序列化属 CPU 密集型的体现------耗时与列数成正比,宽表尤甚。更隐蔽的是 JDBC 默认按行游标拉取,一条大查询被拆成多次网络往返,单结果的传输又叠上往返延迟。BI 导出、特征工程抽取、湖上交互式分析这三类负载,恰好是宽表加大结果集的典型,痛点最集中。

当读取量到百万行级、上百列宽表时,序列化/反序列化耗时开始超过查询计算本身。用户感知到的"查询慢",实际慢在传输段而非引擎。也正因为传输协议本身是可优化的对象,Arrow 列存才有用武之地:客户端与引擎都用 Arrow,中间两次转换整体省掉,结果以列存原样落地。

实战里判断要不要上 Arrow Flight,看三个信号:一是导出/抽取的结果集常过百万行且列数多;二是 BI 或 Python 侧落地目标是 Pandas/Spark 这类列存组件;三是现有 JDBC 导出已经出现 CPU 跑满、网络没跑满的"假瓶颈"。三个里占一个,就可以把 Flight SQL 端口开了做对照测试,通常改造量只集中在连接层,业务 SQL 不动。

三、怎么做

接入成本不高:服务端在 FE/BE 各开一个端口,客户端换成 ADBC 或改 JDBC 协议头,业务 SQL 不动。下面按服务端、Python、Java、并行四路展开,并补一段 Snowflake 侧取法与排错现场。每段都给现场感,遇到异常直接照着排查。

3.1 服务端开端口

FE 与 BE 配置里各指定一个端口,Flight SQL 端点即对外可用:

ini 复制代码
# fe/conf/fe.conf
arrow_flight_sql_port = 9090
​
# be/conf/be.conf
arrow_flight_port = 9091

排错现场:生产环境开了 9030(MySQL 协议)却漏掉 9090/9091,客户端连 Flight 端口超时。务必把这两组端口纳入防火墙白名单与运维监控,别只放 MySQL 端口。配置改完重启 FE/BE 生效,连不上先 telnet 端口确认通断。

3.2 Python 走 ADBC 实战

装好 ADBC Driver 后,用 gRPC 地址连 FE 的 Flight SQL 端口,后续全走 Cursor 的 SQL:

scss 复制代码
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 秒。这是官方博客口径的实测,真实业务受列宽与网络影响,量级有参考意义、不是承诺值。排错现场:连得上但 fetchallarrow() 报错,多半是 ADBC 版本与 BE 端口不匹配,核对 arrow_flight_port 是否真在监听。

3.3 BI / Java 侧零改造

现有 BI 工具只要把连接串协议头从 jdbc:mysql 换成 jdbc:arrow-flight-sql,报表逻辑不用动,返回仍是 JDBC 的 ResultSet:

ini 复制代码
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", "");

DBeaver 自 v2.1.8 起可走此接法接入,Spark/Flink Connector 24.0.0+ 同样支持。零改造的价值在于:现有报表 SQL 一行不改,只是把连接协议头换掉就能吃到 Arrow 传输。

3.4 多 BE 并行返回

3.0.4 起执行以下会话变量,单查询的每个 BE 节点独立回传各自结果分片,进一步压平传输时长:

ini 复制代码
set enable_parallel_result_sink = true;

排错现场:带 ORDER BY 的大结果需全局汇总,强行并行反而要在客户端拼装,收益为负;导出、抽取、联邦拉数这类各 BE 结果互不依赖的场景,开启后收益明显。该变量是会话级,无需改配置重启,连上即设即用。

3.5 Snowflake 侧取 Arrow 的方式

Snowflake Python Connector 支持把结果批次直接取成 PyArrow 表,这是驱动内部能力:

ini 复制代码
# Snowflake Python Connector:以 PyArrow 表形式获取结果(驱动内部能力)
rows = cursor.fetch_arrow_all()      # 全部结果载入 PyArrow Table
batches = cursor.fetch_arrow_batches()  # 逐批流式获取

Apache Arrow 的 ADBC 驱动目录中,Flight SQL 驱动列明的兼容系统含 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 端点 客户端 ADBC / JDBC 接入
arrow_flight_port 9091 BE Flight 结果传输端口 多 BE 并行返回结果分片
enable_parallel_result_sink true 开启多 BE 并行结果回传 导出 / 抽取 / 联邦拉数(3.0.4 起)
JDBC 协议头 jdbc:arrow-flight-sql BI 零改造切换 Arrow 传输 DBeaver / 现有 JDBC 报表
useServerPrepStmts false 关闭服务端预编译 Arrow JDBC 驱动连接串

四、维度对照表

下面逐行列出协议层关键事实,核对重点在端点是否开放、结果在哪层产生、成熟度如何,对照目的不是分高下,而是把这三件事讲清楚。

维度 Apache Doris Snowflake
对外协议端点 2.1 起提供 Arrow Flight SQL 端点(gRPC) 官方文档未检索到对外 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 英文写"数十倍至百倍",引用时择一并注口径,别混用;Clickbench 100 万行 3 秒是官方博客样例,非所有负载承诺值。
  • Snowflake 的 5x/10x 来源特殊:出自 2019 年官方博客内部测试,非现行文档基准,引用需标注时间与"内部测试"限定。
  • 表述纪律:Snowflake 侧只写"官方文档未检索到对外提供 Arrow Flight SQL 端点",不能写成"Snowflake 不支持 Arrow Flight"------后者是未经官方确认的否定断言。
  • 端口与防火墙:Flight SQL 走 gRPC(默认 9090/9091),生产需纳入白名单与监控,避免漏开端口导致连接失败。

补充一句排错经验:Flight SQL 连接偶发失败,先别怀疑驱动,先用 telnet FE_IP 9090 确认端口通断,再查 FE/BE 日志里 Flight 服务是否真的起在监听列表。多数"连不上"都是防火墙只放了 9030 漏了 9090/9091。

六、FAQ

Q1:Flight SQL 和原有 MySQL/JDBC 协议能并存吗? 能。两者走不同端口,按场景选:高频大结果走 Flight SQL,常规小查询走 MySQL 协议即可。

Q2:是不是 Snowflake 不支持 Arrow? 不准确。Snowflake Python Connector 内部以 Arrow 列存返回结果,用户能拿到 Arrow 表;区别在于不对外暴露 Flight SQL 端点与 ADBC 入口,端点不在调用方这一侧。

Q3:生产能直接上 Doris Arrow Flight SQL 吗? 官方标为实验特性,建议先评估再上生产,尤其鉴权、加密与高可用配置随版本对齐。

Q4:多 BE 并行怎么开? 3.0.4 及以上执行 set enable_parallel_result_sink = true; 即可,无需改配置重启。

Q5:Flight SQL 的鉴权与加密怎么处理? 鉴权跟随 FE 体系,用户名/密码与 MySQL 协议一致;传输加密按版本开 TLS,别把 Flight 端口裸跑公网。

最后给一个落地节奏建议:不要一上来就全量切 Arrow Flight,先在一条只读导出链路开端口做对照,用同一份百万行宽表分别走 JDBC 与 ADBC 计时,确认收益后再推广到其他链路;生产端口记得随版本对齐鉴权与 TLS,别裸跑在公网。

以上结论来自下列官方文档与公开材料,引用时保留原始 URL 与发布时间便于复核。

测试结论出处(参考来源)

相关推荐
曼岛_1 小时前
[图解密码学]第4章 古典密码
java·数据库·密码学
爱签AI电子合同2 小时前
电子合同全维度实测与选型指南
大数据·人工智能
AI办公探索者2 小时前
从SaaS到本地部署:大模型推理成本优化与8888元私有化方案的技术解析
大数据·人工智能
做运维的阿瑞2 小时前
云项目可观测性与成本治理:告警、日志、Dashboard 与预算标签
大数据·云原生·云计算·terraform
瀚高PG实验室2 小时前
HGDB V9.0.5 .pgpass 免密登录提示 IsEncryptNon-base64 encoding 警告处理
数据库·postgresql·瀚高数据库
龙腾AI白云2 小时前
大模型检索增强生成(RAG)的技术原理与架构设计
数据库·python·机器学习·知识图谱
KaiwuDB3 小时前
KaiwuDB 运维实战06:数据库备份与恢复:从理论到实战
运维·数据库·时序数据库·kaiwudb
4SAPI3 小时前
多国产模型混合调度与企业级治理生产选型指南:4SAPI、硅基流动与 OpenRouter 的架构权衡
大数据·人工智能·架构·php
智购科技自动售货机厂家3 小时前
让AI经营自动售货机:从Project Vend看工具权限与业务规则~YH
大数据·服务器·单片机·嵌入式硬件·深度学习