尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Neon 源码目录结构全解析:从 compute 到 storage 的 Serverless Postgres 代码地图

Neon 源码目录结构全解析:从 compute 到 storage 的 Serverless Postgres 代码地图 Neon 源码目录结构全解析从 compute 到 storage 的 Serverless Postgres 代码地图【免费下载链接】neonNeon: Serverless Postgres. We separated storage and compute to offer autoscaling, code-like database branching, and scale to zero.项目地址: https://gitcode.com/GitHub_Trending/ne/neon本文以 docs/sourcetree.md 为骨架逐层拆解 NeonServerless Postgres仓库的源码树布局每一个核心子目录承担什么职责、与计算/存储分离架构的关系、以及如何围绕这份目录展开日常开发——包括 Rust 依赖管理cargo-hakari、Cargo deny 安全审计、Python/poetry 测试环境搭建和 CLion 调试工程配置。读完本文你将能在这份庞大仓库中快速定位到任一模块的源码、测试与配置并具备直接上手开发的最小操作路径。目录总览一个仓库三种语言一条完整的计算-存储分离链路Neon 将 PostgreSQL 的计算与存储分离计算节点Compute Node负责执行 SQL存储层由 pageserver、safekeeper 与 storage_broker 等组件组成。源码树的每个子目录都对应这条链路上的一个环节同时混编了 Rust核心服务、CPostgreSQL 扩展、Python集成测试三种语言。从仓库根目录的 Cargo.toml 可以看到Rust workspace 当前共包含 40 余个 crate覆盖compute_tools、control_plane、pageserver、proxy、safekeeper、storage_broker、storage_controller、storage_scrubber以及libs/下大量共享库。下面按字母序逐目录说明其定位。storage_broker存储节点之间的无状态消息中枢storage_broker 是 Neon 存储 broker为 safekeeper 与 pageserver 提供消息传递能力。它要解决两个核心问题详见 docs/storage_broker.md让 safekeeper 与 pageserver 互相感知谁持有哪些 timeline、这些 timeline 的最新状态避免存储节点之间建立 O(n²) 的全互联连接。broker 被谁使用pageserver 通过它确定最先进且存活的 safekeeper 以拉取 WALsafekeeper 通过它同步 timeline 状态——推进remote_consistent_lsn、backup_lsn以及决定由谁把 WAL 卸载到 S3。从技术上它是一个基于 tonicgRPC的无状态 pub-sub 消息 broker。由于无状态故障转移可交由 Kubernetes 完成源码中虽未内置复制机制但实现上并不难扩展。gRPC 服务定义见 storage_broker/proto/broker.proto核心 RPC 有四个SubscribeSafekeeperInfo订阅 safekeeper 状态更新可订阅全部或指定 timelinePublishSafekeeperInfosafekeeper 以流式方式推送自己的 timeline 状态SubscribeByFilter按消息类型 tenant/timeline 过滤订阅PublishOne发布单条消息。目前最主要的消息类型是SafekeeperTimelineInfo每个 safekeeper 会定期为每个活跃 timeline 推送状态其中包含term、last_log_term、flush_lsn、commit_lsn、backup_lsn、remote_consistent_lsn、safekeeper_connstr、http_connstr以及可选的availability_zone等字段。broker 在 gRPC 服务的同一端口上还提供/metrics。客户端连接细节默认监听地址为127.0.0.1:50051见 storage_broker/src/lib.rs默认 keepalive 间隔 5000ms、连接超时 5s。连接是懒加载的——首次请求才真正建连若 endpoint 以https://开头会自动启用 TLS。调试技巧可以用 grpcurl 直接查看当前被推送的值grpcurl -proto broker/proto/broker.proto -d {all:{}} -plaintext localhost:50051 storage_broker.BrokerService/SubscribeSafekeeperInfostorage_controller管理 pageserver 集群与多分片租户storage_controller 是 Neon storage controller负责管理一组 pageserver并向外部暴露统一 API使一个被切成多个 shard 的租户many-sharded tenant可以被当作单一实体来管理。它与 broker 的分工不同broker 解决节点间信息分发controller 解决集群编排、租户分片与节点调度。control_plane本地控制平面/control_plane 是本地控制平面提供启动、配置、停止以本地进程方式运行的 pageserver 与 postgres 实例的功能主要服务于集成测试和本地安装的 CLI 工具。从源码看control_plane/src/lib.rs它内部按组件拆分为多个模块background_process后台进程管理、endpoint计算节点端点、local_env本地环境布局、pageserver、safekeeper、postgresql_confPostgreSQL 配置生成与storage_controller。以 pageserver 为例control_plane/src/pageserver.rs 中的start()即负责在本地拉起一个 pageserver 进程这正是测试夹具如 test_runner/fixtures/pageserver的底层实现基础。docs特性与概念文档/docs 存放 Neon 特性与概念的文档目前主要是面向开发者的文档。它与本篇文章直接相关的重要主题文档包括docs/pageserver-services.mdpageserver 内部各服务线程Page Service、WAL Receiver、Backup Service 等的架构说明docs/walservice.mdWAL servicesafekeeper 集群的整体设计docs/storage_broker.md上文 broker 的详细说明docs/safekeeper-protocol.mdsafekeeper 共识协议的详细描述。pageserverNeon 存储服务/pageserver 是 Neon 的存储服务storage service承担多项职责见 docs/sourcetree.md 与 docs/pageserver-services.md存储并管理数据生成用于引导 ComputeNode 的 tarball响应来自 Compute Node 的GetPageLSN请求从 WAL service 接收 WAL 并解码重放适用于 pageserver 所维护 chunk 的 WAL。其内部由多个线程/服务组成Page Service监听来自计算节点的 GetPageLSN 请求每个连接一个线程使用 libpq 协议通信WAL Receiver使用 PostgreSQL 物理流复制协议连接 safekeeper 并持续接收 WALBackup Service负责把恢复数据外置到远程存储目前支持本地文件系统、AWS S3、Azure且默认关闭可通过remote_storage配置开启。pageserver 的核心抽象是Repositorytrait见 docs/pageserver-services.md每个租户一个 Repository存放在.neon/tenants/tenant_id目录下。每个 Repository 内含多个 Timeline与 PostgreSQL WAL timeline 无关更接近分支 branch的概念与 branch 一一对应。此外还有 WAL redo manager它通过一个运行在 Neon 特殊 wal-redo 模式下的 Postgres 进程来重放 WAL 记录。proxyPostgres 协议代理/路由器/proxy 是 Postgres 协议代理/路由器监听 psql 端口可通过外部服务校验认证并创建新的数据库与账户在本项目中即 control plane API。它面向 serverless 场景承担连接路由、认证转发与计算节点调度入口的角色。test_runner基于 pytest 的集成测试/test_runner 存放用 Python 编写、基于 pytest 框架的集成测试。测试覆盖端到端链路fixtures/中封装了 pageserver、safekeeper、endpoint 的测试夹具如 test_runner/fixtures/neon_fixtures.pyregress/下有大量回归测试performance/下则包含 TPC-H、pgvector、large_synthetic_oltp 等性能测试另有logical_repl/、cloud_regress/、sql_regress/等专题测试目录。vendor/postgres-v14 与 vendor/postgres-v15定制化 PostgreSQL 源码/vendor/postgres-v14和/vendor/postgres-v15是各版本 PostgreSQL 源码树附带 Neon 所需的修改。当前仓库根目录 Makefile 中POSTGRES_VERSIONS v17 v16 v15 v14即 Neon 目前支持在 PostgreSQL 14 到 17 上构建运行构建产物默认安装到pg_install/编译参数由 postgres.mk 引入。pgxn/neon核心存储管理扩展/pgxn/neon 是 PostgreSQL 扩展实现了存储管理器 APIstorage manager API以及与远程 pageserver 的网络通信。它位于计算节点内部负责把 PostgreSQL 的页面读写请求转译为对远端 pageserver 的GetPageLSN调用并承载 WAL 提议walproposer等能力。扩展的核心 C 源文件包括 pgxn/neon/neon.c、pgxn/neon/libpagestore.c、pgxn/neon/walproposer.c 等扩展版本升级脚本以neon--1.0.sql、neon--1.x--1.y.sql的形式维护在 pgxn/neon/ 目录中。pgxn/neon_test_utils测试与调试专用扩展/pgxn/neon_test_utils 是包含测试与调试所需函数的 PostgreSQL 扩展其 SQL 定义见 pgxn/neon_test_utils/neon_test_utils--1.3.sql实现位于 pgxn/neon_test_utils/neontest.c。这类测试专用扩展模式允许在不污染生产代码的前提下注入故障、观测内部状态。pgxn/neon_walredopageserver 内的 WAL 重放进程库/pgxn/neon_walredo 是将 Postgres 作为 pageserver 中WAL redo process运行的库。pageserver 需要按需把 WAL 重放成页面版本以满足 GetPageLSN这个重放过程就交给一个以特殊模式启动的 Postgres 进程pgxn/neon_walredo/walredoproc.cpageserver 通过管道与其通信。safekeeperWAL 服务接收与分发中心/safekeeper 是 Neon 的 WAL service从主计算节点接收 WAL再流式传给 pageserver。正如 docs/walservice.md 所描述它充当近期生成 WAL 的暂存区与再分发中心。架构要点主 Postgres 把 WAL 流式推送给 safekeeper并把它当作同步副本对待主节点使用复制槽防止在 WAL 尚未送达 WAL service 前就将其丢弃数据流为Compute node → WAL Service多个 safekeeper→ Pageserver一条 WAL 记录只有当多数派 safekeeper收到并落盘后才算持久化基于Paxos的共识算法管理 quorum并保证任意时刻只有一个主节点在向 quorum 推送 WAL主节点采用push方式连接 safekeeper这与传统流复制中副本主动发起连接不同负责推送的组件叫WAL proposer是运行在主 Postgres 中的后台进程实现见 pgxn/neon/walproposer.cpageserver 使用 Postgres 主备之间相同的流复制协议连接 safekeeper 拉取 WAL测试场景下也可让 pageserver 直连主 PostgreSQL。关于为什么要单独的 WAL servicepageserver 是可能丢失的单点而 Neon 主容错存储是 S3不希望事务提交被 pageserver 阻塞。WAL service 充当近期数据的临时容错存储待 WAL 与页面写入 S3 后即可裁剪trim。共识算法的形式化规格见 safekeeper/spec/ 下的 TLA 规范文件。workspace_hack 与 libs依赖固定与共享库/workspace_hack 这个 crate 只用于固定pin down部分依赖自动化工具是 cargo-hakari。其作用是统一 workspace 中所有 crate 的依赖特性组合避免因特性在不同 crate 间不一致导致重复编译。/libs 把多个粒度较小的 Neon 辅助 crate 聚合在一个屋檐下包括均为 workspace 成员见 Cargo.toml/libs/postgres_ffi与 PostgreSQL 文件格式交互的实用函数内含从 PostgreSQL 头文件复制来的常量/libs/utils在仓库内其他 crate 间共享的通用辅助代码未来有进一步模块化的空间/libs/metrics帮助服务器暴露 Prometheus 指标此外还有pageserver_api、safekeeper_api、compute_api、walproposer、wal_decoder、remote_storage、postgres_backend、pq_proto、http-utils、tracing-utils、tenant_size_model等共同支撑各服务的 RPC 定义、WAL 解析、远端存储抽象等基础能力。开发工作流Rust 依赖管理、安全审计与构建添加 Rust 依赖同步 hakari manifest当你新增一个 Cargo 依赖时需要运行以下命令并提交更新后的Cargo.lock与workspace_hack/可能没有变化这也没关系cargo hakari generate cargo hakari manage-deps如果尚未安装 hakari出现error: no such subcommand: hakari先安装cargo install cargo-hakari审计第三方 Rust 依赖Neon 使用 Cargo deny 检查依赖图是否符合要求——检测安全漏洞、匹配许可证并确保 crate 只来自受信任来源cargo deny check整体构建仓库根目录的 Makefile 提供了make一站式构建入口all目标 neonpostgres-installneon-pg-ext默认BUILD_TYPEdebug可用BUILD_TYPErelease切换PostgreSQL 各版本扩展通过neon-pg-ext-version目标编译安装。使用 Python测试环境与强制检查由于 Debian/Ubuntu 自带的 Python 包普遍过旧官方不建议手动安装依赖而是用一个统一的虚拟环境描述在 pyproject.toml 中poetry 管理package-mode false。前置条件安装Python 3.11最低支持版本或更高版本。poetry 配置同样兼容更新版本如果遇到问题可单独安装 Python 3.11# Ubuntu 示例 sudo add-apt-repository ppa:deadsnakes/ppa sudo apt update sudo apt install python3.11安装poetry对精确版本不敏感按官方文档安装即可。通过./scripts/pysync安装依赖注意 CI 使用特定 Python 版本本地版本不同可能导致部分 lint 工具结果与 CI 有差异可用poetry env use /path/to/python指定解释器例如poetry env use python3.11。激活虚拟环境poetry shell或单次运行poetry run pytest强制检查ruff mypy项目强制用ruff统一格式、用mypy保证类型标注。在仓库根目录紧挨pyproject.toml运行poetry run ruff format . # 格式化所有代码 poetry run ruff check . # Python 语法检查 poetry run mypy . # 确保没有类型错误警告不要从仓库根目录以外的目录运行mypy否则它找不到配置文件pyproject.toml 中配置了mypy_path与strict true并针对_jsonnet、asyncpg、pg8000等模块做了ignore_missing_imports覆盖。另外可考虑运行pycodestyle或你喜欢的 linter修复潜在缺陷并补充类型标注以避免Any。变更 Python 依赖新增或修改包时可用poetry add、poetry update或直接编辑pyproject.toml后者记得运行poetry lock更新锁文件。更多细节参考 poetry 官方文档。配置 IDE以 CLion 为例Neon 由三种语言、三种项目模型构成根 Cargo.toml 下的多个 Rust crate、test_runner目录下的 Python 集成测试、以及基于 Makefile 用 C 构建的 Postgres 扩展vendor/postgres*与pgxn。这里以 CLion 为例说明配置方法。使用 Rust 插件CLion 配合 Rust 插件打开 Neon 仓库即可同时识别 Rust 与 Python 工程官方未尝试配置调试器。为 C 代码生成编译数据库C 代码通过 Make而非 CMake构建需借助compilation database一个列出所有 C 源文件及编译参数的 JSON 文件让 CLion 理解工程克隆 Neon 仓库并安装全部依赖含 Python先不要用 CLion 打开在仓库根目录执行# 安装 compiledb 工具解析 make 输出并生成编译数据库 poetry add -D compiledb # 清理构建树以便全量重建Makefile 与 --dry-run/--assume-new 兼容不佳 # 生成编译数据库目前只能完整重编译一次 make distclean # 全量重建 Postgres 部分并把编译命令存入编译数据库-j 参数可按需调整 make -j$(nproc) --print-directory postgres-v15 neon-pg-ext-v15 | poetry run compiledb --verbose --no-build # 卸载工具 poetry remove -D compiledb # 确保 compile_commands.json 不被提交 echo /compile_commands.json .git/info/exclude在 CLion 中Open File or Project选择生成的compile_commands.json作为项目打开编译数据库不能加入已有 CLion 工程且不要打开目录要打开该文件项目开始索引 C 源码与 C 标准库后可能需要为编译数据库配置 C 编译器在同一工程内用编辑器打开根Cargo.tomlCLion 会提示并开始索引 Rust 代码这样你就有了一个同时认识 C 文件、Rust 文件并自动识别 Python 文件的 CLion 工程在 CLion 设置中配置缩进Editor Code Style C/C顶部 scheme 选 Project在 Tabs and Indents 勾选 Use tab characterTab size 设为 4。你还可以开启 Cargo Clippy 诊断、用 Rustfmt 替代内置格式化器。当 C 文件布局变化时只需重新生成编译数据库无需重建 CLion 工程。已知问题CLion 中测试结果Rust 单元测试与 Python 集成测试可读性较差建议改用命令行运行CLion 不支持非本地 Python 解释器不同于 PyCharm例如 WSL 环境下 CLion 看不到poetry与已装依赖Python 支持受限CLion 中的 Cargo Clippy 诊断可能占用较多资源poetry add -D即使随后poetry remove -D也会大幅改动poetry.lock可用git checkout poetry.lock配合./scripts/pysync还原。结语一张地图三条主线回顾整棵源码树可以归纳出三条开发主线存储链路storage_broker信息分发→storage_controller集群编排→pageserver数据落地与页面服务→safekeeperWAL 暂存与共识→libs/walproposer、libs/wal_decoder、libs/remote_storage底层支撑计算链路pgxn/neon存储管理器扩展→pgxn/neon_walredo重放进程→compute_tools计算节点管理→proxy连接路由与认证工程支撑control_plane本地编排、test_runnerpytest 集成测试、workspace_hacklibs/依赖固定与共享库、docs/架构文档。无论你是要定位某个 WAL 记录的处理路径、为扩展新增一个 SQL 函数还是要搭建本地测试环境都可以从这张目录地图出发顺着对应的 crate 与文档继续深入。而本仓库各子目录间的协作关系也可以进一步在 docs/pageserver-services.md、docs/walservice.md 与 docs/storage_broker.md 中获得更完整的架构视角。【免费下载链接】neonNeon: Serverless Postgres. We separated storage and compute to offer autoscaling, code-like database branching, and scale to zero.项目地址: https://gitcode.com/GitHub_Trending/ne/neon创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表