ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Neon Compute Tools 实战指南:compute_ctl 计算节点启动流程、状态机与运维详解

Neon Compute Tools 实战指南:compute_ctl 计算节点启动流程、状态机与运维详解 Neon Compute Tools 实战指南compute_ctl 计算节点启动流程、状态机与运维详解【免费下载链接】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导读compute_tools是 Neon 开源仓库中负责计算节点compute node这一侧的完整工具集其核心二进制compute_ctl是一个用 Rust 编写的 Postgres 包装器wrapper通常作为 Docker 容器 entrypoint 或 systemdExecStart运行负责在 Neon 存算分离架构下完成计算节点从空目录到可对外服务的全部初始化工作。本文将基于 compute_tools/README.md 为主体结合 compute_tools/src 目录下的源码实现系统讲解compute_ctl的启动流程、命令行参数、后台服务线程、HTTP API、自动伸缩autoscaling集成、状态机以及测试与跨平台编译方法帮助你从能用进阶到理解其内部机制。compute_ctl 的定位与运行形态在 Neon 的存算分离架构中Postgres 作为计算节点与存储层pageserver分离每次启动计算节点都是一次从零开始的全新启动。compute_ctl就是为了管理这一过程而生的它以 JSON 文件形式接收集群计算节点规格说明compute spec每次启动都是全新启动数据目录会被删除并重新初始化它负责与 safekeeper、pageserver 通信把 Postgres 引导到正确的时间线timeline上它启动 Postgres、创建角色和数据库并最终挂起等待 postmaster 退出。从 compute_tools/Cargo.toml 可以看到compute_tools是一个独立 Cargo 包compute_toolsv0.1.0依赖了compute_api、vm_monitor、remote_storage、postgres_initdb、pageserver_page_api等工作区内部库以及clap命令行解析、tokio、axum、hyperHTTP 服务等通用依赖这决定了其功能边界既要与 Neon 控制平面/存储层通信又要对本地 Postgres 做进程级管理。compute_ctl 的启动与初始化流程按 README 的描述compute_ctl在计算节点初始化期间处理所有 Neon 特有的工作完整流程如下接受集群计算节点规格说明cluster/compute spec规格以 JSON 文件形式给出每次启动都是全新启动fresh start因此每次运行都会删除并重新初始化数据目录把配置文件写入PGDATA目录同步 safekeeper 并取得 commit LSN使用上一步返回的 LSN 从 pageserver 拉取basebackup尝试启动postgres并等待其就绪、可以接受连接检查并alter/drop/create角色与数据库挂起hang等待postmaster进程退出。上述流程在源码中对应 compute.rs 中ComputeNode的启动逻辑其中第 4、5 步的同步 safekeeper 并取得 LSN由 sync_sk.rs 的check_if_synced/ping_safekeeper实现basebackup 通过pageserver_page_apilibs/pageserver_api的页服务客户端从 pageserver 获取且支持压缩BaseBackupCompression。需要特别说明的是这是一个无状态的启动模型——数据不保存在本地而是全部从存储层重建这正是 Neon scale to zero 能力的基础计算节点可以被随时销毁下次启动时通过 safekeeper 的 LSN 与 pageserver 的 basebackup 恢复到一致状态。spec 从哪来控制平面 API 或本地文件README 中的示例使用-S /var/db/postgres/specs/current.json直接指定本地的 spec 文件。从当前源码 compute_ctl.rs 看compute_ctl还支持通过-p/--control-plane-uri与-i/--compute-id从 Neon 控制平面拉取 specspec.rs 中get_config_from_control_plane()会请求{base_uri}/compute/api/v2/computes/{compute_id}/spec携带NEON_CONTROL_PLANE_TOKEN环境变量作为Authorization: Bearer头请求采用最多 3 次尝试的重试逻辑网络错误、503服务暂不可用、502 会重试其他状态码如 404、500则直接失败不重试控制平面返回Empty状态表示还没有 speccompute_ctl会进入等待状态。无论 spec 来自本地文件还是控制平面最终都会解析为 compute.rs 中的ParsedSpec其中包含tenant_id、timeline_id、pageserver_conninfo、safekeeper_connstrings等关键信息。对于旧版本控制平面生成的 specParsedSpec::try_from还支持从pageserver_connstring字段或cluster.settings中的 GUC如neon.pageserver_connstring、neon.tenant_id、neon.timeline_id反向推导连接信息保持了向后兼容。命令行参数详解README 给出的典型用法compute_ctl -D /var/db/postgres/compute \ -C postgresql://cloud_adminlocalhost/postgres \ -S /var/db/postgres/specs/current.json \ -b /usr/local/bin/postgres各参数含义参数含义-D/--pgdataPostgres 数据目录路径PGDATA每次启动会被清空重建-C/--connstr连接 Postgres 的连接串cloud_admin是 Neon 的超级用户角色-S集群计算节点spec 的 JSON 文件路径-b/--pgbinpostgres可执行文件路径默认值postgres也可用环境变量POSTGRES_PATH覆盖结合当前源码 compute_ctl.rs 的Cli结构基于clap派生compute_ctl实际支持的参数远不止上述四个整理如下参数默认值说明-b, --pgbinpostgresenvPOSTGRES_PATHPostgres 可执行文件路径-r, --remote-ext-base-url无远程扩展存储代理网关extension storage proxy gateway的基础 URL用于按需下载扩展--external-http-port3080外部 HTTP 服务器端口控制平面、metrics 抓取器等通过它访问 compute--internal-http-port3081内部 HTTP 服务器端口供 compute 内进程neon 扩展、local_proxy使用--http-port无Hadron 部署的向后兼容参数功能等同--external-http-port内部端口自动 1-D, --pgdata必填数据目录-C, --connstr必填连接串--privileged-role-nameneon_superuser弱超级用户角色名只能由小写字母与下划线组成有正则校验--cgroupLinuxneon-postgres自动伸缩场景下 postgres 所在的 cgroup 名称--filecache-connstrLinuxhostlocalhost port5432 ... usercloud_admin连接 Postgres 供 vm-monitor 文件缓存使用的连接串--vm-monitor-addrLinux0.0.0.0:10301vm-monitor 监听地址--resize-swap-on-bindfalse绑定阶段是否调整 swap 大小--set-disk-quota-for-fs无为指定文件系统设置磁盘配额-c, --config无本地配置文件spec路径与-p互斥-i, --compute-id必填compute 的唯一 ID-p, --control-plane-uri无控制平面 API 基础 URL指定后从控制平面拉取 spec要求同时提供-i--installed-extensions-collection-interval3600秒已安装扩展统计的采集间隔--devfalse开发模式跳过 VM 特有操作如进程终止--pg-init-timeout无Init 状态下的 Postgres 启动超时--lakebase-modefalseDatabricks lakebase 部署模式Hadron 相关关键解读-C指定的连接串会在ComputeNode::new()compute.rs中被附加一组额外的 GUC 选项-c rolecloud_admin -c default_transaction_read_onlyoff -c search_path -c statement_timeout0 -c pgaudit.lognone。原因是用户可能通过ALTER DATABASE ... SET ...设置了statement_timeout、default_transaction_read_only等参数会阻碍compute_ctl对数据库 schema 的配置因此必须在连接前强制重置控制平面提供的选项会被追加在后面允许覆盖。在 Linux 设置了AUTOSCALING环境变量的情况下compute.rs 的maybe_cgexec()会使用cgexec -g memory:neon-postgres启动 postgres使其运行在neon-postgrescgroup 中从而允许自动伸缩系统精确控制 postgres 的资源占用。两个核心服务线程compute-monitor 与 http-endpointREADME 指出compute_ctl除了主流程外还会派生两个独立服务线程compute-monitor检查 Postgres 的最后活动时间戳last activity timestamp并将其写入共享的ComputeNode状态http-endpoint运行一个基于 Hyper 的 HTTP API 服务器提供就绪readiness与最近活动last activity查询。compute-monitor 的检测原理实现位于 monitor.rs。launch_monitor()会启动一个名为compute-monitor的线程以500msMONITOR_CHECK_INTERVAL为周期循环执行其活动检测逻辑check()依次检查数据库统计变化实验性检测受ActivityMonitorExperimental特性开关控制对pg_stat_database求和active_time、sessions排除postgres、template0、template1任一指标变化即视为有活动后端状态变化查询pg_stat_activity中client backend类型的连接排除自身与cloud_admin若存在非idle后端则最后活动现在若都是idle取state_change时间戳的最大值walsender 数量select count(*) from pg_stat_replication where application_name ! walproposer有 walsender 则不挂起逻辑复制订阅pg_stat_subscription中pid is not null的订阅存在则不挂起autovacuum workerpg_stat_activity中backend_type autovacuum worker存在则不挂起。这些不应挂起的例外检测非常关键monitor 的目的本质上是为 scale-to-zero 决策提供依据——如果存在复制、订阅或后台任务compute 就不应该被自动关闭。同时 monitor 还维护两个 Prometheus 指标PG_CURR_DOWNTIME_MS当前停机时长与PG_TOTAL_DOWNTIME_MS累计停机时长并在 compute 处于Terminated/TerminationPendingFast/TerminationPendingImmediate/Failed等终态时优雅退出。另外monitor 在等待 Postgres 进入Running状态时受pg_init_timeout约束默认 60 秒若超时仍未进入 Running例如用错误的 spec 启动、连上了错误的 pageserver/safekeeper会直接exit(1)让计算节点重启以便用最新 spec 重试见 monitor.rs。http-endpoint内部与外部两套 HTTP APIcompute_ctl实际启动的是两个Hyper/axum HTTP 服务器见 http/server.rs外部服务器默认端口 3080面向控制平面、metrics 抓取器路由包括/status、/configure、/refresh_configuration、/terminate、/promote、/metrics、/check_writability、/hadron_liveness_probe等内部服务器默认端口 3081只绑定 loopback仅对 compute 内的进程Postgres neon 扩展、local_proxy开放路由包括/extension_server/{*filename}下载扩展、/extensions安装扩展、/grants、/refresh_configuration。各路由实现位于 compute_tools/src/http/routesstatus.rsGET /status加锁读取共享ComputeState并序列化为ComputeStatusResponse返回实现 README 所述就绪与最后活动查询configure.rsPOST /configure接收 JSON 格式的ConfigurationRequest解析为ParsedSpec后写入共享状态、置为ConfigurationPending再阻塞等待 compute 变为Running若失败则返回 500 及错误信息这也是状态机中Running → ConfigurationPending的触发入口terminate.rs、promote.rs、refresh_configuration.rs分别对应终止、提升灾备切换与热刷新配置。ComputeStatecompute.rs是跨线程共享的核心结构status当前状态、last_active最后活动时间、error、pspec当前 spec等字段都在Mutex保护之下配合Condvar实现状态变更通知每次set_status()都会更新COMPUTE_CTL_UP指标便于监控系统追踪当前状态。AUTOSCALING 环境变量与 vm-monitorREADME 明确指出如果设置了AUTOSCALING环境变量compute_ctl会启动位于libs/vm_monitor的 vm-monitor。对于 VM 计算节点vm-monitor 与 VM 自动伸缩系统通信协调降级downscaling并在资源紧张时请求立即升级upscaling。从 compute_ctl.rs 可见autoscaling 模式下涉及三个关键参数--cgrouppostgres 所在 cgroup默认neon-postgres、--filecache-connstrvm-monitor 连接 Postgres 用于文件缓存管理的连接串、--vm-monitor-addr默认0.0.0.0:10301。vm-monitor 本体是工作区独立库位于 libs/vm_monitor在compute_tools的依赖声明Cargo.toml中通过path ../libs/vm_monitor/引入。其角色可以概括为作为 compute 内部与外部自动伸缩系统之间的资源代言人——平时配合 scale-to-zero 观察资源利用率以推动降级当 Postgres 在 cgroup 层面出现内存/CPU 压力时则向上请求升级从而让 Neon 的计算节点在最小可用资源与峰值需求之间动态调整。计算节点状态机State DiagramREADME 附带的 mermaid 状态图完整描述了 compute 在compute_ctl管理下的生命周期。该状态机在源码中的落地形态即ComputeStatus见 compute.rs 的set_status()/set_failed_status()与COMPUTE_CTL_UP指标下面完整保留原图对关键状态的解读Emptycompute 进程刚被拉起尚无任何 specConfigurationPending / Configuration已收到或正在拉取spec进入配置阶段——对应 README 启动流程的第 25 步清空数据目录、写配置、同步 safekeeper、拉 basebackupInitspec 立即可用时直接从 Empty 进入对应启动 Postgres 并等待就绪阶段若失败进入FailedRunning配置完成、Postgres 可接受连接这是稳态RefreshConfigurationPending / RefreshConfiguration运行中收到/refresh_configuration请求拉取新 spec 并热重配置如变更实例规格、GUC 参数失败会回到RefreshConfigurationPending重试TerminationPendingFast / TerminationPendingImmediate收到终止请求Fast 模式会保留 30 秒让控制平面检查状态Immediate 立即终止随后进入Terminated并退出进程Failed任何阶段配置失败都会进入仍可通过/refresh_configuration请求尝试恢复或者进程直接退出。从代码实现看两个终止路径的差异也体现在 monitor 的退出逻辑中monitor.rsmonitor 一旦发现 compute 进入这四个终态之一便停止活动检测、优雅退出。测试与代码质量README 给出了开发compute_tools时常用的三个命令原样保留并补充说明# 1. Cargo 格式化 cargo fmt # 2. 运行测试 cargo test # 3. Clippy 静态检查将警告视为错误 cargo clippy --all --all-targets -- -Dwarnings -Drust-2018-idioms仓库中已存在的测试包括 compute_tools/tests/config_test.rs 与 compute_tools/tests/pg_helpers_tests.rs前者针对配置解析/生成逻辑后者针对 Postgres 辅助函数。此外compute_tools的testingfeaturetesting [fail/failpoints]会启用 failpoint 支持便于在 compute_ctl.rs 的单元测试中注入故障场景例如模拟不同 spec 组合下的--pgdata/--connstr解析。同时 Cargo.toml 中#![deny(unsafe_code)]见 lib.rs表明整个 crate 禁用 unsafe 代码这也解释了 clippy 检查为什么对代码风格如此严格。跨平台编译从 macOS 交叉编译 Linux GNU 可执行文件README 提供了两种从 macOSx86交叉编译 Linux GNURust 术语中的x86_64-unknown-linux-gnu平台可执行文件的方法这是 CI 或本地构建 compute 镜像时的常见需求。方式一使用一次性 Docker 容器使用官方 rustlang/rust或rust镜像把当前目录挂载进去编译docker run --rm \ -v $(pwd):/compute_tools \ -w /compute_tools \ -t rustlang/rust:nightly cargo build --release --targetx86_64-unknown-linux-gnu或者一行版docker run --rm -v $(pwd):/compute_tools -w /compute_tools -t rust:latest cargo build --release --targetx86_64-unknown-linux-gnu方式二Rust 原生交叉编译在宿主机上添加目标平台并安装 macOS 交叉编译工具链# 添加编译目标 rustup target add x86_64-unknown-linux-gnu # 安装 macOS 交叉编译器工具链 brew tap SergioBenitez/osxct brew install x86_64-unknown-linux-gnu最后通过CARGO_TARGET_*环境变量指定链接器后构建CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKERx86_64-unknown-linux-gnu-gcc cargo build --targetx86_64-unknown-linux-gnu --release注意事项compute_tools依赖链中包含 Linux 平台专用代码例如 compute.rs 中#[cfg(target_os linux)]的 filecache/cgroup/vm-monitor 参数、nix系统调用、rlimit等因此 README 提供的两种交叉编译方案目标明确针对 Linux 部署环境本机macOS开发时这些平台相关字段会被cfg条件编译剔除不影响本地cargo test与cargo clippy的正常使用。总结compute_ctl是 Neon 存算分离架构在计算节点侧的总调度器它把清空数据目录 → 同步 safekeeper 取 LSN → 从 pageserver 拉 basebackup → 启动 Postgres → 配置角色/数据库 → 挂起等待这一整套无状态启动流程自动化并通过 compute-monitor 与内部/外部两套 HTTP API 支撑起 scale-to-zero、自动伸缩与动态重配置能力。README 中的状态机图则是对这一整套生命周期的权威抽象——无论是排查Failed、理解/configure热更新还是调试终止流程都可以从这张图出发在 compute.rs、monitor.rs 与 compute_tools/src/http/routes 中找到对应的代码实现。【免费下载链接】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),仅供参考
返回列表