Spark Connect Protobuf 定义:协议文件与 Python 桩代码生成全指南
Spark Connect Protobuf 定义协议文件与 Python 桩代码生成全指南【免费下载链接】sparkApache Spark - A unified analytics engine for large-scale data processing项目地址: https://gitcode.com/gh_mirrors/sp/sparkSpark Connect 是 Apache Spark 的客户端—服务器client-server架构方案它把 Spark 的核心执行能力封装为远程服务客户端通过标准协议与服务器通信。而这一协议的定义就落在sql/connect/common/src/main/protobuf/目录下的一组.proto文件中。本篇指南以仓库中的 README.md 为骨架系统讲解 Spark Connect 协议的定义方式、.proto文件的构成以及修改协议后如何通过 Docker 镜像或本地 Python 环境重新生成 PySpark 所需的 Python 桩代码stubs帮助你在开发和提交 Spark Connect 相关改动时快速掌握协议修改的完整闭环。阅读完本文你将能够理解sql/connect/common/src/main/protobuf目录下各.proto文件的职责划分与底层生成链路掌握两种官方推荐的代码生成方法Docker 镜像法与本地buf法并理解其原理差异了解生成产物在python/pyspark/sql/connect/proto/下的组织方式与代码风格校验规则。一、目录概览Spark Connect 协议从何而来sql/connect/common/src/main/protobuf/目录下存放了定义 Spark Connect 协议的全部.proto文件它们统一声明了package spark.connect与syntax proto3组织在 spark/connect/ 子目录中文件职责base.proto协议核心Plan、UserContext、各类请求/响应消息如AnalyzePlanRequest、ExecutePlanRequest、FetchErrorDetailsRequestcatalog.protoCatalog 相关操作CurrentDatabase、TableExists、GetTables等commands.proto服务端命令定义如SqlCommand、WriteOperation等common.proto通用类型如StorageLevel、DataType引用、Expression引用expressions.proto表达式Expression的定义relations.proto关系Relation的定义覆盖 DataFrame 逻辑计划types.protoSpark 数据类型DataType、StructType等ml.protoML 相关 API 的消息定义ml_common.protoML 通用类型与参数处理pipelines.protoDeclarative Pipelines 相关定义example_plugins.proto插件示例定义这些.proto文件相互 import形成完整的协议模型。例如 base.proto 顶部的 import 语句就引入了commands.proto、common.proto、expressions.proto、relations.proto、types.proto、ml.proto与pipelines.proto。从源码结构看这一目录同时是 JVM 侧服务端与 Python 侧客户端协议定义的中枢JVM 侧通过option java_package org.apache.spark.connect.proto与option java_multiple_files true生成 Java 类Python 侧则通过buf的 protoc 插件生成*_pb2.py与*_pb2.pyi文件供 PySpark 客户端使用。二、修改 .proto 之后为什么必须重新生成桩代码协议文件是客户端与服务端之间的“契约”。当你在sql/connect/common/src/main/protobuf/下修改了任何.proto文件比如给消息新增字段、为Plan增加新的操作类型必须重新生成python/pyspark/sql/connect/proto/下的 Python 桩代码否则Python 客户端无法感知新协议PySpark 客户端通过python/pyspark/sql/connect/proto/下的*_pb2.py进行消息序列化/反序列化。协议已改而桩代码未更新客户端将无法构造或解析新消息。类型提示缺失*_pb2.pyi文件为 IDE 与mypy提供类型信息不更新会导致类型检查与自动补全失真。CI 校验失败从仓库配置看pyproject.toml中明确将python/pyspark/sql/connect/proto/*排除在ruff的 lint 范围之外原因是这些文件是自动生成的与python/pyspark/sql/streaming/proto/*同理。任何手工改动都会被后续重新生成覆盖因此必须走正式生成流程。官方在 README.md 中给出了两种生成方法Docker 镜像法推荐与本地 Python 环境法。下文逐一展开。三、Method 1Docker 镜像法推荐免安装、可复现Docker 法无需在本地安装任何代码生成工具构建出的镜像自带固定版本的工具链生成结果可复现适合 CI 或多人协作场景。3.1 构建镜像在 Spark 仓库根目录下执行docker build -t connect-cg \ --build-context root. \ dev/spark-test-image/connect-gen-protos/说明-t connect-cg为镜像命名--build-context root.把Spark 仓库根目录作为名为root的构建上下文这样 Dockerfile 可以COPY --fromroot pyproject.toml ./pyproject.toml获取依赖定义构建目标目录是dev/spark-test-image/connect-gen-protos/其中只有一份 Dockerfile。打开这份 Dockerfile 可以看到镜像的具体构成它基于ubuntu:nobleUbuntu 24.04安装python3.12与python3.12-venv从 GitHub Releases 下载固定版本buf当前 Dockerfile 中ARG BUF_VERSION1.66.1并安装到/usr/local/bin/buf创建虚拟环境/opt/spark-venv并设置为默认PATH从root上下文拷贝pyproject.toml随后执行python3.12 -m pip install --group ci_lint安装 CI lint 依赖组——该组见 pyproject.toml 中的ci_lint组包含internal_lint其中锁定了mypy1.19.1、mypy-protobuf3.3.0、ruff0.14.8等版本与internal_ci_connect包含protobuf6.33.5等以/spark为工作目录ENTRYPOINT指向/spark/dev/connect-gen-protos.sh。因此镜像内工具版本与pyproject.toml中的锁定版本保持一致这正是“可复现环境”的来源。3.2 运行镜像生成代码在 Spark 仓库根目录执行docker run --cpus 1 -it --rm -v $(pwd):/spark connect-cg参数含义--cpus 1限制容器使用 1 个 CPU控制构建期资源占用-it分配交互式终端便于观察生成日志--rm容器退出后自动删除-v $(pwd):/spark将当前 Spark 仓库挂载到容器内的/sparkconnect-cg上一步构建的镜像名。容器启动后ENTRYPOINT会在/spark下执行 dev/connect-gen-protos.sh该脚本内部进一步调用./dev/gen-protos.sh connect $即 dev/gen-protos.sh最终把生成的*_pb2.py、*_pb2.pyi等文件写入挂载目录python/pyspark/sql/connect/proto/。由于仓库是以 bind mount 方式挂载容器内写出的文件会直接落盘到本地 checkout退出容器后改动依然保留。四、Method 2本地 Python 环境法无需 Docker不想用 Docker 时可以在本地准备工具链后直接运行生成脚本。4.1 前置条件需要两个基础工具**buf与 buf.gen.yaml 控制行为Python 3.12生成产物依赖较新的 Python 生态。4.2 安装 Python 依赖先查看 pyproject.toml 中锁定的最新版本——具体而言internal_lint组中定义了ruff0.14.8 mypy1.19.1 mypy-protobuf3.3.0README 给出的安装命令以当前pyproject.toml为准pip install mypyversion mypy-protobufversion ruffversion例如pip install mypy1.19.1 mypy-protobuf3.3.0 ruff0.14.8提示版本号务必与pyproject.toml保持一致。mypy-protobuf负责生成*_pb2.pyi类型桩文件ruff负责对生成代码做统一格式化mypy用于类型检查。若版本漂移生成的代码格式或类型注解可能与仓库 CI 期望不符。4.3 执行生成脚本在 Spark 仓库根目录运行./dev/connect-gen-protos.sh脚本将生成的 Python 文件写入python/pyspark/sql/connect/proto/。也可以传入自定义输出目录./dev/connect-gen-protos.sh /tmp/my-proto-output五、源码视角生成链路内部做了什么理解了两种方法后再深入源码看这条生成链路能更好地把握“改协议 → 重新生成”的内在逻辑。5.1 入口脚本与参数dev/connect-gen-protos.sh 是一个极薄的封装if [[ $# -gt 1 ]]; then echo Illegal number of parameters. echo Usage: ./dev/connect-gen-protos.sh [path] exit -1 fi ./dev/gen-protos.sh connect $它只接收 0 或 1 个参数可选的自定义输出路径其余工作全部委托给dev/gen-protos.sh connect。而dev/gen-protos.sh是一个同时服务connect与streaming两个模块的通用生成脚本if [[ $1 connect ]]; then MODULEconnect OUTPUT_PATH${SPARK_HOME}/python/pyspark/sql/connect/proto/ SOURCE_MODULEspark.connect TARGET_MODULEpyspark.sql.connect.proto elif [[ $1 streaming ]]; then MODULEstreaming OUTPUT_PATH${SPARK_HOME}/python/pyspark/sql/streaming/proto/ SOURCE_MODULEorg.apache.spark.sql.execution.streaming TARGET_MODULEpyspark.sql.streaming.proto ...connect 模式与 streaming 模式共用一套处理逻辑只是源.proto目录、输出目录和模块命名不同。connect 模式进入sql/connect/common/src/main目录执行buf generatestreaming 模式则进入sql/core/src/main。这也是为什么两个模块生成的 Python 产物结构完全一致。5.2 插件配置buf.gen.yamlbuf generate的行为由sql/connect/common/src/main/buf.gen.yaml控制。它一次生成多种语言的产物version: v1 plugins: - plugin: buf.build/protocolbuffers/cpp:v33.5 out: gen/proto/cpp - plugin: buf.build/protocolbuffers/csharp:v33.5 out: gen/proto/csharp - plugin: buf.build/protocolbuffers/java:v33.5 out: gen/proto/java - plugin: buf.build/grpc/ruby:v1.76.0 out: gen/proto/ruby - plugin: buf.build/protocolbuffers/ruby:v33.5 out: gen/proto/ruby - plugin: buf.build/protocolbuffers/python:v33.5 out: gen/proto/python - plugin: buf.build/grpc/python:v1.76.0 out: gen/proto/python - name: mypy out: gen/proto/python可以看到C、C#、Java、Ruby、Python 与 gRPC、mypy 桩都在同一轮buf generate中产出。虽然脚本最终只把gen/proto/python下的 Python 文件拷贝到目标模块但其他语言产物也已就绪可供服务端JVM等端侧在构建时使用。此外buf.yaml中启用了默认 lint 规则与FILE级别的 breaking change 检查用于在生成时把住协议兼容性。5.3 生成后的后处理生成并非简单拷贝dev/gen-protos.sh 还会做四类后处理以适配 PySpark 的实际包布局导入路径改写把生成的 Python 文件中的from spark.connect import ...改写为from pyspark.sql.connect.proto import ..._pb2.py与_pb2_grpc.py并把序列化描述符中的模块名从spark.connect改为pyspark.sql.connect.proto.pyi类型桩修正对*.pyi文件替换 import 与模块引用并删除typing_extensions.final装饰器行添加 Apache License 头为每个生成文件头部追加 ASF License 注释删除空 gRPC 文件如果*_grpc.py内容为空行数仅剩 20 行即 License 头等模板行则直接删除避免产生无意义的空模块。随后脚本用ruff format --config $SPARK_HOME/pyproject.toml对生成代码统一格式化最后将gen/proto/python下所有.py*文件拷贝到OUTPUT_PATH并清理临时目录。5.4 生成产物落点connect 模式的默认输出目录为python/pyspark/sql/connect/proto/。当前仓库中该目录下的产物与.proto文件一一对应例如base_pb2.py/base_pb2.pyi← 对应 base.protorelations_pb2.py/relations_pb2.pyi← 对应 relations.protoexpressions_pb2.py/expressions_pb2.pyi← 对应 expressions.protocommands_pb2.py、catalog_pb2.py、types_pb2.py、common_pb2.py、ml_pb2.py、ml_common_pb2.py、pipelines_pb2.py、example_plugins_pb2.py等均配有对应的.pyi类型桩这些文件属于自动生成产物不应手工编辑对协议的任何修改都应回到.proto源文件再通过上述两种方法之一重新生成。六、典型工作流与注意事项综合以上内容一次完整的“协议修改 → 代码重新生成”工作流如下修改sql/connect/common/src/main/protobuf/spark/connect/下的一个或多个.proto文件新增字段、消息或服务方法在仓库根目录执行docker build -t connect-cg --build-context root. dev/spark-test-image/connect-gen-protos/构建工具镜像首次或工具版本变化时执行docker run --cpus 1 -it --rm -v $(pwd):/spark connect-cg完成生成或改用本地法安装buf与mypy/mypy-protobuf/ruff版本以 pyproject.toml 为准再运行./dev/connect-gen-protos.sh检查git status确认python/pyspark/sql/connect/proto/下的*_pb2.py、*_pb2.pyi等文件已同步更新若只需临时验证可传自定义目录例如./dev/connect-gen-protos.sh /tmp/my-proto-output避免污染工作区。注意事项汇总版本锁定本地法务必以 pyproject.toml 中internal_lint组锁定的mypy、mypy-protobuf、ruff版本为准Docker 法由 Dockerfile 自动保证版本一致。Python 版本Docker 镜像内置 Python 3.12本地环境要求 Python 3.12。生成是全覆盖式的dev/gen-protos.sh 会先删除旧的gen临时目录再重新生成并整体拷贝到输出目录输出目录中的旧文件会被新文件覆盖因此不要手工混入改动。协议兼容性buf.yaml 启用了FILE级别的 breaking change 检查修改消息字段时需遵循 protobuf 的兼容性规则例如不要复用已废弃的字段号避免破坏既有客户端。七、结语Spark Connect 的协议定义集中保存在sql/connect/common/src/main/protobuf/中它是客户端与服务端通信契约的唯一事实来源。修改协议后通过 README.md 中介绍的 Docker 镜像法或本地buf法重新生成 Python 桩代码即可让 PySpark 客户端与服务端保持同步。理解背后的生成链路connect-gen-protos.sh→gen-protos.sh→buf generate→ 后处理与拷贝能让你在遇到生成异常或提交协议变更时快速定位问题也便于在 CI 中对齐工具版本、维持生成产物的可复现性。【免费下载链接】sparkApache Spark - A unified analytics engine for large-scale data processing项目地址: https://gitcode.com/gh_mirrors/sp/spark创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Sails 布局系统(Layouts)完全指南:EJS 视图布局的原理、配置与实战

Sails 布局系统(Layouts)完全指南:EJS 视图布局的原理、配置与实战

Sails 布局系统(Layouts)完全指南:EJS 视图布局的原理、配置与实战 【免费下载链接】sails Realtime MVC Framework for Node.js 项目地址: https://gitcode.com/gh_mirrors/sa/sails 导读 在 Sails(Realtime MVC Framewo…

2026/9/20 21:14:28 阅读更多 →
广东励志成长基地是什么?适合哪些孩子?广东本地有哪些正规机构?这篇一次讲清。

广东励志成长基地是什么?适合哪些孩子?广东本地有哪些正规机构?这篇一次讲清。

作为在这个行业有了解的人,简单回答一下:广东励志成长基地本质是面向青春期青少年的封闭式寄宿成长机构,核心是心理疏导 行为矫正 励志引导,不是传统意义上的管教所。广东励志成长基地,是广东省内面向青春期青少年开…

2026/9/20 21:13:28 阅读更多 →
跨境电商从零开始怎么做:新店运营环境搭建实操方案

跨境电商从零开始怎么做:新店运营环境搭建实操方案

跨境电商从零开始怎么做,第一件事不是选品,也不是找货源,而是把第一间店的运行环境搭对。选品可以边做边调,账号环境一旦从第一天就用错,后面所有操作都要在补救的基础上进行。 这篇文章按"先定平台、再搭环境、然…

2026/9/20 21:13:28 阅读更多 →

最新新闻

停在昨天源码拆解,搞定高频面试题不再卡壳

停在昨天源码拆解,搞定高频面试题不再卡壳

停在昨天源码拆解,搞定高频面试题不再卡壳 配置环境就卡半天,这是多少开发者的噩梦?明明照着文档敲,结果报了一堆错,折腾到深夜还是没跑通。更让人头大的是,很多 高频面试题…

2026/9/21 22:57:54 阅读更多 →
搞定QQ头象显示,最佳实践避坑指南

搞定QQ头象显示,最佳实践避坑指南

搞定QQ头象显示,最佳实践避坑指南 官方文档翻了三遍还是没搞懂图片加载逻辑?别急,这很正常。QQ头象看似简单,实则涉及网络请求、缓存策略、内存管理三大核心模块。很多转行嵌入式的朋友,习惯直接读源码,结果被庞大的代码量劝退。…

2026/9/21 22:57:54 阅读更多 →
2026年配音工具技术选型:四款国内轻量方案与海外API的工程化适配对比

2026年配音工具技术选型:四款国内轻量方案与海外API的工程化适配对比

做技术教程和开源项目演示这两年,配音环节换过不少工具。从自录音频到AI合成,踩过的坑涵盖长文本生成中断、多音字误读、免费版带水印、缺乏API集成接口等。前后测了十来款,结合桌面剪辑、移动端批量、程序化调用等场景,把2026年实…

2026/9/21 22:57:54 阅读更多 →
WinUtil Windows 11 系统优化完整指南:批量装软件、调优、修复、管更新一站式搞定

WinUtil Windows 11 系统优化完整指南:批量装软件、调优、修复、管更新一站式搞定

WinUtil Windows 11 系统优化完整指南:批量装软件、调优、修复、管更新一站式搞定 【免费下载链接】winutil Chris Titus Techs Windows Utility - Install Programs, Tweaks, Fixes, and Updates 项目地址: https://gitcode.com/GitHub_Trending/wi/winutil …

2026/9/21 22:57:54 阅读更多 →
DLSS Swapper 教程:3 分钟自己换掉游戏里的 DLSS 版本

DLSS Swapper 教程:3 分钟自己换掉游戏里的 DLSS 版本

DLSS Swapper 教程:3 分钟自己换掉游戏里的 DLSS 版本 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper 你肯定也遇到过:新出的 3A 大作内置的 DLSS(深度学习超级采样,NVID…

2026/9/21 22:57:54 阅读更多 →
InCharge源码拆解:告别报错堆栈,3个核心机制详解最佳实践

InCharge源码拆解:告别报错堆栈,3个核心机制详解最佳实践

InCharge源码拆解:告别报错堆栈,3个核心机制详解最佳实践 盯着屏幕上一长串红色的 java.lang.NullPointerException 或者 Unrecognized field 'incharge'…

2026/9/21 22:56:53 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →