后端数据库文档数据库【免费下载链接】FerretDBA truly Open Source MongoDB alternative项目地址https://gitcode.com/gh_mirrors/fe/FerretDB点击查看免费下载本文是一篇围绕 FerretDB StackGres 组合的端到端部署实战教程先介绍 FerretDB 如何把 MongoDB 有线协议翻译到 PostgreSQL 后端、StackGres 又提供了哪些 Postgres 管理能力然后从零开始搭建 K3s/K3d 集群、安装 StackGres Operator、创建 SGCluster、通过 SGScript 自动建库建用户最后部署 FerretDB Deployment 并用 mongosh 验证插入与查询再以 Meteor 应用为例验证真实业务负载下的落库效果。读完本文你将掌握MongoDB 兼容访问层 Kubernetes 原生 Postgres 托管这一生产级开源组合的完整落地路径。背景FerretDB 与 StackGres 为什么适合组合在一起FerretDB 是 MongoDB 的开源替代品它做的事情可以概括为一句话把 MongoDB 的 wire protocol有线协议流量翻译成对 PostgreSQL 的 SQL 调用。也就是说你的 MongoDB 客户端不需要改任何代码、换任何驱动连接的却是一个 PostgreSQL 数据库。原始文档中描述的核心机制是FerretDB 会把 BSON 格式的 MongoDB wire protocol 数据转换成 PostgreSQL 中的 JSONB 存储并支持 JSONB 的高级查询。从当前仓库的源码可以进一步印证这条链路FerretDB 服务端入口 cmd/ferretdb/main.go 定义了--postgresql-url参数默认值postgres://127.0.0.1:5432/postgres并把它注入 internal/handler/handler.go 中的NewOpts.PostgreSQLURL最终由documentdb.NewPool建立到 PostgreSQL 的连接池。所有 MongoDB 命令最终都落到 PostgreSQL 侧的存储过程与 JSONB 数据上见 internal/documentdb/documentdb_core/documentdb_core.go 中由 genwrap 生成的bson_*系列封装。而 StackGres 是 OnGres 出品的full-stack Postgres Platform本质是一个 Kubernetes Operator它允许你用一段简短的 YAML 清单或者 Web Console 上的点选操作就能创建生产就绪的 Postgres 集群开箱即用地包含高可用基于 Patroni 的自动故障转移复制主从/级联复制连接池PgBouncer sidecar默认部署自动化备份监控与集中式日志150 扩展支持并集成 BabelfishSQL Server 兼容、Citus分片、Timescale时序等。把两者结合就能在 Kubernetes 上获得一个自带管理能力的 PostgreSQL MongoDB 兼容前端的完整开源数据库栈。环境准备Kubernetes 集群与命令行工具在安装 StackGres 之前需要准备一个正在运行的 Kubernetes 集群常用命令行工具kubectl与helm若未安装请参照各自官方安装文档如果没有现成集群可以用 K3s 快速搭一个单节点集群curl -sfL https://get.k3s.io | sh -这条命令会在几秒钟内取决于网络速度给你一个可用的单节点集群。macOS 上的 K3s/K3d 处理K3s 并不原生支持 macOS在 macOS 上需要借助虚拟机或 Linux 容器运行。文档给出的路径是先安装 Docker Desktop在 Preferences 的 Kubernetes 选项卡中启用 Kubernetes 并点击 Apply Restart更顺滑的方式是使用 K3d 把 K3s 跑在 Docker 里通过 Homebrew 安装并创建集群brew install k3d k3d cluster create cluster-name --image rancher/k3s:v1.25.9-k3s1随后把集群配置导出到~/.kube/config让kubectl和helm都能连接操作k3d kubeconfig get cluster-name ~/.kube/config注意文档指出Linux 上直接使用sudo k3s kubectl config view --raw ~/.kube/config也能导出 kubeconfig但在 macOS 上更推荐上面 K3d 的方式如果不再需要 K3s可用sudo /usr/local/bin/k3s-uninstall.sh卸载。安装 StackGres Operator官方推荐的安装方式是通过 Helm chart。本教程使用的命令如下helm repo add stackgres-charts https://stackgres.io/downloads/stackgres-k8s/stackgres/helm/ helm install --create-namespace --namespace stackgres stackgres-operator stackgres-charts/stackgres-operator第一条命令添加 StackGres 的 Helm 仓库第二条命令在stackgres命名空间安装 operator--create-namespace会自动创建命名空间。确认 operator 就绪并查看运行中的 Podkubectl wait -n stackgres deployment -l groupstackgres.io --forconditionAvailable kubectl get pods -n stackgres -l groupstackgres.io第一条命令会阻塞等待相关 Deployment 变为 Available第二条命令列出stackgres命名空间中运行的 Pod。正常情况下输出类似NAME READY STATUS RESTARTS AGE stackgres-operator-c4c6b4bcd-trsgp 1/1 Running 0 4m50s stackgres-restapi-6986cc8997-lfwql 2/2 Running 0 4m49s可以看到 operator 与 REST API 两个 Pod 都在运行说明控制平面已就绪。创建 StackGres 集群SGCluster本教程的示例资源来自 apps-on-stackgres 仓库的examples/ferretdb目录其中01-namespace.yaml、02-sgpoolingconfig.yaml、03-createuser_secret.sh、04-sgscript.yaml、05-sgcluster.yaml、06-ferretdb.yaml分别对应下面的各个步骤。先创建一个用于归拢所有相关资源的命名空间kind: Namespace apiVersion: v1 metadata: name: ferretdb应用该文件kubectl apply -f 01-namespace.yaml关键前提为 PgBouncer 配置忽略search_path这是整套配置中非常关键的一步。FerretDB 在启动时会尝试配置 PostgreSQL 的search_path参数但 StackGres 默认部署的 PgBouncer sidecar 并不支持该启动参数。处理方式有两个禁用 PgBouncer sidecar文档明确标注not recommended不推荐自定义 PgBouncer 的连接池配置让它在启动参数中忽略search_path。方案 2 通过SGPoolingConfig实现apiVersion: stackgres.io/v1 kind: SGPoolingConfig metadata: name: sgpoolingconfig1 namespace: ferretdb spec: pgBouncer: pgbouncer.ini: pgbouncer: ignore_startup_parameters: extra_float_digits,search_path应用kubectl apply -f 02-sgpoolingconfig.yaml其中ignore_startup_parameters同时列出了extra_float_digits和search_path两个参数前者同样属于 PgBouncer 不支持透传的启动参数。这条配置在整个 StackGres FerretDB 组合中属于最常见的坑务必先于集群创建完成。用 SGScript 自动创建用户与数据库FerretDB 使用一个或多个 PostgreSQL 数据库并要求这些数据库由指定用户创建并拥有。本教程创建一个数据库、一个用户、一个唯一密码但不使用 PostgreSQL 超级用户而是利用 StackGres 的SGScript机制在集群创建后自动执行 SQL 脚本完成建库建用户。第一步创建一个Secret其中包含生成随机密码并创建用户的 SQL 命令#!/bin/sh PASSWORD$(dd if/dev/urandom bs1 count8 statusnone | base64 | tr / 0) kubectl -n ferretdb create secret generic createuser \ --from-literalsqlcreate user ferretdb with password ${PASSWORD}保存为03-createuser_secret.sh并执行./03-createuser_secret.sh这里用/dev/urandom生成 8 字节随机数据经 base64 编码并把/替换为0得到安全的随机密码随后以Secret的形式存入集群sqlkey 存的就是create user ...语句。第二步创建SGScript它包含两个脚本一个从上述Secret读取 SQL 字面量来创建带密码的用户另一个创建归属于该用户、符合 FerretDB 需求的数据库apiVersion: stackgres.io/v1 kind: SGScript metadata: name: createuserdb namespace: ferretdb spec: scripts: - name: create-user scriptFrom: secretKeyRef: name: createuser key: sql - name: create-database script: | create database ferretdb owner ferretdb encoding UTF8 locale en_US.UTF-8 template template0;应用kubectl apply -f 04-sgscript.yaml注意建库语句中的几个细节owner ferretdb让数据库归属于刚才创建的用户encoding UTF8、locale en_US.UTF-8与template template0避开 template1 中可能存在的自定义对象保证了一个干净、可预测的字符集环境。创建 SGCluster现在创建 Postgres 集群本身apiVersion: stackgres.io/v1 kind: SGCluster metadata: namespace: ferretdb name: postgres spec: postgres: version: 15 instances: 1 pods: persistentVolume: size: 5Gi configurations: sgPoolingConfig: sgpoolingconfig1 managedSql: scripts: - sgScript: createuserdbkubectl apply -f 05-sgcluster.yaml要点解读postgres.version: 15使用 PostgreSQL 15instances: 1单实例即可满足演示需求生产可调大以获得高可用persistentVolume.size: 5Gi为每个 Pod 分配 5Gi 持久卷configurations.sgPoolingConfig: sgpoolingconfig1引用前面创建的 PgBouncer 配置managedSql.scripts引用createuserdb这个 SGScriptStackGres 会在集群启动后自动执行其中的建库建用户脚本。等待集群就绪通常几十秒到几分钟kubectl -n ferretdb get pods NAME READY STATUS RESTARTS AGE postgres-0 6/6 Running 0 16mPod 显示6/6表示主容器与各 sidecar包括 postgres-util、PgBouncer 等都已就绪。随后可以验证数据库是否已由 SGScript 自动创建并归属正确用户kubectl -n ferretdb exec -it postgres-0 -c postgres-util -- psql -l ferretdb List of databases Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges ------------------------------------------------------------------------------------------------------------- ferretdb | ferretdb | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | ...Owner列是ferretdb说明 SGScript 已成功完成建用户 建库 赋权的自动化流程。部署 FerretDB无状态 Deployment ServiceFerretDB 本身是无状态应用因此直接用标准的Deployment便于水平扩展Service模式部署apiVersion: apps/v1 kind: Deployment metadata: name: ferretdb-dep namespace: ferretdb labels: app: ferretdb spec: replicas: 1 selector: matchLabels: app: ferretdb template: metadata: labels: app: ferretdb spec: containers: - name: ferretdb image: ghcr.io/ferretdb/ferretdb ports: - containerPort: 27017 env: - name: FERRETDB_POSTGRESQL_URL value: postgres://postgres/ferretdb --- apiVersion: v1 kind: Service metadata: name: ferretdb namespace: ferretdb spec: selector: app: ferretdb ports: - name: mongo protocol: TCP port: 27017 targetPort: 27017kubectl apply -f 06-ferretdb.yaml解读FERRETDB_POSTGRESQL_URL连接串postgres://postgres/ferretdb的构成需要仔细拆解第一个postgrespostgres协议前缀第二个postgresStackGres 暴露的 Service 名称指向所创建集群的主实例其名字与SGCluster的名字一致本教程中 SGCluster 名为postgresferretdb数据库名即 SGScript 中创建的ferretdb数据库。从源码角度印证FerretDB 通过--postgresql-url/ 环境变量注入 PostgreSQL 连接串cmd/ferretdb/main.go 定义了postgresql-url与postgresql-url-file两个参数PostgreSQLURLFile非空时会覆盖前者见 cmd/ferretdb/main.go随后在 internal/handler/handler.go 由documentdb.NewPool(opts.PostgreSQLURL, ...)建立连接池。容器内通过FERRETDB_POSTGRESQL_URL环境变量注入正是 CLI 参数环境变量映射的标准用法。用 mongosh 验证连接部署成功后用kubectl run启动一个临时mongosh客户端 Pod 进行验证kubectl -n ferretdb run mongosh --imagertsp/mongosh --rm -it -- bashFerretDB 会在 MongoDB wire protocol 层透出与 PostgreSQL 相同的数据库、用户名与密码。也就是说前面用 SGScript 创建的ferretdb用户、随机密码和ferretdb数据库此时都能作为 MongoDB 凭据直接使用。在终端提示符出现后执行mongosh mongodb://ferretdb:${PASSWORD}${FERRETDB_SVC}/ferretdb?authMechanismPLAIN其中${PASSWORD}ferretdb用户在 PostgreSQL 中的随机密码可以从Secret中取回kubectl -n ferretdb get secret createuser --template {{ printf %s\n (.data.sql | base64decode) }}${FERRETDB_SVC}FerretDBService暴露的地址与端口例如kubectl -n ferretdb get svc ferretdb NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ferretdb ClusterIP 10.43.94.52 none 27017/TCP 10m示例中服务地址为10.43.94.52:27017。连接串中的authMechanismPLAIN指定使用明文认证机制与 PostgreSQL 的密码认证对应。Quickstart插入与查询数据连接成功后即可执行 MongoDB 风格的插入与查询ferretdb db.test.insertOne({a:1}) { acknowledged: true, insertedId: ObjectId(646dca174663396264d4bfeb) } ferretdb db.test.find() [ { _id: ObjectId(646dca174663396264d4bfeb), a: 1 } ]如果想看看数据在 PostgreSQL 侧到底长什么样可以进入 postgres-util 容器直接查询kubectl -n ferretdb exec -it postgres-0 -c postgres-util -- psql ferretdb psql (15.1 (OnGres 15.1-build-6.18)) Type help for help. ferretdb# set search_path to ferretdb; SET ferretdb# \dt List of relations Schema | Name | Type | Owner -------------------------------------------------------- ferretdb | _ferretdb_database_metadata | table | ferretdb ferretdb | test_afd071e5 | table | ferretdb (2 rows) ferretdb# table test_afd071e5; _jsonb ----------------------------------------------------------------------------------------------------------------------------- {a: 1, $s: {p: {a: {t: int}, _id: {t: objectId}}, $k: [_id, a]}, _id: 646dca174663396264d4bfeb} (1 row)这里可以非常直观地看到 BSON 到 JSONB 的物化过程集合test对应一张名为test_afd071e5的表表名带哈希后缀文档被存进_jsonb列$s字段记录了类型 schema$k为键顺序、p为每个字段的类型映射文档字段{a: 1}与_id都以 JSONB 形式保存_ferretdb_database_metadata表用于维护数据库元数据。这正好呼应了文档开头所述FerretDB 把 BSON 转换为 PostgreSQL 的 JSONB这一核心原理。真实业务负载验证Meteor 应用接入为了在本地完整测试整套链路先用kubectl port-forward把集群内 FerretDB Service 的 27017 端口转发到本机kubectl port-forward svc/ferretdb 27017:27017 -n ferretdb在另一个终端验证连通性需要本机装有 mongoshmongosh mongodb://ferretdb:${PASSWORD}localhost:27017/ferretdb?authMechanismPLAIN然后创建一个 Meteor 应用需先按官方文档安装 Meteormeteor create app-name cd app-name meteor npm install把app-name替换为实际项目名。Meteor 脚手架默认会在启动时当Links集合为空时插入若干带title、url、createdAt字段的文档并发布整个集合见server/main.js中的insertLink与Meteor.publish(links, ...)逻辑这与文档展示的示例代码一致。随后用 FerretDB 的 MongoDB URI 启动 Meteor让它使用外部 MongoDB 数据库而不是自带一个MONGO_URLmongodb://username:passwordlocalhost:27017/mydatabase meteor回到 PostgreSQL 侧验证数据落库ferretdb-# \dt List of relations Schema | Name | Type | Owner -------------------------------------------------------- ferretdb | _ferretdb_database_metadata | table | ferretdb ferretdb | links_e9ca9aee | table | ferretdb ferretdb | test_afd071e5 | table | ferretdb (3 rows) ferretdb# table links_e9ca9aee; _jsonb ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ {$s: {p: {_id: {t: string}, url: {t: string}, title: {t: string}, createdAt: {t: date}}, $k: [_id, title, url, createdAt]}, _id: 7NmpEw6k7z7HNTJpf, url: https://www.meteor.com/tutorials/react/creating-an-app, title: Do the Tutorial, createdAt: 1687291371079} {$s: {p: {_id: {t: string}, url: {t: string}, title: {t: string}, createdAt: {t: date}}, $k: [_id, title, url, createdAt]}, _id: f3D3wB25KGduKzbsc, url: https://guide.meteor.com, title: Follow the Guide, createdAt: 1687291371148} {$s: {p: {_id: {t: string}, url: {t: string}, title: {t: string}, createdAt: {t: date}}, $k: [_id, title, url, createdAt]}, _id: rdJH59NGgnonSSe5o, url: https://docs.meteor.com, title: Read the Docs, createdAt: 1687291371159} {$s: {p: {_id: {t: string}, url: {t: string}, title: {t: string}, createdAt: {t: date}}, $k: [_id, title, url, createdAt]}, _id: zoGgwqbofdGDvPyj4, url: https://forums.meteor.com, title: Discussions, createdAt: 1687291371164} (4 rows)links集合对应links_e9ca9aee表Meteor 插入的 4 条文档createdAt以毫秒时间戳形式保存在 JSONB 中完整地物化到了 PostgreSQL。这证明了一个关键事实MongoDB 生态应用如 Meteor无需任何代码修改就可以把数据真正落进 PostgreSQL。总结与延伸整个部署链路可以概括为Kubernetes 集群 → StackGres Operator → SGCluster含 PgBouncer 配置与 SGScript 自动建库→ FerretDB Deployment/Service → MongoDB 客户端 / Meteor 应用。几点核心经验值得沉淀search_path是必踩的坑FerretDB 启动时会设置 PostgreSQL 的search_path必须通过SGPoolingConfig让 PgBouncer 忽略该参数否则连接会失败凭据即数据库凭据FerretDB 透出 PostgreSQL 的用户、密码与数据库SGScript 自动化建库建用户让整套流程可重复、可审计无状态易扩展FerretDB 是无状态应用Deployment 模式可随时水平扩缩容数据可观测所有 MongoDB 文档都以带$sschema 信息的 JSONB 形式存储在 PostgreSQL 中既可以用 MongoDB 语法访问也可以在 PostgreSQL 侧直接用 SQL 查询。通过 FerretDB你可以继续使用熟悉的 MongoDB 文档模型与语法同时把数据托付给 PostgreSQL——结合 StackGres Operator 之后Kubernetes 上就拥有了一个带高可用、复制、连接池、备份、监控的完整开源数据库栈。如果想继续深入了解可以查看本仓库中的 FerretDB 配置说明如 cmd/ferretdb/main.go 中的全部 CLI 参数与默认值、数据处理核心internal/documentdb 目录下的连接池与文档处理实现以及仓库根目录的 README.md。在阅读源码时建议把重点放在 cmd/ferretdb/main.go 的参数定义与 internal/handler/handler.go 的初始化流程上二者能帮你快速建立入口参数 → 连接池 → 命令分发的整体认知。赞分享后端数据库文档数据库【免费下载链接】FerretDBA truly Open Source MongoDB alternative项目地址https://gitcode.com/gh_mirrors/fe/FerretDB点击查看免费下载相关推荐在 Kubernetes 上使用 CyberTec Postgres Operator 部署 FerretDB开源 MongoDB 替代方案的完整实操指南在 Kubernetes 上使用 CyberTec Postgres Operator 部署 FerretDB开源 MongoDB 替代方案的完整实操指南 本后端数据库文档数据库使用 KubeDB 托管 PostgreSQL 在 Kubernetes 上部署 FerretDB 实战指南使用 KubeDB 托管 PostgreSQL 在 Kubernetes 上部署 FerretDB 实战指南 FerretDB 是一款开源文档数据库它在 Po后端数据库文档数据库JDK HotSpot 反汇编插件 hsdisCapstone、LLVM、binutils 三大后端的构建与使用实战指南JDK HotSpot 反汇编插件 hsdisCapstone、LLVM、binutils 三大后端的构建与使用实战指南 本文围绕 JDK 仓库中的 hsdi后端数据库文档数据库创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考