【分布式数据库】使用docker搭建MongoDB真分布
一. 在虚拟机下载docker
1. 检查环境
Docker需要在64位版本的Ubuntu上安装。此外,你还需要保证你的Ubuntu内 核的最小版本不低于3.10。使用 uname -r
命令查看虚拟机版本。
uname -r
2. 卸载旧版本
在安装 Docker Engine 之前,需要卸载任何冲突的包。发行版维护者在 容易。您必须先卸载这些软件包,然后才能安装官方 Docker 引擎版本。
要卸载的非官方软件包有:
docker.io
docker-compose
docker-compose-v2
docker-doc
podman-docker
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
)
apt-get
可能会报告您没有安装任何这些软件包。存储在其中的映像、容器、卷和网络不是 卸载 Docker 时自动删除。
3. 安装docker
3.1 安装curl
sudo apt-get install ca-certificates curl
3.2 安装Docker
**不知道什么原因,一直下载失败 , 连接失败解决:解决docker下载不了问题 **
网站连接:在 Ubuntu 上安装 Docker 引擎 |Docker 文档
sudo curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
3.3 配置镜像加速
首先访问阿里云网站 : https://www.aliyun.com/ 注册一个账号。在首页的产品中,找到阿里云的容器镜像服务:
点击后进入控制台:找到镜像工具下的镜像加速器:
页面向下滚动,即可找到配置的文档说明:
# 创建目录
mkdir -p /etc/docker
# 复制内容,注意把其中的镜像加速地址改成你自己的
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"]
}
EOF
# 重新加载配置
systemctl daemon-reload
# 重启Docker
systemctl restart docker
这样就预防超时的问题了。
3.4 将用户放入docker组中
使用 docker
命令而不需要 sudo
,你通常需要确保 docker
用户组被正确设置,并且你的用户是该组的一部分。然后我们现在就是要把当前的用户添加到这个docker组中。
sudo groupadd docker #添加用户组
sudo gpasswd -a ${username} docker#将当前用户添加至用户组
newgrp docker #更新用户组
4. 安装MongoDB 3.6
因为配置了国内的镜像,下载起来非常丝滑。
sudo docker pull mongo:3.6
下载好了然后呢,下载到了那里。 我们可以看看docker的基本命令,也就是我们拉取了镜像,我们可以使用 docker images
查看我们拉取的镜像。
sudo docker images
发现我们已经拉取成功了。
5. 安装docker-compose
Docker Compose是Docker公司推出的一个工具软件,用于定义和运行多个Docker容器。它允许用户通过YAML格式的配置文件(通常是docker-compose.yml)来定义多个容器之间的调用关系,并通过简单的命令来启动、停止和重启这些容器。
使用sudo apt-get install docker-compose
命令进行安装。
sudo apt-get install docker-compose
6. 安装bridge-utils
bridge-utils是Linux下一款用于管理网桥的工具。其中的brctl命令可以用来在内核中建立、维护、检查网桥配置。没有这个就无法使用btcrl show查看docker网络。
sudo apt-get install bridge-utils
二. 使用docker搭建我们的MongoDB真分布
1 . 准备好mongo集群的端口
port 27001 28001 29001 shard1的3个端口。
port 27002 28002 29002 shard2的3个端口。
port 27012 28012 29012 shard3的3个端口。
port 27003 28003 29003 configserver的3个端口
port 27004 mongos的端口 只准备一个mongos出口 可以设置多个
2. 创建一个network
创建一个自定义的Docker网络。使用Docker运行容器时,默认情况下,容器之间是不互通的(除非它们被连接到同一个网络或者使用了Docker的默认桥接网络)。
docker network create mongo_cluster_net #创建一个network
docker network ls #查看docker的所有network
3. 创建文件夹
su #超级用户
mkdir -p /mnt/mongo/data/ #放数据
mkdir -p /mnt/mongo/log/ #放log
ls /mnt/mongo/ #查看创建文件
4. 将全部的9个mongodb的shard全部都装到docker的container里
shard1 : port 27001 28001 29001 shard1的3个端口。
docker run -d -p 27001:27018 \
-v /mnt/mongo/data/shard10/:/data/db/ \
-v /mnt/mongo/log/shard10/:/data/configdb/ \
--network mongo_cluster_net --name shard10 mongo:3.6 \
mongod --shardsvr --replSet shard1 --logpath=/data/configdb/shard1.log
docker run -d -p 28001:27018 \
-v /mnt/mongo/data/shard11/:/data/db/ \
-v /mnt/mongo/log/shard11/:/data/configdb/ \
--network mongo_cluster_net --name shard11 mongo:3.6 \
mongod --shardsvr --replSet shard1 --logpath=/data/configdb/shard1.log
docker run -d -p 29001:27018 \
-v /mnt/mongo/data/shard12/:/data/db/ \
-v /mnt/mongo/log/shard12/:/data/configdb/ \
--network mongo_cluster_net --name shard12 mongo:3.6 \
mongod --shardsvr --replSet shard1 --logpath=/data/configdb/shard1.log
shard2 : port 27002 28002 29002 shard2的3个端口。
docker run -d -p 27002:27018 \
-v /mnt/mongo/data/shard20/:/data/db/ \
-v /mnt/mongo/log/shard20/:/data/configdb/ \
--network mongo_cluster_net --name shard20 mongo:3.6 \
mongod --shardsvr --replSet shard2 --logpath=/data/configdb/shard2.log
docker run -d -p 28002:27018 \
-v /mnt/mongo/data/shard21/:/data/db/ \
-v /mnt/mongo/log/shard21/:/data/configdb/ \
--network mongo_cluster_net --name shard21 mongo:3.6 \
mongod --shardsvr --replSet shard2 --logpath=/data/configdb/shard2.log
docker run -d -p 29002:27018 \
-v /mnt/mongo/data/shard22/:/data/db/ \
-v /mnt/mongo/log/shard22/:/data/configdb/ \
--network mongo_cluster_net --name shard22 mongo:3.6 \
mongod --shardsvr --replSet shard2 --logpath=/data/configdb/shard2.log
shard3 : port 27012 28012 29012 shard3的3个端口。
docker run -d -p 27012:27018 \
-v /mnt/mongo/data/shard30/:/data/db/ \
-v /mnt/mongo/log/shard30/:/data/configdb/ \
--network mongo_cluster_net --name shard30 mongo:3.6 \
mongod --shardsvr --replSet shard3 --logpath=/data/configdb/shard3.log
docker run -d -p 28012:27018 \
-v /mnt/mongo/data/shard31/:/data/db/ \
-v /mnt/mongo/log/shard31/:/data/configdb/ \
--network mongo_cluster_net --name shard31 mongo:3.6 \
mongod --shardsvr --replSet shard3 --logpath=/data/configdb/shard3.log
docker run -d -p 29012:27018 \
-v /mnt/mongo/data/shard32/:/data/db/ \
-v /mnt/mongo/log/shard32/:/data/configdb/ \
--network mongo_cluster_net --name shard32 mongo:3.6 \
mongod --shardsvr --replSet shard3 --logpath=/data/configdb/shard3.log
创建完毕后使用 docker container ls -a
查看我们创建的容器,也可以使用docker ps
查看容器 。
docker ps
此命令主要用于列出当前正在运行的容器。如果不加任何选项,它将只显示正在运行的容器的基本信息,如容器ID、名称、状态、镜像等。
docker container ls -a
:此命令用于列出所有的容器,包括正在运行的容器和已经停止的容器。-a
选项代表 “all”,意味着显示所有容器。
5. 配置config-server
port 27003 28003 29003 config-server的3个端口 。
docker run -d -p 27003:27003 --name confsvr1 \
-v /mnt/mongo/data/cfgsvr1/:/data/db/ \
mongo:3.6 --configsvr --dbpath /data/db --replSet crs --port 27003
docker run -d -p 28003:27003 --name confsvr2 \
-v /mnt/mongo/data/cfgsvr2/:/data/db/ \
mongo:3.6 --configsvr --dbpath /data/db --replSet crs --port 27003
docker run -d -p 29003:27003 --name confsvr3 \
-v /mnt/mongo/data/cfgsvr3/:/data/db/ \
mongo:3.6 --configsvr --dbpath /data/db --replSet crs --port 27003
6. 将shard的replica和config-server的replica配置完成
现在我们创建了9个shard 和 3个config-server ,他们之间是毫无联系的,接下来我们就要将他们链接起来。
6.1 安装mongodb-clients
sudo apt install mongodb-clients
6.2 配置shard的replica
先进入mongo ,192.168.88.131:27001 为 ubt—ip
(shard1)
mongo 192.168.88.131:27001
config = { _id:"shard1", members:[
{_id:0,host:"192.168.88.131:27001"},
{_id:1,host:"192.168.88.131:28001",arbiterOnly:true},
{_id:2,host:"192.168.88.131:29001"}
]
}
rs.initiate(config)
exit
(shard2)
mongo 192.168.88.131:27002
config = { _id:"shard2", members:[
{_id:0,host:"192.168.88.131:27002"},
{_id:1,host:"192.168.88.131:28002",arbiterOnly:true},
{_id:2,host:"192.168.88.131:29002"}
]
}
rs.initiate(config)
exit
(shard3)
mongo 192.168.88.131:27012
config = { _id:"shard3", members:[
{_id:0,host:"192.168.88.131:27012"},
{_id:1,host:"192.168.88.131:28012",arbiterOnly:true},
{_id:2,host:"192.168.88.131:29012"}
]
}
rs.initiate(config)
exit
(config-svr)
mongo 192.168.88.131:27003
config = { _id:"crs",configsvr:true, members:[
{_id:0,host:"192.168.88.131:27003"},
{_id:1,host:"192.168.88.131:28003"},
{_id:2,host:"192.168.88.131:29003"}
]
}
rs.initiate(config)
7. 用docker为mongos造一个container
docker run -d -p 27004:27017 \
-v /mnt/mongo/log/mongos1/:/var/log/mongodb/ \
--network mongo_cluster_net --name mongos1 mongo:3.6 mongos --bind_ip_all --port 27017 --configdb crs/192.168.88.131:27003,192.168.88.131:28003,192.168.88.131:29003
8. 将所有的shards统一到mongos中
mongo 192.168.88.131:27004
use admin
db.runCommand({addshard:"shard1/192.168.88.131:27001,192.168.88.131:28001,192.168.88.131:29001"})
db.runCommand({addshard:"shard2/192.168.88.131:27002,192.168.88.131:28002,192.168.88.131:29002"})
db.runCommand({addshard:"shard3/192.168.88.131:27012,192.168.88.131:28012,192.168.88.131:29012"})
db.runCommand({listshards:1})
测试是否成功
db.runCommand({enablesharding:"test"})
db.runCommand({shardcollection:"test.kpl",key:{id:"hashed"}})
8.1 注:重启虚拟机后,重启docker mongo
因为上次没做完下课了,再次启动发现docker里面的mongodb全停下来了,在这重新启用一下
使用 docker container ls -a
命令查看所有容器。然后使用 docker start 容器名字 或者id
回到之前的实验
二. run 100000个文档的插入
1. 10w的先遣侦察兵
因为这是在实验室,时间并不够我们跑1400w数据,所以先来个10w试试水。因为我们要使用 test
数据库,所以我们先切换一下。
use test
show collections
现在我们可以先看一下数据库的状态 使用 db.stats()
,发现这几个mongo是连在一起的。
插入数据: 使用循环命令,插入数据,然后等他跑起来。对于现在的计算机10w还是很容易的。
mongo 192.168.88.131:27004
var before = new Date()
for(var i=1;i<=100000;i++){
db.kpl.insert({
id:i,
name:i,
english:Math.round(Math.random() * 100),
math:Math.round(Math.random() * 100),
chinese:Math.round(Math.random() * 100),
geography:Math.round(Math.random() * 100),
music:Math.round(Math.random() * 100),
love:Math.round(Math.random() * 100)
})
print(i)
}
var after = new Date()
execution_mills = after - before
print(execution_mills)
finalshell可以看见虚拟机的cpu和gpu的资源使用情况,我们可以看见,cpu在拼命干活。
数据跑完了我们可以看见,只用了 165526ms
,也就是 2 分钟多一点。我们可以估算一下,1400万数据,大概就要4.66个小时左右。
2. 再次查看表的状态
使用 db.stats()
。随便介绍一下每个参数代表什么。
db.stats()
- shard1/192.168.88.131:27001,192.168.88.131:29001:
- 这是分片的信息,它显示了该数据库分片所在的 MongoDB 实例的地址和端口。
- db:
- 数据库的名称,这里是
test
。
- 数据库的名称,这里是
- collections:
- 数据库中的集合数量,这里是 1(kpl)。
- views:
- 数据库中的视图数量,这里是 0。
- objects:
- 集合中的文档总数,这里是 33,755。 也就是本次10w数据,shard1节点分到了33,755个数据。
- avgObjSize:
- 集合中文档的平均大小(以字节为单位),这里是 144 字节。
- dataSize:
- 集合中所有文档的总大小(以字节为单位),这里是 4,860,720 字节,约 4.63 MB。
- storageSize:
- MongoDB 为存储集合中的数据所分配的总磁盘空间(以字节为单位)。这可能会比
dataSize
大,因为 MongoDB 可能会预留一些空间以供将来增长。这里是 2,228,224 字节,约 2.13 MB。
- MongoDB 为存储集合中的数据所分配的总磁盘空间(以字节为单位)。这可能会比
- numExtents:
- 集合中的 extent 数量。Extent 是 MongoDB 用于存储数据的连续磁盘空间块。在大多数情况下,你不需要直接关心这个值,但如果你正在做大量的数据插入或删除操作,它可能会帮助你理解数据的物理布局。
- indexes:
- 集合中的索引数量,这里是 2。
- indexSize:
- 所有索引的总大小(以字节为单位),这里是 1,413,120 字节,约 1.35 MB。
- fsUsedSize:
- MongoDB 实例所使用的文件系统的已使用空间大小(以字节为单位)。这可以告诉你 MongoDB 进程占用了多少磁盘空间,但它也可能包括其他文件或目录。这里是 17,779,392,512 字节,约 16.56 GB。
- fsTotalSize:
- MongoDB 实例所使用的文件系统的总大小(以字节为单位)。这里是 19,994,112,000 字节,约 18.62 GB。
- ok:
- 这是一个状态字段,指示命令是否成功执行。值为 1 表示成功。