所有托管服务节省 15%

测试技能,享折扣

使用代码: Skills 开始使用
China
Linux 虚拟服务器

如何在 VPS 上安装和配置 MongoDB(完整指南)

MongoDB 是一个面向文档的 NoSQL 数据库,将记录存储为 BSON(Binary JSON)文档,通过原生分片实现无模式数据建模和水平可扩展性。与关系型数据库不同,MongoDB 不需要预定义的表模式,使其成为具有不断演变的数据结构、高写入吞吐量或分层数据关系的应用程序的首选。

本指南介绍了在 Linux VPS 上进行生产级 MongoDB 部署的步骤——涵盖从官方存储库安装、身份验证加固、网络访问控制、TLS 配置、性能调优和备份自动化。每个步骤都假设您在真实服务器环境中运行,其中安全性和可靠性是不可协商的。

前置条件

继续之前,请确认以下内容:

  • 运行 Ubuntu 20.04 LTS 或 Ubuntu 22.04 LTS 的 VPS(两者命令相同)
  • 通过 SSH 进行 Root 或 sudo-privileged 用户访问
  • 最少 2 GB RAM(生产工作负载建议 4 GB)
  • 快速存储卷上至少 20 GB 的可用磁盘空间
  • UFW 或 iptables 可用于防火墙管理
  • 基本熟悉 Linux 命令行

> 架构说明:MongoDB 的 WiredTiger 存储引擎使用默认内部缓存,大小为 (RAM – 1 GB) 的 50%。在 2 GB VPS 上,这大约产生 512 MB 的缓存。对于读取密集型工作负载,至少配置 4 GB RAM 以避免缓存压力导致的持续磁盘 I/O。

MongoDB 与其他 NoSQL 数据库:快速对比

功能MongoDBRedisCassandraCouchDB
数据模型文档 (BSON)键值宽列文档 (JSON)
查询语言MQL (丰富查询)命令CQLMango / MapReduce
水平扩展原生分片集群模式原生多主
ACID 事务是 (v4.0+, 多文档)部分 (Lua 脚本)轻量级
最佳用例通用应用、API缓存、会话时间序列、物联网离线优先同步
磁盘持久化主存储可选 (RDB/AOF)主存储主存储
全文搜索Atlas Search / 文本索引有限有限

第1步:更新系统

始终从完全修补的系统开始。过时的软件包会引入已知的CVE,这些漏洞可能在您安装应用程序堆栈之前就被利用。

sudo apt update && sudo apt upgrade -y

应用内核或libc更新后,重新启动以激活新内核:

sudo reboot

服务器重新上线后通过SSH重新连接(通常需要30–60秒)。

第 2 步:从官方存储库安装 MongoDB

Ubuntu 的默认 apt 存储库提供的是过时的、社区重新打包的 MongoDB 版本,缺乏最新的安全补丁和引擎改进。始终从 MongoDB 的官方存储库安装。

添加 MongoDB GPG 密钥和存储库

apt-key 命令在 Ubuntu 22.04 上已弃用。使用推荐的密钥环方法,该方法适用于 20.04 和 22.04:

curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | 
  sudo gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg

添加官方存储库条目:

echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] 
  https://repo.mongodb.org/apt/ubuntu $(lsb_release -cs)/mongodb-org/7.0 multiverse" | 
  sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list

> 版本说明:如果您需要特定版本以实现应用程序兼容性,请将 7.0 替换为您的目标版本(例如 6.0)。MongoDB 7.0 是截至 2024 年的当前长期支持版本。

安装 MongoDB 软件包

sudo apt update
sudo apt install -y mongodb-org

这将安装以下组件:

    mongod — 主数据库守护程序
    mongos — 分片路由器(用于分片集群部署)
    mongosh — 现代 MongoDB Shell(替代旧版 mongo 二进制文件)
    mongodb-database-tools — 包括 mongodump、mongorestore、mongoexport 和 mongoimport

    固定已安装的版本

    防止可能破坏应用程序兼容性的意外升级:

    echo "mongodb-org hold" | sudo dpkg --set-selections
    echo "mongodb-org-database hold" | sudo dpkg --set-selections
    echo "mongodb-org-server hold" | sudo dpkg --set-selections
    echo "mongosh hold" | sudo dpkg --set-selections
    echo "mongodb-org-mongos hold" | sudo dpkg --set-selections
    echo "mongodb-org-tools hold" | sudo dpkg --set-selections

    第 3 步:配置系统级先决条件

    MongoDB 在守护程序启动前调整某些内核和文件系统参数时性能最佳。

    为打开的文件设置 ulimit

    MongoDB 需要较高的文件描述符限制。创建 systemd 覆盖:

    sudo mkdir -p /etc/systemd/system/mongod.service.d
    sudo tee /etc/systemd/system/mongod.service.d/limits.conf > /dev/null <<EOF
    [Service]
    LimitFNOFILE=64000
    LimitNPROC=64000
    EOF

    禁用透明大页面 (THP)

    THP 会导致 MongoDB 中出现显著的延迟峰值。持久禁用它:

    sudo tee /etc/systemd/system/disable-thp.service > /dev/null <<EOF
    [Unit]
    Description=Disable Transparent Huge Pages (THP)
    DefaultDependencies=no
    After=sysinit.target local-fs.target
    Before=mongod.service
    
    [Service]
    Type=oneshot
    ExecStart=/bin/sh -c 'echo never | tee /sys/kernel/mm/transparent_hugepage/enabled > /dev/null'
    ExecStart=/bin/sh -c 'echo never | tee /sys/kernel/mm/transparent_hugepage/defrag > /dev/null'
    
    [Install]
    WantedBy=basic.target
    EOF
    
    sudo systemctl daemon-reload
    sudo systemctl enable --now disable-thp

    验证设置是否生效:

    cat /sys/kernel/mm/transparent_hugepage/enabled

    输出应显示 [never] 作为活动值。

    第 4 步:启动并启用 MongoDB

    sudo systemctl daemon-reload
    sudo systemctl start mongod
    sudo systemctl enable mongod

    确认守护进程正在运行:

    sudo systemctl status mongod

    在输出中查找 Active: active (running)。如果服务启动失败,立即检查日志:

    sudo tail -50 /var/log/mongodb/mongod.log

    常见的启动失败包括:

    • 端口 27017 已在使用 — 另一个进程绑定到该端口;使用 sudo ss -tlnp | grep 27017 识别它
    • 数据目录权限mongod 用户必须拥有 /var/lib/mongodb;使用 sudo chown -R mongodb:mongodb /var/lib/mongodb 修复
    • THP 仍然启用 — WiredTiger 引擎会记录警告,可能会降低性能

    第5步:保护MongoDB — 身份验证和授权

    这是最关键的部分。暴露在互联网上的未受保护的MongoDB实例已导致数千起数据泄露事件。默认安装没有身份验证,这意味着任何能够访问端口27017的人都可以完全读写访问每个数据库。

    创建管理员用户

    连接到本地MongoDB shell(启用身份验证前不需要身份验证):

    mongosh

    在shell内,切换到admin数据库并创建超级用户:

    use admin
    
    db.createUser({
      user: "adminuser",
      pwd: passwordPrompt(),
      roles: [
        { role: "userAdminAnyDatabase", db: "admin" },
        { role: "readWriteAnyDatabase", db: "admin" },
        { role: "dbAdminAnyDatabase", db: "admin" },
        { role: "clusterAdmin", db: "admin" }
      ]
    })

    使用passwordPrompt()而不是纯文本字符串可以防止密码出现在shell历史记录中。在提示时输入密码,然后退出:

    exit

    mongod.conf中启用身份验证

    打开MongoDB配置文件:

    sudo nano /etc/mongod.conf

    找到security部分(它将被注释掉)并启用授权:

    security:
      authorization: enabled

    保存并退出(Ctrl+X,然后Y,然后Enter),然后重启守护进程:

    sudo systemctl restart mongod

    验证身份验证已强制执行

    尝试未经身份验证的连接 — 现在应该失败:

    mongosh --eval "db.adminCommand({ listDatabases: 1 })"

    您应该收到Unauthorized错误。现在正确进行身份验证:

    mongosh -u adminuser -p --authenticationDatabase admin

    创建应用程序范围的用户

    切勿将管理员超级用户用于应用程序连接。为每个应用程序数据库创建最小权限用户:

    use myappdb
    
    db.createUser({
      user: "appuser",
      pwd: passwordPrompt(),
      roles: [
        { role: "readWrite", db: "myappdb" }
      ]
    })

    第 6 步:配置网络绑定和防火墙规则

    限制或扩展 bindIp

    默认情况下,mongod.conf 仅绑定到 127.0.0.1。如果您的应用程序在同一 VPS 上运行,这是正确的设置。如果您需要远程访问(例如,从单独主机上的应用程序服务器),请编辑 /etc/mongod.conf

    net:
      port: 27017
      bindIp: 127.0.0.1,10.0.0.5

    10.0.0.5 替换为应用程序服务器的特定私有 IP。切勿在没有防火墙规则限制对已知 IP 访问的公共接口上设置 bindIp: 0.0.0.0绑定到所有接口且没有防火墙是导致 MongoDB 数据泄露事件的主要原因。

    更改后重新启动:

    sudo systemctl restart mongod

    配置 UFW 防火墙规则

    如果需要远程访问,仅允许特定的受信任 IP:

    sudo ufw allow from 10.0.0.5 to any port 27017 proto tcp
    sudo ufw enable
    sudo ufw status verbose

    阻止所有其他对端口 27017 的外部访问:

    sudo ufw deny 27017

    UFW 按顺序处理规则 — 上面的特定 allow from 规则优先于广泛的 deny 规则,对受信任的 IP 生效。

    第 7 步:为加密连接启用 TLS/SSL

    对于任何 MongoDB 流量跨越网络的部署——即使是私有 LAN——TLS 加密是强制性的。没有它,凭证和数据以明文形式传输。

    生成自签名证书用于测试(在生产环境中使用 CA 签名的证书——考虑将其与您域名的 SSL 证书配对):

    sudo mkdir -p /etc/mongodb/ssl
    sudo openssl req -newkey rsa:4096 -nodes -keyout /etc/mongodb/ssl/mongodb.key 
      -x509 -days 365 -out /etc/mongodb/ssl/mongodb.crt 
      -subj "/CN=your-vps-hostname"
    sudo cat /etc/mongodb/ssl/mongodb.crt /etc/mongodb/ssl/mongodb.key | 
      sudo tee /etc/mongodb/ssl/mongodb.pem > /dev/null
    sudo chown -R mongodb:mongodb /etc/mongodb/ssl
    sudo chmod 600 /etc/mongodb/ssl/mongodb.pem

    将 TLS 配置添加到 /etc/mongod.conf

    net:
      port: 27017
      bindIp: 127.0.0.1
      tls:
        mode: requireTLS
        certificateKeyFile: /etc/mongodb/ssl/mongodb.pem

    重启 MongoDB 并使用 TLS 连接:

    sudo systemctl restart mongod
    mongosh --tls --tlsCertificateKeyFile /etc/mongodb/ssl/mongodb.pem 
      --tlsAllowInvalidCertificates -u adminuser -p --authenticationDatabase admin

    --tlsAllowInvalidCertificates 标志仅在开发环境中对自签名证书可接受。使用 CA 签名的证书时将其删除。

    第8步:在 mongod.conf 中进行性能调优

    对于在具有专用资源的 VPS 上的生产部署,调优 WiredTiger 缓存和日志记录设置。打开 /etc/mongod.conf 并添加或修改以下内容:

    storage:
      dbPath: /var/lib/mongodb
      journal:
        enabled: true
      wiredTiger:
        engineConfig:
          cacheSizeGB: 1.5
    
    operationProfiling:
      slowOpThresholdMs: 100
      mode: slowOp
    
    replication:
      oplogSizeMB: 1024

    关键调优参数说明:

    • cacheSizeGB — 将其设置为可用 RAM 的大约 50% 减去 1 GB。在 4 GB VPS 上,使用 1.5。在 8 GB VPS 上,使用 3.5
    • slowOpThresholdMs — 超过此阈值(以毫秒为单位)的查询将被记录到分析器。降低此值有助于及早识别未索引的查询。
    • oplogSizeMB — 如果您计划稍后添加副本集成员,则相关。预先调整 oplog 大小可避免高写入工作负载上的复制延迟。

    应用更改:

    sudo systemctl restart mongod

    第9步:使用 mongodump 进行备份和恢复

    手动备份

    mongodump 
      --uri="mongodb://adminuser:yourpassword@127.0.0.1:27017/?authSource=admin" 
      --out /var/backups/mongodb/$(date +%Y-%m-%d)

    手动恢复

    mongorestore 
      --uri="mongodb://adminuser:yourpassword@127.0.0.1:27017/?authSource=admin" 
      /var/backups/mongodb/2024-06-15

    使用 Cron 自动化备份

    创建一个专用备份脚本:

    sudo tee /usr/local/bin/mongodb-backup.sh > /dev/null <<'EOF'
    #!/bin/bash
    BACKUP_DIR="/var/backups/mongodb"
    TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
    MONGO_URI="mongodb://adminuser:yourpassword@127.0.0.1:27017/?authSource=admin"
    RETENTION_DAYS=7
    
    mkdir -p "${BACKUP_DIR}/${TIMESTAMP}"
    mongodump --uri="${MONGO_URI}" --out="${BACKUP_DIR}/${TIMESTAMP}"
    find "${BACKUP_DIR}" -maxdepth 1 -type d -mtime +${RETENTION_DAYS} -exec rm -rf {} ;
    EOF
    
    sudo chmod +x /usr/local/bin/mongodb-backup.sh

    将其安排为每天凌晨 2:00 运行:

    (crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/mongodb-backup.sh >> /var/log/mongodb-backup.log 2>&1") | crontab -

    > 生产环境考虑:将备份存储在服务器外。将备份保存在与数据库相同的 VPS 上无法防止磁盘故障或服务器泄露。使用 rsyncrclone 或 S3 兼容的对象存储将备份复制到远程位置。

    第 10 步:监控 MongoDB 健康状况

    内置监控命令

    mongosh 内运行服务器统计:

    db.serverStatus()
    db.stats()
    db.currentOp()

    使用 mongostatmongotop

    从 shell 监控实时操作计数:

    mongostat --uri="mongodb://adminuser:yourpassword@127.0.0.1:27017/?authSource=admin"

    监控每个集合的读/写时间:

    mongotop --uri="mongodb://adminuser:yourpassword@127.0.0.1:27017/?authSource=admin"

    关键指标监控

    指标警告阈值表示内容
    wiredTiger.cache.bytes currently in cache> 90% 的 cacheSizeGB缓存压力;增加 RAM 或减少数据集
    connections.current> 80% 的 connections.available连接池耗尽;调整应用程序池
    opcounters.getmore持续高值游标效率低;检查查询模式
    repl.lag(副本集)> 10 秒复制延迟;检查网络和磁盘 I/O
    locks.Global.acquireWaitCount任何持续值锁争用;检查长时间运行的操作

    为 MongoDB 选择合适的托管

    您的 MongoDB 实例的性能和可靠性直接与底层基础设施相关。考虑这些部署层级:

    • 开发和暂存:具有 2–4 GB RAM 的标准 VPS 足以满足非生产工作负载、架构测试和集成环境的需求。
    • 生产单节点:具有 4–8 GB RAM、NVMe 存储和专用 CPU 核心的 VPS 可处理大多数 Web 应用程序的中等生产流量。
    • 高吞吐量生产:专用服务器消除了虚拟化环境中固有的嘈杂邻居效应。WiredTiger 的 I/O 模式从裸机 NVMe 阵列中受益匪浅。
    • ML/分析工作负载:如果您在运行 MongoDB 以及数据管道、聚合密集型分析或向量搜索,GPU 托管可以加速下游处理任务。

    对于需要图形管理界面的部署,带 cPanel 的 VPS 为不太熟悉纯 CLI 管理的团队提供了熟悉的环境,尽管直接 mongod.conf 编辑对于高级配置仍然是必要的。

    部署决策矩阵

    上线前使用此检查清单:

    • [ ] MongoDB 从官方存储库安装,版本已固定
    • [ ] mongod 服务已启用并确认 active (running)
    • [ ] 透明大页已禁用并验证
    • [ ] ulimit 文件描述符设置为 64000 或更高
    • [ ] 在 mongod.conf 中启用身份验证(authorization: enabled
    • [ ] 已创建管理员用户,使用 passwordPrompt() — shell 历史记录中没有明文密码
    • [ ] 已创建应用程序特定用户,具有最小权限角色
    • [ ] bindIp 仅限于 localhost 或特定受信任 IP
    • [ ] UFW 规则已就位 — 端口 27017 从公网阻止
    • [ ] 已启用 TLS 并配置有效证书
    • [ ] WiredTiger 缓存大小设置为 (RAM – 1 GB) 的 50%
    • [ ] 已启用慢查询分析(slowOpThresholdMs: 100
    • [ ] 自动每日备份,带离线服务器复制
    • [ ] 备份恢复已测试 — 从未恢复过的备份不是备份

    常见问题

    MongoDB 默认监听的端口是什么,应该更改吗?

    MongoDB 默认监听 TCP 端口 27017。将其更改为非标准端口会增加一点隐蔽性,但不能替代身份验证和防火墙规则。如果更改,请在 /etc/mongod.conf 中更新 net.port,并相应调整所有 UFW 规则和连接字符串。

    为什么 MongoDB 即使在数据集较小的情况下也会占用大量 RAM?

    WiredTiger 根据公式 max(50% of (RAM - 1 GB), 256 MB) 预分配其内部缓存。这是有意的——将工作数据保存在内存中可以消除磁盘读取。如果在小型 VPS 上 RAM 消耗是个问题,请在 /etc/mongod.conf 中明确将 cacheSizeGB 设置为较低的值。

    我可以在共享主机上运行 MongoDB 吗?

    不可以。MongoDB 需要持久的后台守护进程 (mongod)、对其数据目录的直接文件系统访问,以及绑定到网络端口的能力。这些在共享虚拟主机上都不可用。VPS 是最低可行的环境。

    mongodump 和文件系统快照备份之间有什么区别?

    mongodump 执行逻辑备份——它通过 MongoDB 查询接口读取文档并将其导出为 BSON 文件。它具有可移植性并可跨版本工作,但速度较慢,在没有 --oplog 的情况下无法保证高写入实例上的时间点一致性。文件系统快照 (LVM、ZFS 或云块存储快照) 在一致的时间点捕获原始数据文件,对于大型数据集速度明显更快,但需要存储引擎处于一致状态。

    如何检查已安装的 MongoDB 版本?

    从终端运行以下命令:

    mongod --version

    或从 mongosh 内部:

    db.version()