MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

MongoDB启动与配置指南

2023-10-166.0k 阅读

一、MongoDB 简介

MongoDB 是一款基于分布式文件存储的开源数据库系统,由 C++ 语言编写。它以其灵活的数据模型(BSON,一种类似 JSON 的二进制格式)、高可扩展性、高性能等特点,在现代应用开发中广泛应用,尤其适用于处理大量非结构化和半结构化数据。

二、安装 MongoDB

在开始启动和配置 MongoDB 之前,首先需要确保 MongoDB 已经正确安装在你的系统上。不同操作系统有不同的安装方式:

(一)Windows 系统安装

  1. 下载安装包:从 MongoDB 官方网站(https://www.mongodb.com/try/download/community)下载适用于 Windows 的安装包。
  2. 运行安装程序:双击下载的 .msi 文件,按照安装向导提示进行安装。在安装过程中,可以选择安装路径、是否添加到系统路径等选项。建议勾选“Add MongoDB to the system PATH”,方便后续操作。
  3. 创建数据目录:默认情况下,MongoDB 需要一个数据存储目录,通常为 C:\data\db。如果该目录不存在,需要手动创建。

(二)Linux 系统安装(以 Ubuntu 为例)

  1. 导入 MongoDB 官方 GPG 密钥
wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | sudo apt-key add -
  1. 创建 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
  1. 更新软件包列表并安装 MongoDB
sudo apt-get update
sudo apt-get install -y mongodb-org

(三)MacOS 系统安装

  1. 使用 Homebrew 安装:如果已经安装了 Homebrew,可以直接在终端执行以下命令安装 MongoDB:
brew install mongodb-community
  1. 创建数据目录:MongoDB 默认的数据目录为 /data/db,需要手动创建并设置权限:
sudo mkdir -p /data/db
sudo chown -R `id -un` /data/db

三、启动 MongoDB

(一)使用默认配置启动

  1. Windows 系统:打开命令提示符,进入 MongoDB 的 bin 目录(如果安装时添加到系统路径,则无需进入该目录),执行以下命令启动 MongoDB:
mongod
  1. Linux 系统:在终端执行以下命令启动 MongoDB 服务:
sudo systemctl start mongod

可以通过以下命令检查服务状态:

sudo systemctl status mongod
  1. 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

(二)使用自定义配置文件启动

  1. 创建配置文件:在合适的目录下创建一个配置文件,例如 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

四、基本配置选项详解

(一)系统日志配置

  1. destination:指定日志输出目的地,可以是 file(文件)或 syslog(系统日志)。如果选择 file,还需要指定 path
  2. path:日志文件的路径。例如:
systemLog:
  destination: file
  path: /var/log/mongodb/mongod.log
  1. logAppend:设置为 true 表示追加日志,false 则表示覆盖日志。

(二)存储配置

  1. dbPath:指定数据库的数据存储目录。例如:
storage:
  dbPath: /var/lib/mongodb
  1. journal:启用或禁用 MongoDB 的日志功能。启用日志可以确保数据的一致性和持久性。
storage:
  journal:
    enabled: true

(三)网络配置

  1. bindIp:指定 MongoDB 绑定的 IP 地址。默认情况下,只绑定 127.0.0.1,即只能本地访问。如果要允许远程访问,可以设置为服务器的公网 IP 地址或 0.0.0.0(允许所有 IP 访问,但安全性较低)。
net:
  bindIp: 127.0.0.1
  1. port:指定 MongoDB 监听的端口,默认是 27017
net:
  port: 27017

(四)安全配置

  1. authorization:启用身份验证。在生产环境中,强烈建议启用身份验证以保护数据库安全。设置为 enabled 表示启用身份验证。
security:
  authorization: enabled
  1. keyFile:用于副本集和分片集群的内部身份验证。每个节点都必须有相同的 keyFile。例如:
security:
  keyFile: /path/to/keyfile

五、配置副本集

副本集是 MongoDB 提供的一种高可用性机制,由多个 MongoDB 节点组成,其中一个为主节点(Primary),其余为从节点(Secondary)。主节点负责处理写操作,从节点复制主节点的数据。

(一)初始化副本集

  1. 启动多个 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()

该命令会返回副本集的详细状态信息,包括主节点、从节点的状态,数据同步情况等。

(三)故障转移与自动选举

当主节点发生故障时,副本集中的从节点会自动选举出一个新的主节点,以确保服务的可用性。例如,模拟主节点故障:

  1. 找到当前主节点:通过 rs.status() 命令查看当前主节点。
  2. 停止主节点实例:在相应的命令提示符窗口中按 Ctrl + C 停止主节点的 MongoDB 实例。
  3. 查看副本集状态:再次执行 rs.status() 命令,可以看到从节点已经选举出了新的主节点。

六、配置分片集群

分片集群是 MongoDB 用于处理大规模数据和高并发读写的解决方案。它将数据分散存储在多个分片(Shard)上,每个分片可以是一个独立的副本集。

(一)准备工作

  1. 启动配置服务器:配置服务器存储分片集群的元数据。假设启动三个配置服务器,分别在不同端口启动:
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
  1. 初始化配置服务器副本集:连接到其中一个配置服务器实例,例如端口 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" }
  ]
})

(二)启动分片服务器

假设启动两个分片,每个分片是一个副本集:

  1. 启动第一个分片的副本集
mongod --shardsvr --port 27022 --dbpath C:\data\shard1a --replSet shard1
mongod --shardsvr --port 27023 --dbpath C:\data\shard1b --replSet shard1
  1. 初始化第一个分片的副本集:连接到其中一个实例,例如端口 27022 的实例:
mongo --port 27022

在 MongoDB 客户端中执行:

rs.initiate({
  _id: "shard1",
  members: [
    { _id: 0, host: "localhost:27022" },
    { _id: 1, host: "localhost:27023" }
  ]
})
  1. 同样的方式启动和初始化第二个分片
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 客户端中,对需要分片的数据库和集合启用分片:

  1. 启用数据库分片
sh.enableSharding("test")
  1. 指定分片键并启用集合分片
sh.shardCollection("test.users", { user_id: 1 })

上述命令中,test 是数据库名称,users 是集合名称,{ user_id: 1 } 是分片键,表示根据 user_id 字段进行分片。

七、配置身份验证

(一)创建管理员用户

  1. 以无身份验证模式启动 MongoDB:如果已经启用了身份验证,可以先修改配置文件,将 security.authorization 设置为 disabled,然后重启 MongoDB。
  2. 连接到 MongoDB 实例
mongo
  1. 切换到 admin 数据库
use admin
  1. 创建管理员用户
db.createUser({
  user: "admin",
  pwd: "password",
  roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
})

上述命令创建了一个名为 admin,密码为 password 的管理员用户,该用户具有管理所有数据库用户的权限。

(二)启用身份验证

  1. 修改配置文件:将配置文件中的 security.authorization 设置为 enabled
security:
  authorization: enabled
  1. 重启 MongoDB:根据不同操作系统,使用相应的命令重启 MongoDB 服务。

(三)使用身份验证连接

  1. 使用用户名和密码连接
mongo -u "admin" -p "password" --authenticationDatabase "admin"
  1. 在应用程序中使用身份验证:以 Python 的 pymongo 库为例:
from pymongo import MongoClient

client = MongoClient('mongodb://admin:password@localhost:27017/admin')
db = client['test']
collection = db['users']

八、性能优化配置

(一)内存配置

  1. mmapv1 存储引擎:在早期版本中,mmapv1 是默认存储引擎。可以通过配置 storage.mmapv1.smallFiles 来调整内存使用。smallFiles 设置为 true 时,会使用较小的文件,适用于内存有限的情况,但可能会影响性能。
storage:
  mmapv1:
    smallFiles: true
  1. WiredTiger 存储引擎:从 MongoDB 3.2 开始,WiredTiger 成为默认存储引擎。可以通过 storage.wiredTiger.engineConfig.cacheSizeGB 配置缓存大小,建议将缓存大小设置为服务器物理内存的 50% 左右,但不要超过物理内存。
storage:
  wiredTiger:
    engineConfig:
      cacheSizeGB: 2

(二)索引优化

  1. 创建索引:在 MongoDB 客户端中,可以使用 createIndex 方法创建索引。例如,为 users 集合的 email 字段创建索引:
use test
db.users.createIndex({ email: 1 })
  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");
    }
}

九、常见问题及解决方法

(一)启动失败

  1. 端口被占用:如果启动 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>
  1. 数据目录权限问题:确保 MongoDB 数据目录的权限正确,例如在 Linux 系统中,需要确保 mongodb 用户对数据目录有读写权限。

(二)副本集同步问题

  1. 网络问题:检查副本集节点之间的网络连接是否正常,可以使用 pingtelnet 命令测试。
  2. 配置问题:确保副本集各个节点的配置一致,包括副本集名称、节点地址等。可以通过 rs.conf() 命令查看和修改副本集配置。

(三)分片集群问题

  1. 配置服务器故障:如果配置服务器出现故障,可能导致分片集群无法正常工作。可以通过查看配置服务器的日志文件(通常在配置文件中指定的日志路径)来排查问题。
  2. 分片不均衡:如果发现数据在分片上分布不均衡,可以使用 sh.status() 命令查看分片状态,并通过 sh.moveChunk 命令手动移动数据块。例如:
sh.moveChunk("test.users", { user_id: MinKey }, "shard1")

通过以上详细的启动与配置指南,你应该能够熟练地启动、配置和优化 MongoDB,使其满足不同应用场景的需求。无论是单机开发环境,还是高可用、大规模数据处理的生产环境,正确的配置和优化都能确保 MongoDB 的性能和稳定性。在实际应用中,还需要根据具体业务需求和系统资源情况进行灵活调整。