十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Neon 本地开发环境完全指南:从零搭建 Serverless Postgres 的 compute-storage 分离架构

Neon 本地开发环境完全指南:从零搭建 Serverless Postgres 的 compute-storage 分离架构 Neon 本地开发环境完全指南从零搭建 Serverless Postgres 的 compute-storage 分离架构【免费下载链接】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/neonNeon 是开源的 serverless Postgres 数据库平台其核心思路是把存储与计算彻底分离计算节点是无状态的 PostgreSQL而存储引擎由 pageserver 与 safekeepers 组成将数据重新分布在集群节点之上。本文以仓库根目录 README.md 为骨架结合 control_plane 控制面源码与 Makefile 构建脚本完整讲解如何在 Linux 与 macOS 上从依赖安装、源码构建到本地启动数据库、创建分支并运行测试的全过程帮助你快速搭起一套可复现的 Neon 本地开发环境并理解其架构与命令行工具的设计意图。一、架构概览compute 与 storage 分离一个 Neon 安装由两类角色构成Compute 节点无状态的 PostgreSQL 节点其数据全部由 Neon 存储引擎支撑因而可以随时创建、销毁和弹性伸缩。Neon 存储引擎由两个核心组件组成Pageserver为 compute 节点提供可扩展的存储后端负责存储与管理数据、响应来自 compute 节点的 GetPageLSN 请求、接收并解码 WAL并将 WAL 重放到自身维护的 chunk 中。Safekeepers构成冗余的 WAL 服务从 compute 节点接收 WAL 并持久化保存直到 WAL 被 pageserver 处理并上传到云存储为止。从源码结构可以印证这一分工见 docs/sourcetree.md/pageserver是 Neon 存储服务Neon storage service/safekeeper是 WAL 服务接收主 compute 的 WAL 并流转给 pageserver/proxy是 Postgres 协议代理/路由器/pgxn/neon则是实现了存储管理器 API 并与远端 pageserver 通信的 PostgreSQL 扩展。Safekeepers 与 pageserver 之间的消息传递则由storage_broker负责。更详细的开发者文档见 docs/SUMMARY.md 中的各篇文档例如 walservice.md 与 pageserver-services.md。二、安装构建依赖Neon 由 Rust 与打了补丁的 PostgreSQL仓库中通过vendor/postgres-*与compute/patches/维护共同构成因此依赖较多。以下分别给出 Linux 与 macOS 的安装清单。LinuxUbuntu / Debianapt install build-essential libtool libreadline-dev zlib1g-dev flex bison libseccomp-dev \ libssl-dev clang pkg-config libpq-dev cmake postgresql-client protobuf-compiler \ libprotobuf-dev libcurl4-openssl-dev openssl python3-poetry lsof libicu-devFedoradnf install flex bison readline-devel zlib-devel openssl-devel \ libseccomp-devel perl clang cmake postgresql postgresql-contrib protobuf-compiler \ protobuf-devel libcurl-devel openssl poetry lsof libicu-devel libpq-devel python3-devel \ libffi-develArchpacman -S base-devel readline zlib libseccomp openssl clang \ postgresql-libs cmake postgresql protobuf curl lsof注意构建 Neon 要求protocprotobuf-compiler版本不低于 3.15。如果你的发行版自带版本过旧需要自行安装更新版本。从 Makefile 可以看到这些依赖对应的构建行为Linux 下默认会为 PostgreSQL 追加--with-libseccompseccomp BPF 仅 Linux 可用而 macOS 下则会追加-DUSE_PREFETCH并借助 Homebrew 的 openssl3、icu4c、bison、flex 显式覆盖系统自带的旧版本。macOS12.3.1xcode-select --install brew install protobuf openssl flex bison icu4c pkg-config m4 # add openssl to PATH, required for ed25519 keys generation in neon_local echo export PATH$(brew --prefix openssl)/bin:$PATH ~/.zshrc如果出现缺少m4的错误brew install m4 brew link --force m4随后安装 Rustcurl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh并安装 PostgreSQL 客户端仅 psqlbrew install libpq brew link --force libpqRustc 版本约束项目通过根目录的 rust-toolchain.toml 固定构建所用的工具链版本[toolchain] channel 1.88.0 profile default components [llvm-tools, rustfmt, clippy]该文件会被rustup自动识别rustup 会按需安装并使用其中固定的工具链版本。使用 rustup 的开发者若想改用其他工具链可以在项目目录执行rustup override指定不使用 rustup 的用户则需要手动核对本机工具链与文件中的版本一致。较新的 rustc 通常可以正常工作但较旧的版本可能因项目或依赖 crate 用到的新特性而不受支持。三、构建 Neon 与打过补丁的 PostgreSQLLinux 构建# Note: The path to the neon sources can not contain a space. git clone --recursive https://github.com/neondatabase/neon.git cd neon # The preferred and default is to make a debug build. This will create a # demonstrably slower build than a release build. For a release build, # use BUILD_TYPErelease make -jnproc -s # Remove -s for the verbose build log make -jnproc -smacOS 构建# Note: The path to the neon sources can not contain a space. git clone --recursive https://github.com/neondatabase/neon.git cd neon # For a release build, use BUILD_TYPErelease make -jsysctl -n hw.logicalcpu -s make -jsysctl -n hw.logicalcpu -s关于构建行为从 Makefile 中可以提取出如下要点默认也是推荐构建类型是debug它比 release 构建慢但便于调试release 构建通过BUILD_TYPErelease开启。POSTGRES_INSTALL_DIR默认为仓库根目录下的pg_installPostgreSQL 会被安装到该目录下按版本分子目录。项目支持的 PostgreSQL 版本为v17 v16 v15 v14见POSTGRES_VERSIONSDEFAULT_PG_VERSION为 17见 control_plane/src/local_env.rs。构建产物打补丁后的 PostgreSQL、Neon 自身的 Rust 二进制、pgxn下的 Neon 扩展等统一放在build/目录。CARGO_BUILD_FLAGS可用来向 cargo 传递额外参数常见的如--locked与--features testing后者在跑集成测试时需要。运行 psql 与 Python 依赖要使用psql客户端安装postgresql-client包或者把pg_install/bin与pg_install/lib分别加入PATH与LD_LIBRARY_PATH。运行集成测试或 Python 脚本不是使用代码所必需的时需要 Python 3.11 或更高版本并在项目目录中用./scripts/pysync安装 Python 依赖需要poetry1.8。四、启动本地 Neon 数据库cargo neonNeon 自带一个本地开发控制面neon_local通过cargo neon子命令调用。从 control_plane/src/lib.rs 的文档注释可以看到它的定位是“本地控制面可以以本地进程的方式启动、配置和停止 postgres 实例服务于集成测试与本地安装的 CLI 工具”——这是一个面向开发/测试的最小控制面并不适合用于生产环境详见 control_plane/README.md。以下所有命令都应在仓库根目录执行。1. 初始化仓库并启动存储层# Create repository in .neon with proper paths to binaries and data # Later that would be responsibility of a package install script cargo neon init Initializing pageserver node 1 at 127.0.0.1:64000 in .neon # start pageserver, safekeeper, and broker for their intercommunication cargo neon start Starting neon broker at 127.0.0.1:50051. storage_broker started, pid: 2918372 Starting pageserver node 1 at 127.0.0.1:64000 in .neon. pageserver started, pid: 2918386 Starting safekeeper at 127.0.0.1:5454 in .neon/safekeepers/sk1. safekeeper 1 started, pid: 2918437cargo neon init会在当前目录创建.neon仓库写入配置、各节点的数据目录并生成 JWT 认证所需的公私钥auth_private_key.pem/auth_public_key.pem即使当前未启用认证也会生成便于之后随时开启。cargo neon start会依次启动 storage broker127.0.0.1:50051、pageserver127.0.0.1:64000和 safekeeper127.0.0.1:5454。从 control_plane/src/local_env.rs 可以看到.neon仓库的布局约定pageserver 数据在pageserver_N/目录含权威的pageserver.toml与identity.tomlsafekeepers 数据在safekeepers/sk1等子目录endpoint 数据在endpoints/broker 数据在storage_broker/。NEON_REPO_DIR环境变量可以覆盖仓库位置若未设置则使用$PWD/.neon。2. 创建默认 tenant 与 timeline# create initial tenant and use it as a default for every future neon_local invocation cargo neon tenant create --set-default tenant 9ef87a5bf0d92544f6fafeeb3239695c successfully created on the pageserver Created an initial timeline de200bd42b49cc1814412c7e592dd6e9 at Lsn 0/16B5A50 for tenant: 9ef87a5bf0d92544f6fafeeb3239695c Setting tenant 9ef87a5bf0d92544f6fafeeb3239695c as a default one在 Neon 的数据模型中tenant是资源隔离与计费的单元pageserver 按 tenant 管理数据timeline则是 tenant 内的一条写时复制copy-on-write分支链。--set-default把该 tenant 记录为默认值后续所有neon_local命令在不显式指定--tenant_id时都会使用它。3. 创建并启动 Postgres compute 节点# create postgres compute node cargo neon endpoint create main # start postgres compute node cargo neon endpoint start main Starting new endpoint main (PostgreSQL v14) on timeline de200bd42b49cc1814412c7e592dd6e9 ... Starting postgres at postgresql://cloud_admin127.0.0.1:55432/postgres # check list of running postgres instances cargo neon endpoint list ENDPOINT ADDRESS TIMELINE BRANCH NAME LSN STATUS main 127.0.0.1:55432 de200bd42b49cc1814412c7e592dd6e9 main 0/16B5BA8 running默认启动的 endpoint 使用cloud_admin用户和postgres数据库监听端口从 55432 开始分配。4. 连接数据库并执行查询 psql -p 55432 -h 127.0.0.1 -U cloud_admin postgres postgres# CREATE TABLE t(key int primary key, value text); CREATE TABLE postgres# insert into t values(1,1); INSERT 0 1 postgres# select * from t; key | value ------------ 1 | 1 (1 row)5. 创建分支并在分支上运行 Postgres这是 Neon 最具标志性的能力之一代码式分支code-like branching可以在任意时间点创建独立的分支分支拥有主库全部数据但写入互不影响。# create branch named migration_check cargo neon timeline branch --branch-name migration_check Created timeline b3b863fa45fa9e57e615f9f2d944e601 at Lsn 0/16F9A00 for tenant: 9ef87a5bf0d92544f6fafeeb3239695c. Ancestor timeline: main # check branches tree cargo neon timeline list (L) main [de200bd42b49cc1814412c7e592dd6e9] (L) ┗━ 0/16F9A00: migration_check [b3b863fa45fa9e57e615f9f2d944e601] # create postgres on that branch cargo neon endpoint create migration_check --branch-name migration_check # start postgres on that branch cargo neon endpoint start migration_check Starting new endpoint migration_check (PostgreSQL v14) on timeline b3b863fa45fa9e57e615f9f2d944e601 ... Starting postgres at postgresql://cloud_admin127.0.0.1:55434/postgres # check the new list of running postgres instances cargo neon endpoint list ENDPOINT ADDRESS TIMELINE BRANCH NAME LSN STATUS main 127.0.0.1:55432 de200bd42b49cc1814412c7e592dd6e9 main 0/16F9A38 running migration_check 127.0.0.1:55434 b3b863fa45fa9e57e615f9f2d944e601 migration_check 0/16F9A70 running # this new postgres instance will have all the data from main postgres, # but all modifications would not affect data in original postgres psql -p 55434 -h 127.0.0.1 -U cloud_admin postgres postgres# select * from t; key | value ------------ 1 | 1 (1 row) postgres# insert into t values(2,2); INSERT 0 1 # check that the new change doesnt affect the main postgres psql -p 55432 -h 127.0.0.1 -U cloud_admin postgres postgres# select * from t; key | value ------------ 1 | 1 (1 row)注意timeline branch的输出揭示了分支的底层实现新分支本质上是原 timeline 在某个 LSN 处派生的新 timelineAncestor timeline: main。这也是 Neon “秒级分支”能力的来源——分支只是元数据层面的写时复制并不拷贝物理数据。neon_local会在内存与.neon/config中维护“分支名 ↔ (tenant, timeline)”的映射避免用户与十六进制 ZId 打交道见 control_plane/src/local_env.rs 中branch_name_mappings的相关实现。6. 停止所有实例如果之后还要跑测试见下文必须先停掉刚才启动的所有 pageserver、safekeeper 和 postgres 实例 cargo neon stop7. 处理构建失败如果在初始化 tenant 阶段遇到错误最稳妥的做法是先cargo neon stop删除.neon目录修复问题后重新执行初始化流程。五、更进阶的neon_local用法control_plane/README.md 补充了 README 之外的两个高频场景。指定 PostgreSQL 版本如 Postgres 16默认使用 Postgres 17DEFAULT_PG_VERSION。要使用 Postgres 16需要给其中两条启动命令加上--pg-version参数cargo neon init cargo neon start cargo neon tenant create --set-default --pg-version 16 cargo neon endpoint create main --pg-version 16 cargo neon endpoint start main创建测试用户与数据库模拟云上形态默认cargo neon只提供cloud_admin用户与postgres数据库。若希望拥有类似云服务上的角色与数据库布局可以在创建、启动 endpoint 时加入两个开关cargo neon endpoint create main --pg-version 16 --update-catalog true cargo neon endpoint start main --create-test-user true第一条命令会创建neon_superuser及必要的角色第二条命令会创建test用户和neondb数据库并输出一条可以直接连到test用户的连接串。自定义.neon配置neon_local init还支持通过--configpath传入自定义配置仓库中给出了两份参考示例control_plane/simple.conf最小环境1 个 pageserver 1 个 safekeeper等价于不带--config的内置默认# Minimal neon environment with one safekeeper. This is equivalent to the built-in # defaults that you get with no --config [[pageservers]] id1 listen_pg_addr 127.0.0.1:64000 listen_http_addr 127.0.0.1:9898 listen_grpc_addr 127.0.0.1:51051 pg_auth_type Trust http_auth_type Trust grpc_auth_type Trust [[safekeepers]] id 1 pg_port 5454 http_port 7676 [broker] listen_addr 127.0.0.1:50051control_plane/safekeepers.conf1 个 pageserver 3 个 safekeeper用于验证 WAL 冗余与 quorum 逻辑# Page server and three safekeepers. [pageserver] listen_pg_addr 127.0.0.1:64000 listen_http_addr 127.0.0.1:9898 listen_grpc_addr 127.0.0.1:51051 pg_auth_type Trust http_auth_type Trust grpc_auth_type Trust [[safekeepers]] id 1 pg_port 5454 http_port 7676 [[safekeepers]] id 2 pg_port 5455 http_port 7677 [[safekeepers]] id 3 pg_port 5456 http_port 7678关键配置项说明对应 control_plane/src/local_env.rs 中的数据结构[[pageservers]]每个 pageserver 节点一个条目。listen_pg_addr是 compute 节点连它的 Postgres 协议地址listen_http_addr/listen_grpc_addr分别是 HTTP 管理与 gRPC 接口*_auth_type支持Trust等认证方式。[[safekeepers]]每个 safekeeper 节点一个条目pg_port用于接收 compute 节点的 WALhttp_port用于管理接口。[broker]storage broker 的监听地址负责 safekeeper 与 pageserver 之间的协调消息。[storage_controller]可选storage controller 的配置包括心跳间隔、离线判定阈值max_offline、分片阈值split_threshold等neon_local为加速测试采用了比默认更紧凑的心跳约 1 秒与离线判定10 秒参数。init之后生成的.neon/config记录了仓库状态pg_distrib_dir、neon_distrib_dir、默认 tenant、broker、safekeepers 等。需要留意的是pageserver 的权威配置已迁移到各pageserver_N/pageserver.toml.neon/config中不再接受pageservers字段——如果旧配置里残留该字段加载时会直接报错提示删除这是 local_env.rs 中反序列化器的显式行为。六、运行测试Rust 单元测试仓库使用cargo-nextest在 CI 中运行测试部分 crate 已经不支持直接跑cargo test推荐统一使用cargo install cargo-nextest cargo nextest run集成测试集成测试位于 test_runner基于 pytest 框架编写fixtures 见 test_runner/fixtures/neon_fixtures.py。确保依赖已按前文安装后git clone --recursive https://github.com/neondatabase/neon.git CARGO_BUILD_FLAGS--featurestesting make ./scripts/pytest默认情况下这会在debug 与 release 两种模式、以及所有受支持的 PostgreSQL 版本下各跑一遍耗时很长。本地开发时建议只跑其中一组排列组合例如DEFAULT_PG_VERSION17 BUILD_TYPErelease ./scripts/pytest七、生成火焰图Flamegraphs需要为仓库中的软件生成性能火焰图时可以使用flamegraph-rs或原始的flamegraph.pl。[!IMPORTANT] 如果链接器使用的是lld或mold必须加上--no-rosegment链接参数。这是 Rust 与 lld/mold 配合时的通用问题并非本仓库特有。八、清理构建产物清理源码树中的构建产物在源码根目录执行make clean。彻底移除所有构建与配置阶段产生的产物执行make distclean。它会删除pg_install/、build/并执行cargo clean见 Makefile 的distclean目标。同时建议一并删除target目录下的 cargo 二进制产物以及.neon目录中的数据库。警告删除.neon目录会连同其中所有数据一并删除请确认后再操作。九、进一步阅读与术语约定仓库内的文档索引与源码导读docs所有 Markdown 文档的顶层概览。docs/sourcetree.md源码树布局总览说明pageserver、safekeeper、proxy、pgxn、libs等各目录的职责。docs/glossary.mdNeon 术语表。由于 Neon 与 PostgreSQL 内部机制关系紧密仓库沿用了大量 PostgreSQL 术语并保留了 PostgreSQL 文档中“用 MB 表示 1024×1024 字节”的拼写习惯虽然技术上 MiB 更严谨但为与 PostgreSQL 代码及文档保持一致而沿用 MB。阅读代码与文档前建议先浏览术语表。想加入开发的话请先阅读 CONTRIBUTING.md 了解代码风格与实践并使用cargo doc --no-deps --open在浏览器中查看 rustdoc 文档。十、总结一条命令跑通全链路回顾整个本地开发流程核心操作可以浓缩为# 1. 安装系统依赖Linux/macOS 各不相同见上文 # 2. 安装 Rust 并确保 protoc 3.15 # 3. 构建默认 debug make -jnproc -s # 4. 初始化并启动本地集群 cargo neon init cargo neon start cargo neon tenant create --set-default # 5. 创建并启动 compute 节点 cargo neon endpoint create main cargo neon endpoint start main # 6. 连接 psql -p 55432 -h 127.0.0.1 -U cloud_admin postgres # 7. 测试完毕后停止 cargo neon stop在这条链路背后是 pageserver存储、safekeepersWAL 冗余、storage broker协调与无状态 compute 节点的分工协作以及“分支 写时复制 timeline”这一核心设计。掌握这套本地环境你就拥有了验证 Neon 功能、调试代码与运行集成测试的完整工作台。【免费下载链接】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),仅供参考
返回列表