MongoDB启动与配置指南
一、MongoDB 简介
MongoDB 是一款基于分布式文件存储的开源数据库系统,由 C++ 语言编写。它以其灵活的数据模型(BSON,一种类似 JSON 的二进制格式)、高可扩展性、高性能等特点,在现代应用开发中广泛应用,尤其适用于处理大量非结构化和半结构化数据。
二、安装 MongoDB
在开始启动和配置 MongoDB 之前,首先需要确保 MongoDB 已经正确安装在你的系统上。不同操作系统有不同的安装方式:
(一)Windows 系统安装
- 下载安装包:从 MongoDB 官方网站(https://www.mongodb.com/try/download/community)下载适用于 Windows 的安装包。
- 运行安装程序:双击下载的
.msi
文件,按照安装向导提示进行安装。在安装过程中,可以选择安装路径、是否添加到系统路径等选项。建议勾选“Add MongoDB to the system PATH”,方便后续操作。 - 创建数据目录:默认情况下,MongoDB 需要一个数据存储目录,通常为
C:\data\db
。如果该目录不存在,需要手动创建。
(二)Linux 系统安装(以 Ubuntu 为例)
- 导入 MongoDB 官方 GPG 密钥:
wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | sudo apt-key add -
- 创建 MongoDB 软件源列表文件:
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list
- 更新软件包列表并安装 MongoDB:
sudo apt-get update
sudo apt-get install -y mongodb-org
(三)MacOS 系统安装
- 使用 Homebrew 安装:如果已经安装了 Homebrew,可以直接在终端执行以下命令安装 MongoDB:
brew install mongodb-community
- 创建数据目录:MongoDB 默认的数据目录为
/data/db
,需要手动创建并设置权限:
sudo mkdir -p /data/db
sudo chown -R `id -un` /data/db
三、启动 MongoDB
(一)使用默认配置启动
- Windows 系统:打开命令提示符,进入 MongoDB 的
bin
目录(如果安装时添加到系统路径,则无需进入该目录),执行以下命令启动 MongoDB:
mongod
- Linux 系统:在终端执行以下命令启动 MongoDB 服务:
sudo systemctl start mongod
可以通过以下命令检查服务状态:
sudo systemctl status mongod
- MacOS 系统:在终端执行以下命令启动 MongoDB:
mongod --config /usr/local/etc/mongod.conf
如果使用 Homebrew 安装,也可以通过以下命令管理 MongoDB 服务:
brew services start mongodb-community
brew services stop mongodb-community
brew services restart mongodb-community
(二)使用自定义配置文件启动
- 创建配置文件:在合适的目录下创建一个配置文件,例如
mongod.conf
。以下是一个简单的配置文件示例:
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true
storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
net:
bindIp: 127.0.0.1
port: 27017
上述配置文件中:
- systemLog
部分配置了日志相关设置,日志输出到文件 /var/log/mongodb/mongod.log
并采用追加模式。
- storage
部分指定了数据存储目录为 /var/lib/mongodb
并启用了日志功能。
- net
部分设置了绑定的 IP 地址为本地回环地址 127.0.0.1
,端口为默认的 27017
。
2. 启动 MongoDB:根据不同操作系统,使用以下命令启动 MongoDB 并指定配置文件:
- Windows 系统:在命令提示符中执行:
mongod --config "C:\path\to\mongod.conf"
- **Linux 系统**:
sudo mongod --config /etc/mongod.conf
- **MacOS 系统**:
mongod --config /usr/local/etc/mongod.conf
四、基本配置选项详解
(一)系统日志配置
- destination:指定日志输出目的地,可以是
file
(文件)或syslog
(系统日志)。如果选择file
,还需要指定path
。 - path:日志文件的路径。例如:
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
- logAppend:设置为
true
表示追加日志,false
则表示覆盖日志。
(二)存储配置
- dbPath:指定数据库的数据存储目录。例如:
storage:
dbPath: /var/lib/mongodb
- journal:启用或禁用 MongoDB 的日志功能。启用日志可以确保数据的一致性和持久性。
storage:
journal:
enabled: true
(三)网络配置
- bindIp:指定 MongoDB 绑定的 IP 地址。默认情况下,只绑定
127.0.0.1
,即只能本地访问。如果要允许远程访问,可以设置为服务器的公网 IP 地址或0.0.0.0
(允许所有 IP 访问,但安全性较低)。
net:
bindIp: 127.0.0.1
- port:指定 MongoDB 监听的端口,默认是
27017
。
net:
port: 27017
(四)安全配置
- authorization:启用身份验证。在生产环境中,强烈建议启用身份验证以保护数据库安全。设置为
enabled
表示启用身份验证。
security:
authorization: enabled
- keyFile:用于副本集和分片集群的内部身份验证。每个节点都必须有相同的
keyFile
。例如:
security:
keyFile: /path/to/keyfile
五、配置副本集
副本集是 MongoDB 提供的一种高可用性机制,由多个 MongoDB 节点组成,其中一个为主节点(Primary),其余为从节点(Secondary)。主节点负责处理写操作,从节点复制主节点的数据。
(一)初始化副本集
- 启动多个 MongoDB 实例:假设我们要创建一个包含三个节点的副本集,分别在不同端口启动三个 MongoDB 实例。以下以 Windows 系统为例,在三个不同的命令提示符窗口中执行:
mongod --port 27017 --dbpath C:\data\db1 --replSet rs0
mongod --port 27018 --dbpath C:\data\db2 --replSet rs0
mongod --port 27019 --dbpath C:\data\db3 --replSet rs0
上述命令中,--port
指定了端口号,--dbpath
指定了数据存储目录,--replSet
指定了副本集名称为 rs0
。
2. 连接到其中一个实例并初始化副本集:打开 MongoDB 客户端(mongo
),连接到其中一个实例,例如端口 27017
的实例:
mongo --port 27017
在 MongoDB 客户端中执行以下命令初始化副本集:
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "localhost:27017" },
{ _id: 1, host: "localhost:27018" },
{ _id: 2, host: "localhost:27019" }
]
})
上述命令中,_id
为副本集名称,members
数组中定义了副本集中的各个节点。
(二)查看副本集状态
在 MongoDB 客户端中执行以下命令查看副本集状态:
rs.status()
该命令会返回副本集的详细状态信息,包括主节点、从节点的状态,数据同步情况等。
(三)故障转移与自动选举
当主节点发生故障时,副本集中的从节点会自动选举出一个新的主节点,以确保服务的可用性。例如,模拟主节点故障:
- 找到当前主节点:通过
rs.status()
命令查看当前主节点。 - 停止主节点实例:在相应的命令提示符窗口中按
Ctrl + C
停止主节点的 MongoDB 实例。 - 查看副本集状态:再次执行
rs.status()
命令,可以看到从节点已经选举出了新的主节点。
六、配置分片集群
分片集群是 MongoDB 用于处理大规模数据和高并发读写的解决方案。它将数据分散存储在多个分片(Shard)上,每个分片可以是一个独立的副本集。
(一)准备工作
- 启动配置服务器:配置服务器存储分片集群的元数据。假设启动三个配置服务器,分别在不同端口启动:
mongod --configsvr --port 27019 --dbpath C:\data\config1 --replSet configRS
mongod --configsvr --port 27020 --dbpath C:\data\config2 --replSet configRS
mongod --configsvr --port 27021 --dbpath C:\data\config3 --replSet configRS
- 初始化配置服务器副本集:连接到其中一个配置服务器实例,例如端口
27019
的实例:
mongo --port 27019
在 MongoDB 客户端中执行以下命令初始化配置服务器副本集:
rs.initiate({
_id: "configRS",
members: [
{ _id: 0, host: "localhost:27019" },
{ _id: 1, host: "localhost:27020" },
{ _id: 2, host: "localhost:27021" }
]
})
(二)启动分片服务器
假设启动两个分片,每个分片是一个副本集:
- 启动第一个分片的副本集:
mongod --shardsvr --port 27022 --dbpath C:\data\shard1a --replSet shard1
mongod --shardsvr --port 27023 --dbpath C:\data\shard1b --replSet shard1
- 初始化第一个分片的副本集:连接到其中一个实例,例如端口
27022
的实例:
mongo --port 27022
在 MongoDB 客户端中执行:
rs.initiate({
_id: "shard1",
members: [
{ _id: 0, host: "localhost:27022" },
{ _id: 1, host: "localhost:27023" }
]
})
- 同样的方式启动和初始化第二个分片:
mongod --shardsvr --port 27024 --dbpath C:\data\shard2a --replSet shard2
mongod --shardsvr --port 27025 --dbpath C:\data\shard2b --replSet shard2
初始化:
rs.initiate({
_id: "shard2",
members: [
{ _id: 0, host: "localhost:27024" },
{ _id: 1, host: "localhost:27025" }
]
})
(三)启动路由服务器(mongos)
路由服务器负责接收客户端请求,并将请求转发到相应的分片。启动一个 mongos 实例:
mongos --configdb configRS/localhost:27019,localhost:27020,localhost:27021 --port 27017
上述命令中,--configdb
指定了配置服务器副本集的地址,--port
指定了 mongos 监听的端口。
(四)添加分片到集群
连接到 mongos 实例:
mongo --port 27017
在 MongoDB 客户端中执行以下命令添加分片:
sh.addShard("shard1/localhost:27022,localhost:27023")
sh.addShard("shard2/localhost:27024,localhost:27025")
(五)启用分片
在 mongos 客户端中,对需要分片的数据库和集合启用分片:
- 启用数据库分片:
sh.enableSharding("test")
- 指定分片键并启用集合分片:
sh.shardCollection("test.users", { user_id: 1 })
上述命令中,test
是数据库名称,users
是集合名称,{ user_id: 1 }
是分片键,表示根据 user_id
字段进行分片。
七、配置身份验证
(一)创建管理员用户
- 以无身份验证模式启动 MongoDB:如果已经启用了身份验证,可以先修改配置文件,将
security.authorization
设置为disabled
,然后重启 MongoDB。 - 连接到 MongoDB 实例:
mongo
- 切换到
admin
数据库:
use admin
- 创建管理员用户:
db.createUser({
user: "admin",
pwd: "password",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
})
上述命令创建了一个名为 admin
,密码为 password
的管理员用户,该用户具有管理所有数据库用户的权限。
(二)启用身份验证
- 修改配置文件:将配置文件中的
security.authorization
设置为enabled
。
security:
authorization: enabled
- 重启 MongoDB:根据不同操作系统,使用相应的命令重启 MongoDB 服务。
(三)使用身份验证连接
- 使用用户名和密码连接:
mongo -u "admin" -p "password" --authenticationDatabase "admin"
- 在应用程序中使用身份验证:以 Python 的
pymongo
库为例:
from pymongo import MongoClient
client = MongoClient('mongodb://admin:password@localhost:27017/admin')
db = client['test']
collection = db['users']
八、性能优化配置
(一)内存配置
- mmapv1 存储引擎:在早期版本中,mmapv1 是默认存储引擎。可以通过配置
storage.mmapv1.smallFiles
来调整内存使用。smallFiles
设置为true
时,会使用较小的文件,适用于内存有限的情况,但可能会影响性能。
storage:
mmapv1:
smallFiles: true
- WiredTiger 存储引擎:从 MongoDB 3.2 开始,WiredTiger 成为默认存储引擎。可以通过
storage.wiredTiger.engineConfig.cacheSizeGB
配置缓存大小,建议将缓存大小设置为服务器物理内存的 50% 左右,但不要超过物理内存。
storage:
wiredTiger:
engineConfig:
cacheSizeGB: 2
(二)索引优化
- 创建索引:在 MongoDB 客户端中,可以使用
createIndex
方法创建索引。例如,为users
集合的email
字段创建索引:
use test
db.users.createIndex({ email: 1 })
- 分析查询计划:使用
explain
方法分析查询计划,以确定是否使用了正确的索引。例如:
db.users.find({ email: "test@example.com" }).explain()
(三)连接池优化
在应用程序中,合理配置连接池可以提高性能。以 Java 的 MongoClient
为例,可以通过 MongoClientOptions
配置连接池大小等参数:
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.connection.ConnectionPoolSettings;
import org.bson.Document;
import java.util.concurrent.TimeUnit;
public class MongoDBExample {
public static void main(String[] args) {
ConnectionPoolSettings connectionPoolSettings = ConnectionPoolSettings.builder()
.maxSize(100)
.maxWaitTime(1, TimeUnit.MINUTES)
.build();
MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString("mongodb://localhost:27017"))
.applyToConnectionPoolSettings(builder -> builder.applySettings(connectionPoolSettings))
.build();
MongoClient mongoClient = MongoClients.create(settings);
MongoDatabase database = mongoClient.getDatabase("test");
MongoCollection<Document> collection = database.getCollection("users");
}
}
九、常见问题及解决方法
(一)启动失败
- 端口被占用:如果启动 MongoDB 时提示端口被占用,可以通过以下命令查看占用端口的进程并终止它:
- Windows 系统:
netstat -ano | findstr :27017
taskkill /F /PID <PID>
- **Linux 系统**:
sudo lsof -i :27017
sudo kill -9 <PID>
- **MacOS 系统**:
lsof -i :27017
kill -9 <PID>
- 数据目录权限问题:确保 MongoDB 数据目录的权限正确,例如在 Linux 系统中,需要确保
mongodb
用户对数据目录有读写权限。
(二)副本集同步问题
- 网络问题:检查副本集节点之间的网络连接是否正常,可以使用
ping
和telnet
命令测试。 - 配置问题:确保副本集各个节点的配置一致,包括副本集名称、节点地址等。可以通过
rs.conf()
命令查看和修改副本集配置。
(三)分片集群问题
- 配置服务器故障:如果配置服务器出现故障,可能导致分片集群无法正常工作。可以通过查看配置服务器的日志文件(通常在配置文件中指定的日志路径)来排查问题。
- 分片不均衡:如果发现数据在分片上分布不均衡,可以使用
sh.status()
命令查看分片状态,并通过sh.moveChunk
命令手动移动数据块。例如:
sh.moveChunk("test.users", { user_id: MinKey }, "shard1")
通过以上详细的启动与配置指南,你应该能够熟练地启动、配置和优化 MongoDB,使其满足不同应用场景的需求。无论是单机开发环境,还是高可用、大规模数据处理的生产环境,正确的配置和优化都能确保 MongoDB 的性能和稳定性。在实际应用中,还需要根据具体业务需求和系统资源情况进行灵活调整。