概述
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-mongos
是 mongos
搭建分片集群的路由程序,mongodb-org-server
是 mongod
数据库的进程守护程序,mongodb-org-shell
是 shell
命令行工具程序
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-db
和mongo-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
color
的 0
表示不返回字段,其中的 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
甚至更多需要恢复时,我们会花 1
天 2
天甚至更多的时间才能完成,这时我们可以使用到分片技术保证数据的完整性。当你的数据需要支撑全球业务时,这时我们也可以使用分片技术跨地域秒级读取数据。完整的分片集群包括路由节点(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
- 在终端中执行下面命令,创建名为
shard1
的3
个shardsvr
容器
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
- 在终端中执行下面命令,创建名为
shard2
的3
个shardsvr
容器
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
- 在终端中执行下面命令,创建名为
config1
的3
个configsvr
容器
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
- 在终端中执行下面命令,创建名为
mongos1
的3
个mongos
容器
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/