Configuration | Administration | Playbook | Dashboard | Parameter
Overview
MongoDB was once a stunning technology, allowing developers to cast aside the “schema constraints” of relational databases and quickly build applications. However, over time, MongoDB abandoned its open-source nature, changing its license to SSPL, which made it unusable for many open-source projects and early commercial projects. Most MongoDB users actually do not need the advanced features provided by MongoDB, but they do need an easy-to-use open-source document database solution. To fill this gap, FerretDB was born.
PostgreSQL’s JSON functionality is already well-rounded: binary storage JSONB, GIN arbitrary field indexing, various JSON processing functions, JSON PATH, and JSON Schema, it has long been a fully-featured, high-performance document database. However, providing alternative functionality and direct emulation are not the same. FerretDB can provide a smooth transition to PostgreSQL for applications driven by MongoDB drivers.
Pigsty provided a Docker-Compose support for FerretDB in 1.x, and native deployment support since v2.3. As an optional feature, it greatly benefits the enrichment of the PostgreSQL ecosystem. The Pigsty community has already become a partner with the FerretDB community, and we shall find more opportunities to work together in the future.
Configuration
You have to define a Mongo (FerretDB) cluster before deploying it. There are some parameters for it:
Here’s an example to utilize the default single-node pg-meta
cluster as MongoDB:
ferret:
hosts: { 10.10.10.10: { mongo_seq: 1 } }
vars:
mongo_cluster: ferret
mongo_pgurl: 'postgres://dbuser_meta:DBUser.Meta@10.10.10.10:5432/meta'
The mongo_cluster
and mongo_seq
are required identity parameters, you also need mongo_pgurl
to specify the underlying PostgreSQL URL for FerretDB.
You can also setup multiple replicas and bind an L2 VIP to them, utilize the underlying HA Postgres cluster through Services
mongo-test:
hosts:
10.10.10.11: { mongo_seq: 1 }
10.10.10.12: { mongo_seq: 2 }
10.10.10.13: { mongo_seq: 3 }
vars:
mongo_cluster: mongo-test
mongo_pgurl: 'postgres://test:test@10.10.10.11:5436/test'
vip_enabled: true
vip_vrid: 128
vip_address: 10.10.10.99
vip_interface: eth1
Administration
Create Cluster
To create a defined mongo/ferretdb cluster, run the mongo.yml
playbook:
./mongo.yml -l ferret # install mongo/ferretdb on group 'ferret'
Since FerretDB saves all data in underlying PostgreSQL, it is safe to run the playbook multiple times.
Remove Cluster
To remove a mongo/ferretdb cluster, run the mongo.yml
playbook with mongo_purge
subtask and mongo_purge
flag.
./mongo.yml -e mongo_purge=true -t mongo_purge
FerretDB Connect
You can connect to FerretDB with any MongoDB driver using the MongoDB connection string, here we use the mongosh
command line tool installed above as an example:
mongosh 'mongodb://dbuser_meta:DBUser.Meta@10.10.10.10:27017?authMechanism=PLAIN'
mongosh 'mongodb://test:test@10.10.10.11:27017/test?authMechanism=PLAIN'
Since Pigsty uses the scram-sha-256
as the default auth method, you must use the PLAIN
auth mechanism to connect to FerretDB. Check FerretDB: authentication for details.
You can also use other PostgreSQL users to connect to FerretDB, just specify them in the connection string:
mongosh 'mongodb://dbuser_dba:DBUser.DBA@10.10.10.10:27017?authMechanism=PLAIN'
Quick Start
You can connect to FerretDB, and pretend it is a MongoDB cluster.
$ mongosh 'mongodb://dbuser_meta:DBUser.Meta@10.10.10.10:27017?authMechanism=PLAIN'
The MongoDB commands will be translated into SQL
commands and run in underlying PostgreSQL:
use test # CREATE SCHEMA test;
db.dropDatabase() # DROP SCHEMA test;
db.createCollection('posts') # CREATE TABLE posts(_data JSONB,...)
db.posts.insert({ # 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');
If you are not familiar with MongoDB, here is a quick start: Perform CRUD Operations with MongoDB Shell
To generate some load, you can run a simple benchmark with mongosh
:
cat > benchmark.js <<'EOF'
const coll = "testColl";
const numDocs = 10000;
for (let i = 0; i < numDocs; i++) { // insert
db.getCollection(coll).insert({ num: i, name: "MongoDB Benchmark Test" });
}
for (let i = 0; i < numDocs; i++) { // select
db.getCollection(coll).find({ num: i });
}
for (let i = 0; i < numDocs; i++) { // update
db.getCollection(coll).update({ num: i }, { $set: { name: "Updated" } });
}
for (let i = 0; i < numDocs; i++) { // delete
db.getCollection(coll).deleteOne({ num: i });
}
EOF
mongosh 'mongodb://dbuser_meta:DBUser.Meta@10.10.10.10:27017?authMechanism=PLAIN' benchmark.js
You can check supported Mongo commands on ferretdb: supported commands, and there may be some differences between MongoDB and FerretDB. Check ferretdb: differences for details, it’s not a big deal for sane usage.
Playbook
There’s a built-in playbook mongo.yml
for installing the FerretDB cluster. But you have to define it first.
mongo.yml
mongo.yml
: Install MongoDB/FerretDB on the target host.
This playbook consists of the following sub-tasks:
mongo_check
: check mongo identitymongo_dbsu
: create os user mongodmongo_install
: install mongo/ferretdb rpmmongo_purge
: purge mongo/ferretdbmongo_config
: config mongo/ferretdbmongo_cert
: issue mongo/ferretdb ssl certs
mongo_launch
: launch mongo/ferretdb servicemongo_register
: register mongo/ferretdb to prometheus
Dashboard
There is one dashboard for FERRET
module for now.
Mongo Overview
Mongo Overview: Overview of a Mongo/FerretDB cluster
Parameter
There are 9 parameters in MONGO
module.
Parameter | Type | Level | Comment |
---|---|---|---|
mongo_seq |
int | I | mongo instance identifier, REQUIRED |
mongo_cluster |
string | C | mongo cluster name, MONGO by default |
mongo_pgurl |
pgurl | C/I | underlying postgres URL for ferretdb |
mongo_ssl_enabled |
bool | C | mongo/ferretdb ssl enabled, false by default |
mongo_listen |
ip | C | mongo listen address, empty for all addr |
mongo_port |
port | C | mongo service port, 27017 by default |
mongo_ssl_port |
port | C | mongo tls listen port, 27018 by default |
mongo_exporter_port |
port | C | mongo exporter port, 9216 by default |
mongo_extra_vars |
string | C | extra environment variables for MONGO server |
# mongo_cluster: #CLUSTER # mongo cluster name, required identity parameter
# mongo_seq: 0 #INSTANCE # mongo instance seq number, required identity parameter
# mongo_pgurl: 'postgres:///' # mongo/ferretdb underlying postgresql url, required
mongo_ssl_enabled: false # mongo/ferretdb ssl enabled, false by default
mongo_listen: '' # mongo/ferretdb listen address, '' for all addr
mongo_port: 27017 # mongo/ferretdb listen port, 27017 by default
mongo_ssl_port: 27018 # mongo/ferretdb tls listen port, 27018 by default
mongo_exporter_port: 9216 # mongo/ferretdb exporter port, 9216 by default
mongo_extra_vars: '' # extra environment variables for mongo/ferretdb