FerretDB
MongoDB 线协议兼容的 PostgreSQL 方案
MongoDB 线协议兼容的 PostgreSQL 方案
FerretDB 是开源的 MongoDB 线协议兼容中间件,可将 PostgreSQL 作为 MongoDB 的直接替代后端。依赖 MongoDB 线协议的应用可以通过它无缝使用 PostgreSQL,在两个数据库生态之间建立桥梁。
启用 FerretDB 需要使用 FerretDB 修订的 documentdb 扩展;Pigsty 软件仓库也提供该扩展。此冻结版本中的最新组合为 FerretDB 2.7 与 DocumentDB 0.107.0。
快速上手
按照 Pigsty 的标准安装流程,使用 mongo 配置模板:
./configure -c mongo # 使用 FerretDB / DocumentDB 配置模板
./install.yml # 安装;生产部署前请先修改 pigsty.yml 中的密码
生产部署时,务必在运行安装剧本前修改 pigsty.yml 中的密码参数。
配置
pg-meta:
hosts:
10.10.10.10: { pg_seq: 1, pg_role: primary }
vars:
pg_cluster: pg-meta
pg_users:
- { name: mongod ,password: DBUser.Mongo ,pgbouncer: true ,roles: [dbrole_admin ] ,comment: ferretdb super user ,superuser: true }
- { name: dbuser_meta ,password: DBUser.Meta ,pgbouncer: true ,roles: [dbrole_admin ] ,comment: pigsty admin user }
- { name: dbuser_view ,password: DBUser.Viewer ,pgbouncer: true ,roles: [dbrole_readonly] ,comment: read-only viewer }
pg_databases:
- {name: meta, owner: mongod ,baseline: cmdb.sql ,comment: pigsty meta database ,schemas: [pigsty] ,extensions: [ documentdb, postgis, vector, pg_cron, rum ]}
pg_hba_rules:
- { user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes' }
- { user: mongod , db: all ,addr: world ,auth: pwd ,title: 'mongodb password access from everywhere' }
node_crontab: [ '00 01 * * * postgres /pg/bin/pg-backup full' ]
# DocumentDB 设置
pg_extensions: [ documentdb, citus, postgis, pgvector, pg_cron, rum ]
pg_libs: 'pg_documentdb, pg_documentdb_core, pg_cron, pg_stat_statements, auto_explain'
pg_parameters: { cron.database_name: meta }
使用
完整说明请参阅 FERRET 模块文档。
安装客户端工具
可以使用 MongoDB 命令行工具 MongoSH 访问 FerretDB。
先用 pig 添加 MongoDB 软件仓库,再通过 yum 或 apt 安装 mongosh:
pig repo add mongo -u
yum install mongodb-mongosh
apt install mongodb-mongosh
连接 FerretDB
任何语言的 MongoDB 驱动都可以使用 MongoDB 连接串访问 FerretDB。以下为 mongosh 示例:
$ mongosh
Current Mongosh Log ID: 67ba8c1fe551f042bf51e943
Connecting to: mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.4.0
Using MongoDB: 7.0.77
Using Mongosh: 2.4.0
For mongosh info see: https://www.mongodb.com/docs/mongodb-shell/
test>
认证
可以使用不同用户登录,细节参阅 FerretDB:认证:
使用示例
连接 FerretDB 后,可以像使用 MongoDB 集群一样执行命令:
MongoDB 命令会转换为 SQL,并在底层 PostgreSQL 中执行:
use test // CREATE SCHEMA test;
db.dropDatabase(); // DROP SCHEMA test;
db.createCollection('posts'); // CREATE TABLE posts(_data JSONB,...)
db.posts.insertOne({ // INSERT INTO posts VALUES(...);
title: 'Post One',body: 'Body of post one',category: 'News',tags: ['news', 'events'],
user: {name: 'John Doe',status: 'author'},date: Date()}
);
db.posts.find().limit(2).pretty(); // SELECT * FROM posts LIMIT 2;
db.posts.createIndex({ title: 1 }) // CREATE INDEX ON posts(_data->>'title');
如果不熟悉 MongoDB,可以参考同样适用于 FerretDB 的 MongoDB Shell CRUD 教程。
下面的 mongosh 脚本可用于生成简单的示例负载:
cat > benchmark.js <<'EOF'
const coll = "testColl";
const numDocs = 1000;
for (let i = 0; i < numDocs; i++) {
db.getCollection(coll).insertOne({ num: i, name: "MongoDB Benchmark Test" });
}
for (let i = 0; i < numDocs; i++) {
db.getCollection(coll).find({ num: i });
}
for (let i = 0; i < numDocs; i++) {
db.getCollection(coll).updateOne({ num: i }, { $set: { name: "Updated" } });
}
for (let i = 0; i < numDocs; i++) {
db.getCollection(coll).deleteOne({ num: i });
}
EOF
mongosh 'mongodb://dbuser_meta:[email protected]:27017' benchmark.js
FerretDB 的支持命令列表和已知差异说明了兼容边界;对基本使用场景而言,这些差异通常影响不大。