- 后端
- 数据库
- 文档数据库
【免费下载链接】FerretDB
A truly Open Source MongoDB alternative
FerretDB 是一个真正开源的 MongoDB 替代方案,它把 MongoDB 兼容层叠加在 PostgreSQL(以及 SQLite)等关系型数据库之上;Tembo 则是一个以 PostgreSQL 为核心的托管开发平台,提供开箱即用的预配置栈。本文将以仓库中的官方博客《How to Run MongoDB Workloads with FerretDB on Tembo》为骨架,完整演示如何在 Tembo 上创建 "Mongo Alternative on Postgres" 实例、获取 TLS 连接串、用mongoimport导入 JSON 数据,并通过mongosh执行真实的 MongoDB 查询与聚合工作负载。读完本文,你将掌握一套从零开始、可直接用于生产环境的"托管 Postgres + MongoDB 兼容"部署方案,并理解其底层认证与 TLS 机制。
为什么是 FerretDB + Tembo
FerretDB 是一个可嵌入的 MongoDB 兼容实现:客户端使用 MongoDB 协议与它通信,而它把文档操作翻译为 PostgreSQL 查询,存储层完全由 PostgreSQL 承载。从源码看,它的核心配置(Config 结构体)只要求提供PostgreSQLURL、监听地址ListenAddr与状态目录StateDir即可启动,默认通过:27017端口对外提供 MongoDB 协议服务(见 监听地址配置)。
Tembo 的价值在于把"托管 Postgres + FerretDB 容器"打包成了按需创建的服务:它提供预构建的 Stacks(栈),开发者不需要自行构建、安装 Docker 或维护额外的基础设施团队,就能获得一个经过调优的文档存储实例。在 Tembo 上,FerretDB 以容器形式与你的数据库并置部署在同一网络内,从而降低访问延迟。
前置条件
开始之前,请准备好以下环境:
- Tembo 账号:用于创建托管实例(参考 Tembo 官方 Getting Started 指南完成注册)。
mongosh:MongoDB Shell,用于连接和操作 FerretDB 实例,也是下面所有示例的执行工具。psql:PostgreSQL 命令行客户端,用于在需要时直接检查底层 PostgreSQL 数据或创建用户。
了解 Tembo 上的 FerretDB 栈
Tembo 中的 Stack(栈)是一套为特定用途预构建、面向企业场景调优的 Postgres 配置集合。对于 MongoDB 用户,Tembo 提供了名为"Mongo Alternative on Postgres"的栈:
- 针对文档存储(document store)工作负载进行了专门优化;
- 栈内组件仍然可调整,并且可以利用 Tembo 上丰富的 Postgres 扩展体系进一步扩展能力;
- Tembo 不仅托管你的 Postgres 实例,还会在数据库旁边以容器方式运行 FerretDB,减少客户端访问 FerretDB 时的网络跳数。
对于正在评估 MongoDB 迁移、又希望继续使用成熟 PostgreSQL 生态的团队来说,这种"几秒钟创建、即开即用"的部署方式可以显著降低引入新数据库的管理成本。
在 Tembo 上创建 FerretDB 实例
登录 Tembo 控制台后,创建 FerretDB 实例的步骤如下:
- 在创建实例页面选择"Mongo Alternative on Postgres"栈(如上图所示)。
- 按需配置云服务商(cloud provider)、实例规格(instance type)、存储大小(storage size)和地域(region)。
- 点击Create,实例预配通常需要几分钟时间。
实例就绪后,在实例详情页可以查看到连接信息,包括连接串(connection string)、用户名(username)、密码(password)和主机(host):
连接串格式与根证书
Tembo 上 FerretDB 实例的连接串遵循以下格式:
mongodb://<USERNAME>:<PASSWORD>@<HOST>:27017/ferretdb?authMechanism=PLAIN&tls=true&tlsCaFile=$(pwd)/ca.crt逐段拆解:
| 参数 | 含义 |
|---|---|
mongodb://<USERNAME>:<PASSWORD>@<HOST>:27017/ferretdb | MongoDB 协议地址、端口(27017)与目标数据库(ferretdb) |
authMechanism=PLAIN | 认证机制,由 Tembo 连接详情生成,配合 Tembo 侧的用户体系使用 |
tls=true | 启用 TLS 加密连接,客户端与服务端之间的流量将被加密 |
tlsCaFile=$(pwd)/ca.crt | 指定 SSL 根证书的本地路径;$(pwd)表示当前工作目录 |
你需要先从连接详情面板下载根 SSL 证书(root CA certificate)。如果证书不放在当前目录,请把$(pwd)替换为证书实际路径,例如:
mongodb://<USERNAME>:<PASSWORD>@<HOST>:27017/ferretdb?authMechanism=PLAIN&tls=true&tlsCaFile=/your/certificate/path/ca.crtTLS 配置并不是 Tembo 独有:FerretDB 自身同样支持通过FERRETDB_LISTEN_TLS等环境变量开启 TLS 监听,客户端侧使用tls=true与tlsCAFile参数建立加密连接,完整说明见 TLS 连接文档。
用 mongoimport 向 FerretDB 导入 JSON 数据
从下载好的证书所在目录执行mongoimport,可以把一个包含采购记录(supply records)的 JSON 文件导入ferretdb数据库的supply集合中:
mongoimport --uri="<mongodb-connection-string>" --db ferretdb --collection supply --file /path/to/exportedFile.json使用时请将<mongodb-connection-string>替换为上面获取到的完整连接串,/path/to/exportedFile.json替换为 JSON 文件的真实路径。
mongoimport是 MongoDB 官方工具链的一部分,FerretDB 对这类原生工具保持兼容:在仓库的 数据迁移指南 中,同样推荐使用mongoexport/mongoimport(以及mongodump/mongorestore)在 MongoDB 与 FerretDB 之间迁移数据,命令格式与 MongoDB 完全一致。
通过 mongosh 连接并运行 MongoDB 工作负载
导入成功后,在包含根证书的目录中,用mongosh直接连接实例:
mongosh "<mongodb-connection-string>"连接建立后,即可执行标准的 MongoDB 操作。下面以supply集合为例,展示三类典型工作负载。
示例 1:查看单条采购记录
先通过findOne()了解supply集合中文档的结构与字段类型:
db.supply.findOne()结果:
response = { _id: ObjectId('65c0d6d5cfba3092d3958fbf'), transaction_id: 10004, customer_name: 'Jorge Lopez', customer_location: 'Madrid, Spain', product_category: 'Sports Equipment', transaction_time: ISODate('2023-07-10T10:00:00.000Z'), product_name: 'Adidas Running Shoes', price: 75, quantity: 2, payment_method: 'Bank Transfer' }可以看到每条记录包含交易编号、客户、品类、时间、商品、价格、数量与支付方式等字段,_id由 MongoDB 风格的 ObjectId 自动生成。
示例 2:按日期范围查询数据
分析某段促销周期内的销售影响时,可以用$gte/$lte限定transaction_time的取值区间:
db.supply.find({ transaction_time: { $gte: ISODate('2023-07-01T00:00:00.000Z'), $lte: ISODate('2023-07-03T23:59:59.000Z') } })结果(节选):
response = [ { _id: ObjectId('65c0d6d5cfba3092d3958fdb'), transaction_id: 10032, customer_name: 'Emma Olsen', customer_location: 'Bergen, Norway', product_category: 'Electronics', transaction_time: ISODate('2023-07-01T14:00:00.000Z'), product_name: 'Amazon Echo', price: 99, quantity: 1, payment_method: 'Bank Transfer' }, { _id: ObjectId('65c0d6d5cfba3092d3958fdc'), transaction_id: 10033, customer_name: 'Jens Petersen', customer_location: 'Copenhagen, Denmark', product_category: 'Fashion', transaction_time: ISODate('2023-07-02T15:00:00.000Z'), product_name: 'Fossil Watch', price: 150, quantity: 1, payment_method: 'MobilePay' }, { _id: ObjectId('65c0d6d5cfba3092d3958fea'), transaction_id: 10047, customer_name: 'Sarah Johnson', customer_location: 'Sydney, Australia', product_category: 'Electronics', transaction_time: ISODate('2023-07-03T13:00:00.000Z'), product_name: 'Dell Laptop', price: 1200, quantity: 1, payment_method: 'Credit Card' }, { _id: ObjectId('65c0d6d5cfba3092d3958feb'), transaction_id: 10048, customer_name: 'Mehmet Yilmaz', customer_location: 'Istanbul, Turkey', product_category: 'Fashion', transaction_time: ISODate('2023-07-03T14:00:00.000Z'), product_name: 'Handmade Bag', price: 80, quantity: 1, payment_method: 'Debit Card' } ]该查询只保留 2023 年 7 月 1 日至 3 日之间发生的交易,可用于促销活动效果的对比分析。
示例 3:聚合找出销量最高的商品
借助聚合管道,可以按商品名分组并汇总销售数量,从而识别最热销的商品:
db.supply.aggregate([ { $group: { _id: '$product_name', totalQuantity: { $sum: '$quantity' } } }, { $sort: { totalQuantity: -1 } }, { $limit: 1 } ])结果:
response = [{ _id: 'The Alchemist', totalQuantity: 5 }]这个操作先把记录按product_name分组,用$sum累加各商品的quantity,再按totalQuantity降序排序并只取第一名,最终得到销量最高的商品。
以上只是几个代表性格例:findOne/find覆盖了文档查询,聚合管道覆盖了$group、$sort、$limit等常用阶段。FerretDB 对这些 MongoDB 语义都有对应的实现与集成测试支撑,例如查询类命令可参考 integration/query 目录下的测试,聚合类命令可参考 aggregation 集成测试,你可以在自己的实例上继续尝试insert、update、delete、索引等更多操作。
底层机制:认证与 TLS 如何工作
在 Tembo 上运行的连接串看似简单,背后是 FerretDB 与 PostgreSQL 深度集成的结果。理解这些机制有助于你在自建环境中复现同样的部署:
- 认证转发给 PostgreSQL:FerretDB 自身不保存用户名与密码,而是把凭据转发给 PostgreSQL 校验。仓库的 认证文档 明确指出,客户端侧目前支持
SCRAM-SHA-256机制,用户在 PostgreSQL 中创建后即可通过mongodb://user:password@host:27017/访问 FerretDB。认证流程在服务端由saslStart/saslContinue命令实现,入口见 msg_saslstart.go 中的 msgSASLStart。 - TLS 加密:
tls=true与tlsCaFile是标准 MongoDB URI 参数。FerretDB 在服务端通过--listen-tls(FERRETDB_LISTEN_TLS)、证书文件与 CA 文件三个配置项开启 TLS 监听,详见 TLS 连接文档;Tembo 托管实例则在连接详情中直接生成了带这些参数的连接串,省去了手工拼接。 - 端口约定:MongoDB 协议默认监听
27017端口(FerretDB 默认值为127.0.0.1:27017,Docker 场景为:27017,见 flags.md),因此 Tembo 的连接串也统一使用该端口。
下一步
通过本文的流程,你可以在几分钟内获得一个"高可用、可扩展的托管 Postgres + MongoDB 兼容层"组合:Tembo 负责实例运维与扩展生态,FerretDB 负责把 MongoDB 工作负载翻译并落到 PostgreSQL 上,期间无需自行搭建 Docker 环境或维护复杂构建。
如果你的目标是从 MongoDB 迁移到开源方案,并且希望工作负载运行在托管 Postgres 服务之上,那么基于 Tembo 的 FerretDB 栈是一个值得评估的起点。你也可以参考仓库中的 FerretDB 安装文档 与 认证配置,在自有基础设施上复现同样的架构。
- 后端
- 数据库
- 文档数据库
【免费下载链接】FerretDB
A truly Open Source MongoDB alternative
相关推荐
在 Taikun CloudWorks 上运行托管 FerretDB 实例:迁移 MongoDB 工作负载的完整实战指南
在 Taikun CloudWorks 上运行托管 FerretDB 实例:迁移 MongoDB 工作负载的完整实战指南 本文以 FerretDB 官方博客指南
后端数据库文档数据库使用 FerretDB 在 Aiven for PostgreSQL 上运行 MongoDB 工作负载:云上部署实战指南
使用 FerretDB 在 Aiven for PostgreSQL 上运行 MongoDB 工作负载:云上部署实战指南 本指南将带你完整走一遍"以 Aiven
后端数据库文档数据库在 Kubernetes 上使用 CyberTec Postgres Operator 部署 FerretDB:开源 MongoDB 替代方案的完整实操指南
在 Kubernetes 上使用 CyberTec Postgres Operator 部署 FerretDB:开源 MongoDB 替代方案的完整实操指南 本
后端数据库文档数据库
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考