MongoDB 使用指南

概述

MongoDB 是一个跨平台的,以 JSON 为数据模型的文档数据库,是当前 NoSQL 数据库产品中最热门的一种。它介于关系数据库和非关系数据库之间,是非关系数据库当中功能最丰富,最像关系数据库的产品。

相关网址

名称 地址
官方网址 https://www.mongodb.com/
服务端网址 https://www.mongodb.com/try/download/community
图形界面管理工具 https://www.mongodb.com/products/compass

安装程序

在 ubuntu 服务器上安装 mongodb

在安装前要特别说明的是整篇文章中我们使用的是 ubuntu 系统进行学习和操作

  • 准备工作

关闭 ubuntu 系统的防火墙

ufw disable
  • 下载程序

其中 mongodb-org-mongosmongos 搭建分片集群的路由程序,mongodb-org-servermongod 数据库的进程守护程序,mongodb-org-shellshell 命令行工具程序

wget https://repo.mongodb.org/apt/ubuntu/dists/focal/mongodb-org/5.0/multiverse/binary-amd64/mongodb-org-mongos_5.0.8_amd64.deb
wget https://repo.mongodb.org/apt/ubuntu/dists/focal/mongodb-org/5.0/multiverse/binary-amd64/mongodb-org-server_5.0.8_amd64.deb
wget https://repo.mongodb.org/apt/ubuntu/dists/focal/mongodb-org/5.0/multiverse/binary-amd64/mongodb-org-shell_5.0.8_amd64.deb
  • 安装程序

程序安装完成后,默认的数据库目录和日志目录存放在 /var/lib/mongodb/var/log/mongodb ,默认的配置文件目录存放在 /etc/mongod.conf

dpkg -i mongodb-org-mongos_5.0.8_amd64.deb
dpkg -i mongodb-org-server_5.0.8_amd64.deb
dpkg -i mongodb-org-shell_5.0.8_amd64.deb
  • 验证程序是否安装成功
mongos --version
mongod --version
mongo --version

使用 docker 的方式安装 mongodb

使用 docker 的方式安装 mongodb 需要你提前安装好 docker ,如果你还没有使用过 docker ,你可以通过《Docker使用指南》来了解它

  • 首先,创建数据卷 mongo-dbmongo-configdb 分别持久化数据文件和配置文件,再创建 mongo-network 网络
docker network create mongo-network
docker volume create mongo-db
docker volume create mongo-configdb
  • 然后,运行 mongo 容器并启动 mongodb 服务
docker run -d -p 27017:27017 --network mongo-network --name mongo -v mongo-db:/data/db -v mongo-configdb:/data/configdb mongo:latest

注意:如果我们要为 mongodb 数据库设置用户名和密码可以添加 -e MONGO_INITDB_ROOT_USERNAME=username-e MONGO_INITDB_ROOT_PASSWORD=password 参数来实现

  • 其次,进入到 mongo 容器中
docker exec -it mongo bash
  • 最后,在 mongo 容器中使用 mongo shell 连接数据库
mongo mongodb://localhost:27017

到这里我们成功的使用 docker 的方式安装好了 mongodb 数据库并进入到了数据库中,下面的基本操作我们就在这里面进行

基本操作

术语与概念

在学习 MongoDB 时我们用它与 MySQL 数据库进行类比,可以更快的理解它的基础概念

MySQL MongoDB 解释 / 说明
database database 数据库
table collection 表 / 集合
row document 记录行 / 文档
column field 字段 / 域
index index 索引

数据库操作

  • 创建数据库
use db1
  • 查看数据库
show dbs

注意:到这里你通过 show dbs 是无法查看到 db1 数据库的,你需要创建一个集合或者直接插入一条数据才能查看到 db1 数据库

  • 删除数据库
db.dropDatabase()

注意:在生产环境中谨慎使用这条命令

集合操作

  • 创建集合
db.createCollection("users")
  • 查看集合
show collections
  • 删除集合
db.users.drop()

注意:在生产环境中谨慎使用这条命令

文档的插入操作

  • 插入文档
db.fruits.insert(
    [
        { "name": "apple", "price": 10, "color": ["red", "green"], },
        { "name": "banana", "price": 8, "color": ["yellow", "green"], },
        { "name": "mongo", "price": 12, "color": ["yellow", "green"], },
    ]
)

注意:在 MongoDB 中不需要提前创建集合就可以直接插入文档,在插入文档的同时自动创建集合

  • 插入一条文档
db.users.insertOne(
    {
        "username": "zhangsan",
        "password": "88888888",
        "form": { "country": "China", "city": "Beijing" }
    }
)
  • 插入多条文档
db.users.insertMany(
    [
        {
            "username": "lisi",
            "password": "4444",
            "form": { "country": "China", "city": "Shanghai" }
        },
        {
            "username": "wanger",
            "password": "666666",
            "form": { "country": "China", "city": "Shenzhen" }
        },
    ]
)

文档的查询操作

  • 单条件查询文档
db.users.find(
    { "username": "zhangsan" }
)

注意:你可以使用 db.users.find().pretty() 格式化显示返回结果

  • 多条件 and 查询文档
db.users.find(
    { "username": "zhangsan", "password": "88888888" }
)
  • 多条件 and 查询文档的另一种形式
db.users.find(
    {
        $and: [
            { "username": "zhangsan" },
            { "password": "88888888" }
        ]
    }
)
  • 多条件 or 查询文档
db.users.find(
    {
        $or: [
            { "username": "zhangsan" },
            { "password": "88888888" }
        ]
    }
)
  • 正则表达式查询文档
db.users.find(
    { username: /^zhang/ }
)

查询条件对照表

SQL MQL 解释 / 说明
a = 1 {a: 1} 等于
a <> 1 {a: {$ne: 1}} 不等于
a > 1 {a: {$gt: 1}} 大于
a >= 1 {a: {$gte: 1}} 大于等于
a < 1 {a: {$lt: 1}} 小于
a <= 1 {a: {$lte: 1}} 小于等于

查询逻辑对照表

SQL MQL 解释 / 说明
a = 1 AND B = 1 {a: 1, b: 1} 或 {$and: [{a: 1}, {b: 1}]} 逻辑与
a = 1 OR B = 1 {$or: [{a: 1}, {b: 1}]} 逻辑或
a IS NULL {a: {$exists: false}} 是否存在
a IN (1, 2, 3) {a: {$in: [1, 2, 3]}} 包含其中一项
  • 查询子文档
db.users.find(
    { "form.country": "China" }
)
  • 控制查询返回的字段
db.fruits.find(
    { "name": "apple" }, { "_id": 0, "name": 1, "color": 1 }
)

注意:其中 _id name color0 表示不返回字段,其中的 1 表示返回字段

文档的更新操作

  • 更新一条文档
db.fruits.updateOne(
    { "name": "banana" }, { $set: { "price": 20 } }
)

注意:updateOne 不管查询到多少条文档都只更新第一条文档

  • 更新多条文档
db.fruits.updateMany(
    { "name": "banana" }, { $set: { "price": 20 } }
)

注意:updateMany 查询到多少条文档就更新多少条文档

更新数组操作符

操作符号 解释 / 说明
$push 增加一个对象到数组底部
$pushAll 增加多个对象到数组底部
$pop 从数组底部删除一个对象
$pull 如果匹配指定的值,从数组中删除相应的对象
$pullAll 如果匹配任意的值,从数组中删除相应的对象
$andToSet 如果不存在则增加一个值到数组

文档的删除操作

  • 删除 price = 10 的文档
db.fruits.remove(
    { "price": 10 }
)
  • 删除 price < 12 的文档
db.fruits.remove(
    { "price": { $lt: 12 } }
)
  • 删除所有文档
db.fruits.remove({})

注意:在生产环境中谨慎使用这条命令

聚合查询

MongoDB 中聚合查询 aggregate 是以管道的形式进行处理数据并主要用于处理数据统计、平均值、求和等

  • 聚合查询
db.fruits.aggregate(
    [
        { $group: { _id: "$name", total: { $sum: 1 } } },
        { $project: { name: "$name", total: "$total" } },
    ]
)

注意:这里对 fruits 集合进行聚合查询,先按 name 字段进行分组并合计分组的数量,然后在返回 name 字段和分组后的 total 字段进行显示

常用聚合查询对照表

SQL MQL 解释 / 说明
WHERE $match 过滤
AS $project 投影
ORDER BY $sort 排序
GROUP BY $group 分组
SKIP $skip 结果限制
LIMIT $limit 结果限制
LEFT OUTER JOIN $lookup 左外连接

索引

db.fruits.createIndex(
    { name: 1 },
    { background: true },
)

注意:创建索引最好的方法是使用 ESR 原则,精确( Equal )匹配的字段放在最前面,排序( Sort )条件放中间,范围( Range )匹配的字段放最后

备份与恢复

  • 备份 db1 数据库中的 users 集合
mongodump -h 127.0.0.1:27017 -d db1 -c users

注意:备份时不指定路径,默认备份在 /dump 目录中,如果数据库有权限请加上 -u username -p password--authenticationDatabase admin 参数执行命令

  • 恢复 db1 数据库中的 users 集合
mongorestore -h 127.0.0.1:27017 -u username -p password -d db1 -c users /dump/db1/users.bson --authenticationDatabase admin

注意:恢复时指定路径在 /dump 目录中的具体文件,如果数据库有权限请加上 -u username -p password--authenticationDatabase admin 参数执行命令

复制集

MongoDB 中复制集也称为副本集,是将数据同步在多个服务器并存储数据的副本,复制集提高了数据的可用性并保证了数据的安全。官方推荐的复制集最小搭建单位是 1 个主节点 2 个从节点,节点的扩展是以奇数的形式进行比如 3 5 7 以此类推,奇数节点是为了保证快速选举出主节点

在 ubuntu 服务器上搭建复制集

在搭建复制集时需要提前在 ubuntu 服务器上安装 mongodb,提前将域名映射到对应的服务器上,注意关闭所有服务器上的防火墙

  • 服务器信息
服务器名称 域名和端口
mongo-rs1-server1 mongo-rs1-server1.example.com:27017
mongo-rs1-server2 mongo-rs1-server2.example.com:27017
mongo-rs1-server3 mongo-rs1-server3.example.com:27017
  • 在所有搭建复制集的服务器上编辑 /etc/mongod.conf 配置文件

更多配置文件的选项请参照 http://docs.mongodb.org/manual/reference/configuration-options/

nano /etc/mongod.conf

/etc/mongod.conf

# 数据存放的位置和方式
storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true
# 日志存放的位置和方式
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log
# 网络接口
net:
  port: 27017
  bindIp: 0.0.0.0
# 进程运行方式
processManagement:
  timeZoneInfo: /usr/share/zoneinfo
# 复制集
replication:
  replSetName: rs1
  • 重启 mongod.service 服务
systemctl restart mongod.service
  • mongo-rs1-server1 服务器上通过 shell 进入数据库
mongo mongodb://mongo-rs1-server1.example.com:27017
  • 初始化复制集方式一
rs.initiate()
rs.add("mongo-rs1-server2.example.com:27017")
rs.add("mongo-rs1-server3.example.com:27017")
  • 初始化复制集方式二
rs.initiate({
    _id: "rs1",
    members: [{
        _id: 0,
        host: "mongo-rs1-server1.example.com:27017"
    }, {
        _id: 1,
        host: "mongo-rs1-server2.example.com:27017"
    }, {
        _id: 2,
        host: "mongo-rs1-server3.example.com:27017"
    }]
})
  • 验证复制集是否搭建成功
rs.status()
  • 在复制集中测试数据
# 打开终端 1 进入 mongo-rs1-server1 节点
mongo mongodb://mongo-rs1-server1.example.com:27017
# 在 mongo-rs1-server1 节点中插入一条数据
db.test.insert({x:1})
# 打开终端 2 进入 mongo-rs1-server2 节点
mongo mongodb://mongo-rs1-server2.example.com:27017
# 在 mongo-rs1-server2 节点中查看数据
db.test.find()

注意:在子节点执行 db.test.find() 报错 not master and slaveOk=false 时,请在子节点中执行 rs.secondaryOk() 指令

使用 docker 的方式搭建复制集

  • 创建容器的网络和数据卷,通过 mongo:later 镜像启动 3 个容器并设置复制集名称为 rs1
docker network create mongo-network
docker volume create mongo-rs1-server1-db
docker volume create mongo-rs1-server1-configdb

docker run -d -p 37017:27017 --network mongo-network --name mongo-rs1-server1 -v mongo-rs1-server1-db:/data/db -v mongo-rs1-server1-configdb:/data/configdb mongo:latest --replSet=rs1 --port 27017 --bind_ip_all

docker network create mongo-network
docker volume create mongo-rs1-server2-db
docker volume create mongo-rs1-server2-configdb

docker run -d -p 37018:27017 --network mongo-network --name mongo-rs1-server2 -v mongo-rs1-server2-db:/data/db -v mongo-rs1-server2-configdb:/data/configdb mongo:latest --replSet=rs1 --port 27017 --bind_ip_all

docker network create mongo-network
docker volume create mongo-rs1-server3-db
docker volume create mongo-rs1-server3-configdb

docker run -d -p 37019:27017 --network mongo-network --name mongo-rs1-server3 -v mongo-rs1-server3-db:/data/db -v mongo-rs1-server3-configdb:/data/configdb mongo:latest --replSet=rs1 --port 27017 --bind_ip_all
  • 进入到 mongo-rs1-server1 容器中
docker exec -it mongo-rs1-server1 bash
  • mongo-rs1-server1 服务器上通过 shell 进入数据库
mongo mongodb://mongo-rs1-server1:27017
  • 初始化复制集方式一
rs.initiate()
rs.add("mongo-rs1-server2:27017")
rs.add("mongo-rs1-server3:27017")
  • 初始化复制集方式二
rs.initiate({
    _id: "rs1",
    members: [{
        _id: 0,
        host: "mongo-rs1-server1:27017"
    }, {
        _id: 1,
        host: "mongo-rs1-server2:27017"
    }, {
        _id: 2,
        host: "mongo-rs1-server3:27017"
    }]
})
  • 验证复制集是否搭建成功
rs.status()

事务处理

通过下面写操作事务和读操作事务的步骤就可以实现读写分离

  • 写操作事务
db.test.insert({x:1},{writeConcern:{w:"majority"}})

注意:majority 表示在复制集中数据已经写入到大多数节点上时应答

  • 读操作事务
db.test.find({x:1}).readPref("secondary").readConcern("majority")

注意:majority 表示在复制集中数据已经同步到大多数节点上时应答

事务操作的选项表

名称(readPreference) 解释 / 说明
primary 默认模式,所有读取都在主节点操作
primaryPreferred 正常情况在主节点操作,当主节点不可用时在从节点操作
secondary 所有读取都在从节点操作
secondaryPreferred 正常情况在从节点操作,当从节点不可用时在主节点操作
nearest 在网络延迟最小的节点操作

分片集群

当你的数据量日益增长达到 1TB 2TB … 甚至更多时,这时我们就需要用到分片技术来横向扩容。当你的单库数据达到 10TB 甚至更多需要恢复时,我们会花 12 天甚至更多的时间才能完成,这时我们可以使用到分片技术保证数据的完整性。当你的数据需要支撑全球业务时,这时我们也可以使用分片技术跨地域秒级读取数据。完整的分片集群包括路由节点(Mongos)提供集群入口,配置节点(Config)以复制集为单位提供集群元数据和分片数据的映射,数据节点(Shard)以复制集为单位横向扩展,最大为 1024 分片,分片数据不重复需要所有分片在一起才可以完整工作。

分片集群概念表

名称 解释 / 说明
片键 / shard key 文档中的一个字段
文档 / doc 包含 片键/shard key 的一行数据
块 / Chunk 包含 n 个 文档/doc
分片 / Shard 包含 n 个 块/Chunk
集群 / Cluster 包含 n 个 分片/Shard

片键选择表

片键 基数 写分布 定向查询
{ _id: 1 } O X X
{ _id: “hashed” } O O X
{ user_id: 1 } X O O
{ user_id: 1, time: 1 } O O O

在 ubuntu 服务器上搭建分片集群

在搭建分片集群时需要提前在所有服务器上搭建单机服务,提前将域名映射到对应的服务器上,注意关闭所有服务器上的防火墙

  • 准备工作

关闭 ubuntu 系统的防火墙

ufw disable
  • 服务器信息
服务器名称 域名和端口
mongo-shard1-server1 mongo-shard1-server1.example.com:27017
mongo-shard1-server2 mongo-shard1-server2.example.com:27017
mongo-shard2-server1 mongo-shard2-server1.example.com:27017
mongo-shard2-server2 mongo-shard2-server2.example.com:27017
mongo-config1-server1 mongo-config1-server1.example.com:27017
mongo-config1-server2 mongo-config1-server2.example.com:27017
mongo-mongos1-server1 mongo-mongos1-server1.example.com:27017

搭建分片服务 shardsvr

  • 在所有搭建分片集群的 shard1 服务器上编辑 /etc/mongod.conf 配置文件

更多配置文件的选项请参照 http://docs.mongodb.org/manual/reference/configuration-options/

nano /etc/mongod.conf

/etc/mongod.conf

# 数据存放的位置和方式
storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true
# 日志存放的位置和方式
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log
# 网络接口
net:
  port: 27017
  bindIp: 0.0.0.0
# 进程运行方式
processManagement:
  timeZoneInfo: /usr/share/zoneinfo
# 复制集
replication:
  replSetName: shard1
# 分片集群分片服务
sharding:
  clusterRole: shardsvr
  • 在所有搭建分片集群的 shard1 服务器上重启 mongod.service 服务
systemctl restart mongod.service
  • mongo-shard1-server1 服务器上通过 shell 进入数据库
mongo mongodb://mongo-shard1-server1.example.com:27017
  • 初始化复制集 shard1
rs.initiate({
    _id: "shard1",
    members: [{
        _id: 0,
        host: "mongo-shard1-server1.example.com:27017"
    }, {
        _id: 1,
        host: "mongo-shard1-server2.example.com:27017"
    }]
})
  • 验证复制集是否搭建成功
rs.status()

搭建分片服务 shardsvr

  • 在所有搭建分片集群的 shard2 服务器上编辑 /etc/mongod.conf 配置文件

更多配置文件的选项请参照 http://docs.mongodb.org/manual/reference/configuration-options/

nano /etc/mongod.conf

/etc/mongod.conf

# 数据存放的位置和方式
storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true
# 日志存放的位置和方式
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log
# 网络接口
net:
  port: 27017
  bindIp: 0.0.0.0
# 进程运行方式
processManagement:
  timeZoneInfo: /usr/share/zoneinfo
# 复制集
replication:
  replSetName: shard2
# 分片集群的分片服务
sharding:
  clusterRole: shardsvr
  • 在所有搭建分片集群的 shard2 服务器上重启 mongod.service 服务
systemctl restart mongod.service
  • mongo-shard2-server1 服务器上通过 shell 进入数据库
mongo mongodb://mongo-shard2-server1.example.com:27017
  • 初始化复制集 shard2
rs.initiate({
    _id: "shard2",
    members: [{
        _id: 0,
        host: "mongo-shard2-server1.example.com:27017"
    }, {
        _id: 1,
        host: "mongo-shard2-server2.example.com:27017"
    }]
})
  • 验证复制集是否搭建成功
rs.status()

搭建配置服务 configsvr

  • 在所有搭建分片集群的 config1 服务器上编辑 /etc/mongod.conf 配置文件

更多配置文件的选项请参照 http://docs.mongodb.org/manual/reference/configuration-options/

nano /etc/mongod.conf

/etc/mongod.conf

# 数据存放的位置和方式
storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true
# 日志存放的位置和方式
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log
# 网络接口
net:
  port: 27017
  bindIp: 0.0.0.0
# 进程运行方式
processManagement:
  timeZoneInfo: /usr/share/zoneinfo
# 复制集
replication:
  replSetName: config1
# 分片集群的配置服务
sharding:
  clusterRole: configsvr
  • 在所有搭建分片集群的 config1 服务器上重启 mongod.service 服务
systemctl restart mongod.service
  • mongo-config1-server1 服务器上通过 shell 进入数据库
mongo mongodb://mongo-config1-server1.example.com:27017
  • 初始化复制集 config1
rs.initiate({
    _id: "config1",
    members: [{
        _id: 0,
        host: "mongo-config1-server1.example.com:27017"
    }, {
        _id: 1,
        host: "mongo-config1-server2.example.com:27017"
    }]
})
  • 验证复制集是否搭建成功
rs.status()

搭建路由服务 mongos

  • 在所有搭建分片集群的 mongos1 服务器上编辑 /etc/mongos.conf 配置文件

更多配置文件的选项请参照 http://docs.mongodb.org/manual/reference/configuration-options/

nano /etc/mongos.conf

/etc/mongos.conf

# 日志存放的位置和方式
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log
# 网络接口
net:
  port: 27017
  bindIp: 0.0.0.0
# 进程运行方式
processManagement:
  timeZoneInfo: /usr/share/zoneinfo
  fork: true
# 复制集
replication:
  localPingThresholdMs: 15
# 分片集群,这里关联配置服务器
sharding:
  configDB: config/mongo-config1-server1.example.com:27017,mongo-config1-server2.example.com:27017,mongo-config1-server3.example.com:27017
  • 在所有搭建分片集群的 mongos1 服务器上编辑 /etc/mongod.conf 配置文件

更多配置文件的选项请参照 http://docs.mongodb.org/manual/reference/configuration-options/

nano /etc/mongod.con

/etc/mongod.conf

  • 在所有搭建分片集群的 mongos1 服务器上启动路由服务
mongos -f /etc/mongos.conf
  • mongo-mongos1-server1 服务器上通过 shell 进入数据库
mongo mongodb://mongo-mongos1-server1.example.com:27017
  • 通过路由服务 mongos 添加分片服务 shardsvr 关系到配置服务 configsvr
sh.addShard("shard1/mongo-shard1-server1.example.com:27017,mongo-shard1-server2.example.com:27017")
sh.addShard("shard2/mongo-shard2-server1.example.com:27017,mongo-shard2-server2.example.com:27017")
  • 验证分片集群是否搭建成功
sh.status()
  • 设置需要分片的数据库和集合

选择片键请参照上面的片键选择表,设置 db1 为分片数据库,设置 db1.users 为分片集合,设置 {_id:"hashed"} 为哈希片键

sh.enableSharding("db1")
sh.shardCollection("db1.users",{_id:"hashed"})
  • 测试分片是否成功

通过切换数据库到 db1 中,在执行循环插入 1000 条数据

use db1
for (i = 0; i < 1000; i++) {
    db.users.insert({ i: i })
}
  • 在宿主机上通过 compass 连接分片集群
mongodb://mongo-mongos1-server1.example.com:27017

使用 docker 的方式搭建分片集群

  • 服务器信息
服务器名称 复制集名称 解释 / 说明
mongo-shard1-server1 shard1 分片复制集 1 的第 1 台服务器
mongo-shard1-server2 shard1 分片复制集 1 的第 2 台服务器
mongo-shard1-server3 shard1 分片复制集 1 的第 3 台服务器
mongo-shard2-server1 shard2 分片复制集 2 的第 1 台服务器
mongo-shard2-server2 shard2 分片复制集 2 的第 2 台服务器
mongo-shard2-server2 shard2 分片复制集 2 的第 3 台服务器
mongo-config1-server1 config1 配置复制集 1 的第 1台服务器
mongo-config1-server2 config1 配置复制集 1 的第 2台服务器
mongo-config1-server3 config1 配置复制集 1 的第 3台服务器
mongo-mongos1-server1 - 路由的第 1 台服务器,提供集群入口
mongo-mongos1-server2 - 路由的第 2 台服务器,提供集群入口
mongo-mongos1-server3 - 路由的第 3 台服务器,提供集群入口

搭建分片服务 shardsvr

  • 在终端中执行下面命令,创建名为 shard13shardsvr 容器
docker network create mongo-network
docker volume create mongo-shard1-server1-db
docker volume create mongo-shard1-server1-configdb

docker run -d -p 38018:27018 --network mongo-network --name mongo-shard1-server1 -v mongo-shard1-server1-db:/data/db -v mongo-shard1-server1-configdb:/data/configdb mongo:latest --replSet=shard1 --shardsvr --port 27018 --bind_ip_all

docker network create mongo-network
docker volume create mongo-shard1-server2-db
docker volume create mongo-shard1-server2-configdb

docker run -d -p 38019:27018 --network mongo-network --name mongo-shard1-server2 -v mongo-shard1-server2-db:/data/db -v mongo-shard1-server2-configdb:/data/configdb mongo:latest --replSet=shard1 --shardsvr --port 27018 --bind_ip_all

docker network create mongo-network
docker volume create mongo-shard1-server3-db
docker volume create mongo-shard1-server3-configdb

docker run -d -p 38020:27018 --network mongo-network --name mongo-shard1-server3 -v mongo-shard1-server3-db:/data/db -v mongo-shard1-server3-configdb:/data/configdb mongo:latest --replSet=shard1 --shardsvr --port 27018 --bind_ip_all
  • 进入到 mongo-shard1-server1 容器中
docker exec -it mongo-shard1-server1 bash
  • mongo-shard1-server1 服务器上通过 shell 进入数据库
mongo mongodb://mongo-shard1-server1:27018
  • 初始化复制集 shard1
rs.initiate({
    _id: "shard1",
    members: [{
        _id: 0,
        host: "mongo-shard1-server1:27018"
    }, {
        _id: 1,
        host: "mongo-shard1-server2:27018"
    }, {
        _id: 2,
        host: "mongo-shard1-server3:27018"
    }]
})
  • 验证复制集是否搭建成功
rs.status()

搭建分片服务 shardsvr

  • 在终端中执行下面命令,创建名为 shard23shardsvr 容器
docker network create mongo-network
docker volume create mongo-shard2-server1-db
docker volume create mongo-shard2-server1-configdb

docker run -d -p 48018:27018 --network mongo-network --name mongo-shard2-server1 -v mongo-shard2-server1-db:/data/db -v mongo-shard2-server1-configdb:/data/configdb mongo:latest --replSet=shard2 --shardsvr --port 27018 --bind_ip_all

docker network create mongo-network
docker volume create mongo-shard2-server2-db
docker volume create mongo-shard2-server2-configdb

docker run -d -p 48019:27018 --network mongo-network --name mongo-shard2-server2 -v mongo-shard2-server2-db:/data/db -v mongo-shard2-server2-configdb:/data/configdb mongo:latest --replSet=shard2 --shardsvr --port 27018 --bind_ip_all

docker network create mongo-network
docker volume create mongo-shard2-server3-db
docker volume create mongo-shard2-server3-configdb

docker run -d -p 48020:27018 --network mongo-network --name mongo-shard2-server3 -v mongo-shard2-server3-db:/data/db -v mongo-shard2-server3-configdb:/data/configdb mongo:latest --replSet=shard2 --shardsvr --port 27018 --bind_ip_all
  • 进入到 mongo-shard2-server1 容器中
docker exec -it mongo-shard2-server1 bash
  • mongo-shard2-server1 服务器上通过 shell 进入数据库
mongo mongodb://mongo-shard2-server1:27018
  • 初始化复制集 shard2
rs.initiate({
    _id: "shard2",
    members: [{
        _id: 0,
        host: "mongo-shard2-server1:27018"
    }, {
        _id: 1,
        host: "mongo-shard2-server2:27018"
    }, {
        _id: 2,
        host: "mongo-shard2-server3:27018"
    }]
})
  • 验证复制集是否搭建成功
rs.status()

搭建配置服务 configsvr

  • 在终端中执行下面命令,创建名为 config13configsvr 容器
docker network create mongo-network
docker volume create mongo-config1-server1-db
docker volume create mongo-config1-server1-configdb

docker run -d -p 28019:27019 --network mongo-network --name mongo-config1-server1 -v mongo-config1-server1-db:/data/db -v mongo-config1-server1-configdb:/data/configdb mongo:latest --replSet=config1 --configsvr --port 27019 --bind_ip_all

docker network create mongo-network
docker volume create mongo-config1-server2-db
docker volume create mongo-config1-server2-configdb

docker run -d -p 28020:27019 --network mongo-network --name mongo-config1-server2 -v mongo-config1-server2-db:/data/db -v mongo-config1-server2-configdb:/data/configdb mongo:latest --replSet=config1 --configsvr --port 27019 --bind_ip_all

docker network create mongo-network
docker volume create mongo-config1-server3-db
docker volume create mongo-config1-server3-configdb

docker run -d -p 28021:27019 --network mongo-network --name mongo-config1-server3 -v mongo-config1-server3-db:/data/db -v mongo-config1-server3-configdb:/data/configdb mongo:latest --replSet=config1 --configsvr --port 27019 --bind_ip_all
  • 进入到 mongo-config1-server1 容器中
docker exec -it mongo-config1-server1 bash
  • mongo-config1-server1 服务器上通过 shell 进入数据库
mongo mongodb://mongo-config1-server1:27019
  • 初始化复制集 config1
rs.initiate({
    _id: "config1",
    members: [{
        _id: 0,
        host: "mongo-config1-server1:27019"
    }, {
        _id: 1,
        host: "mongo-config1-server2:27019"
    }, {
        _id: 2,
        host: "mongo-config1-server3:27019"
    }]
})
  • 验证复制集是否搭建成功
rs.status()

搭建路由服务 mongos

  • 在终端中执行下面命令,创建名为 mongos13mongos 容器
docker network create mongo-network
docker volume create mongo-mongos1-server1-db
docker volume create mongo-mongos1-server1-configdb

docker run -d -p 27017:27017 --network mongo-network --name mongo-mongos1-server1 --entrypoint mongos -v mongo-mongos1-server1-db:/data/db -v mongo-mongos1-server1-configdb:/data/configdb mongo:latest --configdb config/mongo-config1-server1:27019,mongo-config1-server2:27019,mongo-config1-server3:27019 --port 27017 --bind_ip_all

docker network create mongo-network
docker volume create mongo-mongos1-server2-db
docker volume create mongo-mongos1-server2-configdb

docker run -d -p 27018:27017 --network mongo-network --name mongo-mongos1-server2 --entrypoint mongos -v mongo-mongos1-server2-db:/data/db -v mongo-mongos1-server2-configdb:/data/configdb mongo:latest --configdb config/mongo-config1-server1:27019,mongo-config1-server2:27019,mongo-config1-server3:27019 --port 27017 --bind_ip_all

docker network create mongo-network
docker volume create mongo-mongos1-server3-db
docker volume create mongo-mongos1-server3-configdb

docker run -d -p 27019:27017 --network mongo-network --name mongo-mongos1-server3 --entrypoint mongos -v mongo-mongos1-server3-db:/data/db -v mongo-mongos1-server3-configdb:/data/configdb mongo:latest --configdb config/mongo-config1-server1:27019,mongo-config1-server2:27019,mongo-config1-server3:27019 --port 27017 --bind_ip_all
  • 进入到 mongo-mongos1-server1 容器中
docker exec -it mongo-mongos1-server1 bash
  • mongo-mongos1-server1 服务器上通过 shell 进入数据库
mongo mongodb://mongo-mongos1-server1:27017
  • 通过路由服务 mongos 添加分片服务 shardsvr 关系到配置服务 configsvr
sh.addShard("shard1/mongo-shard1-server1:27018,mongo-shard1-server2:27018,mongo-shard1-server3:27018")
sh.addShard("shard2/mongo-shard2-server1:27018,mongo-shard2-server2:27018,mongo-shard2-server3:27018")
  • 验证分片集群是否搭建成功
sh.status()
  • 设置需要分片的数据库和集合

选择片键请参照上面的片键选择表,设置 db1 为分片数据库,设置 db1.users 为分片集合,设置 {_id:"hashed"} 为哈希片键

sh.enableSharding("db1")
sh.shardCollection("db1.users",{_id:"hashed"})
  • 测试分片是否成功

通过切换数据库到 db1 中,在执行循环插入 1000 条数据

use db1
for (i = 0; i < 1000; i++) {
    db.users.insert({ i: i })
}
  • 在宿主机上通过 compass 连接分片集群
mongodb://localhost:27017,localhost:27018,localhost:27019/

你可能感兴趣的:(MongoDB 使用指南)