如何在 VPS 上安装和配置 MongoDB(完整指南)
MongoDB 是一种面向文档的 NoSQL 数据库,以 BSON(二进制 JSON)文档形式存储记录,通过原生分片实现无模式数据建模和水平扩展。与关系型数据库不同,MongoDB 无需预定义表结构,使其成为数据结构不断演变、写入吞吐量高或存在层级数据关系的应用程序的主流选择。
本指南将带您完成在 Linux VPS 上部署生产级 MongoDB 的全过程——涵盖从官方仓库安装、身份验证加固、网络访问控制、TLS 配置、性能调优以及备份自动化。每个步骤均假设您在真实服务器环境中操作,安全性和可靠性不容妥协。
前提条件
在继续之前,请确认以下内容:
- 运行 Ubuntu 20.04 LTS 或 Ubuntu 22.04 LTS 的 VPS(两个版本命令相同)
- 通过 SSH 以 Root 或
sudo权限用户访问 - 最低 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 数据库:快速对比
| 特性 | MongoDB | Redis | Cassandra | CouchDB |
|---|---|---|---|---|
| 数据模型 | 文档(BSON) | 键值 | 宽列 | 文档(JSON) |
| 查询语言 | MQL(丰富查询) | 命令 | CQL | Mango / MapReduce |
| 水平扩展 | 原生分片 | 集群模式 | 原生 | 多主 |
| ACID 事务 | 支持(v4.0+,多文档) | 部分支持(Lua 脚本) | 轻量级 | 支持 |
| 最佳使用场景 | 通用应用、API | 缓存、会话 | 时间序列、IoT | 离线优先同步 |
| 磁盘持久化 | 主存储 | 可选(RDB/AOF) | 主存储 | 主存储 |
| 全文搜索 | Atlas Search / 文本索引 | 有限 | 不支持 | 有限 |
第一步:更新系统
始终从完全打补丁的系统开始。过时的软件包会引入已知的 CVE 漏洞,在您安装应用程序栈之前就可能被利用。
sudo apt update && sudo apt upgrade -y应用内核或 libc 更新后,重启以激活新内核:
sudo reboot服务器恢复在线后(通常 30–60 秒)通过 SSH 重新连接。
第二步:从官方仓库安装 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)。截至 2024 年,MongoDB 7.0 是当前的长期支持版本。
安装 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第三步:配置系统级前提条件
在守护进程启动之前,调整某些内核和文件系统参数可使 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] 为当前活动值。
第四步:启动并启用 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 引擎会记录警告并可能降低性能
第五步:保护 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" }
]
})第六步:配置网络绑定和防火墙规则
限制或扩展 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 27017UFW 按顺序处理规则——位于宽泛的 deny 规则之上的特定 allow from 规则对可信 IP 优先生效。
第七步:启用 TLS/SSL 加密连接
对于 MongoDB 流量跨越网络的任何部署——即使是私有局域网——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 签名证书时请将其移除。
第八步:在 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第九步:使用 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 上无法防范磁盘故障或服务器入侵。使用 rsync、rclone 或兼容 S3 的对象存储将备份复制到远程位置。
第十步:监控 MongoDB 健康状态
内置监控命令
在 mongosh 中运行服务器统计信息:
db.serverStatus()
db.stats()
db.currentOp()使用 mongostat 和 mongotop
从 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 | > cacheSizeGB 的 90% | 缓存压力;增加 RAM 或减少数据集 |
connections.current | > connections.available 的 80% | 连接池耗尽;调整应用连接池 |
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 阵列中获益显著。
- 机器学习/分析工作负载:如果您在数据管道、聚合密集型分析或向量搜索旁边运行 MongoDB,GPU 托管可加速下游处理任务。
对于需要图形化管理界面的部署,带 cPanel 的 VPS 为不熟悉纯命令行管理的团队提供了熟悉的环境,但高级配置仍需直接编辑 mongod.conf。
部署决策清单
上线前请使用此清单:
- [ ] MongoDB 已从官方仓库安装,版本已锁定
- [ ]
mongod服务已启用并确认active (running) - [ ] 透明大页已禁用并验证
- [ ] 文件描述符的
ulimit设置为 64000 或更高 - [ ] 在
mongod.conf中启用了身份验证(authorization: enabled) - [ ] 使用
passwordPrompt()创建了管理员用户——Shell 历史记录中无明文密码 - [ ] 已为应用程序创建具有最小权限角色的专用用户
- [ ]
bindIp仅限于本地主机或特定可信 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()
