跳转到主要内容

这是本节的多页打印视图。 .

返回本页常规视图.

FERRET

Ferret,基于 postgres 的 mongo

MongoDB 已经失去了其开源吸引力,不再适合许多用例。 相比之下,PostgreSQL 提供强大的原生 JSON 支持,作为文档数据库的性能超越了 MongoDB。

因此,FerretDB 在 postgres 之上提供了与 mongo 线协议兼容的层,使 MongoDB 用户能够平滑迁移到 PostgreSQL 的优越平台。 FERRET 是 Pigsty 中的一个 可选 模块。 自 v2.0 以来,它需要 documentdb 扩展才能工作。

Pigsty 已经打包了这个扩展,并提供了一个 mongo.yml 模板,帮助您轻松部署 FerretDB 集群。

配置
    配置 ferret 模块,并使用多个 ferret 节点。
参数
    使用 9 个参数自定义 ferret 组件
管理
    创建、移除、扩展、收缩、升级 ferret 集群
剧本
    可在此模块中使用的 Ansible 剧本
监控
    仪表板、指标、记录和告警规则。
使用
    如何使用 mcli 和配置备份仓库

1 - 使用方法

安装客户端工具,连接并使用 FerretDB

本文档介绍如何安装 MongoDB 客户端工具并连接到 FerretDB。


安装客户端工具

您可以使用 MongoDB 的命令行工具 MongoSH 来访问 FerretDB。

使用 pig 命令添加 MongoDB 仓库,然后使用 yumapt 安装 mongosh

pig repo add mongo -u   # 添加 MongoDB 官方仓库
yum install mongodb-mongosh   # RHEL/CentOS/Rocky/Alma
apt install mongodb-mongosh   # Debian/Ubuntu

安装完成后,您可以使用 mongosh 命令连接到 FerretDB。


连接到 FerretDB

您可以使用任何语言的 MongoDB 驱动程序通过 MongoDB 连接字符串访问 FerretDB。以下是使用 mongosh CLI 工具的示例:

$ 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 的身份验证完全基于 PostgreSQL。由于 Pigsty 管理的 PostgreSQL 集群默认使用 scram-sha-256 认证方式,您必须在连接字符串中指定 PLAIN 认证机制:

mongosh 'mongodb://dbuser_meta:[email protected]:27017?authMechanism=PLAIN'

连接字符串格式:

mongodb://<username>:<password>@<host>:<port>/<database>?authMechanism=PLAIN

使用不同的用户

您可以使用任何已在 PostgreSQL 中创建的用户连接到 FerretDB:

# 使用 dbuser_dba 用户
mongosh 'mongodb://dbuser_dba:[email protected]:27017?authMechanism=PLAIN'

# 使用 mongod 超级用户
mongosh 'mongodb://mongod:[email protected]:27017?authMechanism=PLAIN'

# 连接到特定数据库
mongosh 'mongodb://test:[email protected]:27017/test?authMechanism=PLAIN'

基本操作

连接到 FerretDB 后,您可以像使用 MongoDB 一样进行操作。以下是一些基本操作示例:

数据库操作

// 切换/创建数据库
use mydb

// 显示所有数据库
show dbs

// 删除当前数据库
db.dropDatabase()

集合操作

// 创建集合
db.createCollection('users')

// 显示所有集合
show collections

// 删除集合
db.users.drop()

文档操作

// 插入单个文档
db.users.insertOne({
    name: 'Alice',
    age: 30,
    email: '[email protected]'
})

// 插入多个文档
db.users.insertMany([
    { name: 'Bob', age: 25 },
    { name: 'Charlie', age: 35 }
])

// 查询文档
db.users.find()
db.users.find({ age: { $gt: 25 } })
db.users.findOne({ name: 'Alice' })

// 更新文档
db.users.updateOne(
    { name: 'Alice' },
    { $set: { age: 31 } }
)

// 删除文档
db.users.deleteOne({ name: 'Bob' })
db.users.deleteMany({ age: { $lt: 30 } })

索引操作

// 创建索引
db.users.createIndex({ name: 1 })
db.users.createIndex({ age: -1 })

// 查看索引
db.users.getIndexes()

// 删除索引
db.users.dropIndex('name_1')

与 MongoDB 的差异

FerretDB 实现了 MongoDB 的线协议,但底层使用 PostgreSQL 存储数据。这意味着:

  • MongoDB 命令会被翻译为 SQL 语句执行
  • 大多数基本操作与 MongoDB 兼容
  • 某些高级功能可能有差异或不支持

您可以查阅以下资源了解详细信息:


程序语言驱动

除了 mongosh 命令行工具,您还可以使用各种编程语言的 MongoDB 驱动程序连接到 FerretDB:

Python

from pymongo import MongoClient

client = MongoClient('mongodb://dbuser_meta:[email protected]:27017/?authMechanism=PLAIN')
db = client.test
collection = db.users
collection.insert_one({'name': 'Alice', 'age': 30})

Node.js

const { MongoClient } = require('mongodb');

const uri = 'mongodb://dbuser_meta:[email protected]:27017/?authMechanism=PLAIN';
const client = new MongoClient(uri);

async function run() {
    await client.connect();
    const db = client.db('test');
    const collection = db.collection('users');
    await collection.insertOne({ name: 'Alice', age: 30 });
}

Go

import (
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

uri := "mongodb://dbuser_meta:[email protected]:27017/?authMechanism=PLAIN"
client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))

关键点:所有驱动程序都需要在连接字符串中指定 authMechanism=PLAIN 参数。

2 - 配置

描述您想要的 ferret 集群

FerretDB 集群

在部署 Mongo (FerretDB) 集群之前,您需要使用相关 参数 在清单中定义它。

以下示例使用默认的单节点 pg-meta 集群的 meta 数据库作为 FerretDB 的底层存储:

all:
  children:

    #----------------------------------#
    # ferretdb for mongodb on postgresql
    #----------------------------------#
    # ./mongo.yml -l ferret
    ferret:
      hosts:
        10.10.10.10: { mongo_seq: 1 }
      vars:
        mongo_cluster: ferret
        mongo_pgurl: 'postgres://mongod:[email protected]:5432/meta'

这里,mongo_clustermongo_seq 是基本的身份参数。对于 FerretDB,还需要 mongo_pgurl 来指定底层 PG 位置。

请注意,mongo_pgurl 参数需要一个 PostgreSQL 超级用户。在此示例中,为 FerretDB 定义了一个专用的 mongod 超级用户。

请注意,FerretDB 的 身份验证 完全基于 PostgreSQL。您可以使用 FerretDB 或 PostgreSQL 创建其他常规用户。


PostgreSQL 集群

FerretDB 2.0+ 需要一个扩展:DocumentDB,它依赖于几个其他扩展。以下是为 FerretDB 创建 PostgreSQL 集群的模板:

all:
  children:

    #----------------------------------#
    # pgsql (singleton on current node)
    #----------------------------------#
    # postgres cluster: pg-meta
    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 ] ,superuser: true ,comment: ferretdb super user }
          - { 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 for meta database }
        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' }
        pg_extensions:
          - documentdb, citus, postgis, pgvector, pg_cron, rum
        pg_parameters:
          cron.database_name: meta
        pg_libs: 'pg_documentdb, pg_documentdb_core, pg_cron, pg_stat_statements, auto_explain'  # 将 timescaledb 添加到 shared_preload_libraries

高可用性

您可以使用 服务 连接到高可用的 PostgreSQL 集群,并部署多个 FerretDB 实例副本,并为 FerretDB 层高可用性绑定 L2 VIP。

ferret:
  hosts:
    10.10.10.45: { mongo_seq: 1 }
    10.10.10.46: { mongo_seq: 2 }
    10.10.10.47: { mongo_seq: 3 }
  vars:
    mongo_cluster: ferret
    mongo_pgurl: 'postgres://mongod:[email protected]:5436/test'
    vip_enabled: true
    vip_vrid: 128
    vip_address: 10.10.10.99
    vip_interface: eth1

3 - 参数

使用 9 个参数自定义 FerretDB

FERRET 模块中有 9 个参数。

参数 类型 层级 注释
mongo_seq int I mongo 实例标识符,必需
mongo_cluster string C mongo 集群名称,默认为 MONGO
mongo_pgurl pgurl C/I ferretdb 的底层 postgres URL
mongo_ssl_enabled bool C mongo/ferretdb ssl 启用,默认为 false
mongo_listen ip C mongo 监听地址,为空时监听所有地址
mongo_port port C mongo 服务端口,默认为 27017
mongo_ssl_port port C mongo tls 监听端口,默认为 27018
mongo_exporter_port port C mongo exporter 端口,默认为 9216
mongo_extra_vars string C MONGO 服务器的额外环境变量

默认值

默认参数定义在 roles/ferret/defaults/main.yml

# mongo_cluster:        #CLUSTER  # mongo 集群名称,必需的身份参数
# mongo_seq: 0          #INSTANCE # mongo 实例序列号,必需的身份参数
# mongo_pgurl: 'postgres:///'     # mongo/ferretdb 底层 postgresql url,必需
mongo_ssl_enabled: false          # mongo/ferretdb ssl 启用,默认为 false
mongo_listen: ''                  # mongo/ferretdb 监听地址,'' 表示所有地址
mongo_port: 27017                 # mongo/ferretdb 监听端口,默认为 27017
mongo_ssl_port: 27018             # mongo/ferretdb tls 监听端口,默认为 27018
mongo_exporter_port: 9216         # mongo/ferretdb exporter 端口,默认为 9216
mongo_extra_vars: ''              # mongo/ferretdb 的额外环境变量

mongo_cluster

名称:mongo_cluster,类型:string,层级:C

mongo 集群名称,必需的身份参数。

默认值为 MONGO,但您应该为生产使用显式定义它。

符合正则表达式 [a-z][a-z0-9-]*,建议使用描述性名称并以 mongo- 开头


mongo_seq

名称:mongo_seq,类型:int,层级:I

mongo 实例序列号,mongo 集群中需要唯一整数

您必须为每个 mongo 实例显式定义序列号。整数从 0 或 1 开始。


mongo_pgurl

名称:mongo_pgurl,类型:pgurl,层级:C/I

ferretdb 连接的底层 postgres URL。

没有默认值,您必须显式定义它。这是 FerretDB 将用作其后端存储的 PostgreSQL 数据库 URL。

格式:postgres://username:password@host:port/database


mongo_ssl_enabled

名称:mongo_ssl_enabled,类型:bool,层级:C

mongo/ferretdb ssl 启用标志。

默认值为 false。设置为 true 以启用 mongo 连接的 SSL/TLS 加密。


mongo_listen

名称:mongo_listen,类型:ip,层级:C

mongo 绑定的监听地址。

默认值为空字符串 '',这意味着监听所有可用地址。您可以指定特定的 IP 地址进行绑定。


mongo_port

名称:mongo_port,类型:port,层级:C

mongo 客户端连接的服务端口。

默认值为 27017,这是标准的 MongoDB 端口。如果您需要避免端口冲突,请更改此端口。


mongo_ssl_port

名称:mongo_ssl_port,类型:port,层级:C

mongo 加密连接的 tls 监听端口。

默认值为 27018。当为安全连接启用 SSL/TLS 时,使用此端口。


mongo_exporter_port

名称:mongo_exporter_port,类型:port,层级:C

mongo 指标收集的 exporter 端口。

默认值为 9216。此端口由监控 exporter 使用,向 Prometheus 暴露指标。


mongo_extra_vars

名称:mongo_extra_vars,类型:string,层级:C

MONGO 服务器的额外环境变量。

默认值为空字符串 ''。您可以指定将传递给 FerretDB 进程的额外环境变量。

4 - 管理

运行管理任务

创建 FerretDB 集群

清单定义 FerretDB 集群后,您可以使用以下命令安装它:

./mongo.yml -l ferret   # 在 ferret 组上安装 MongoDB/FerretDB

由于 FerretDB 使用 PostgreSQL 作为其底层存储,多次运行此剧本通常是安全的。


移除 FerretDB 集群

要移除 Mongo/FerretDB 集群,请使用 mongo_purge 参数运行 mongo.yml 剧本的 mongo_purge 子任务:

./mongo.yml -e mongo_purge=true -t mongo_purge

5 - 剧本

使用剧本安装 ferretdb

有一个内置的剧本 mongo.yml 用于在节点上安装 FerretDB。


mongo.yml

mongo.yml:在目标主机上安装 MongoDB/FerretDB。

此剧本包含以下子任务:

  • mongo_check :检查 mongo 身份
  • mongo_dbsu :创建操作系统用户 mongod
  • mongo_install :安装 mongo/ferretdb rpm
  • mongo_purge :清除 mongo/ferretdb
  • mongo_config:配置 mongo/ferretdb
  • mongo_cert :签发 mongo/ferretdb ssl 证书
  • mongo_launch :启动 mongo/ferretdb 服务
  • mongo_register :将 mongo/ferretdb 注册到 prometheus

6 - 监控

FerretDB 监控仪表板和告警

FERRET 模块目前有一个仪表板。

Mongo Overview

Mongo Overview:Mongo/FerretDB 集群概览