MongoDB官方更新速度过快,语法不断更新,shell命令也不断更新,建议直接看官方版。
本文主要从docker角度出发安装MongoDB
如图MongoDB是在关系型与非关系数据库之间,目前企业级网站面临3V(海量Volume,多样variety,实时velocity),3高(高并发,高可扩,高性能),通过数据冗余,在一条数据中存储父子的表数据来解决不能联查的问题。
举个例子:
将数据暂存在MongoDB中,再通过定时任务,写入数据库中。虽然MongoDB存在丢失数据风险的,但如果服务器稳定遍不会出现这种问题
将数据通过冗余的方式写入MongoDB中,通过MongoDB丰富的查询方式解决这个问题。
最基础的使用MongoDB,无法使用事务功能
//下载镜像
docker pull mongo
//创建容器并持久化数据
docker run --name 容器名称 -p 对外端口:27017 --restart=always -v /app/docker/mongo/db:/data/db -v /etc/localtime:/etc/localtime -d mongo --bind_ip_all
//进入docker 容器
docker exec -it 容器名称 bash
//进入docker 容器并登录MongoDB
docker exec -it 容器名称 mongosh
//登录进MongoDB后需要重置Mongo
rs.initiate()
//至此MongoDB可以正常使用了
进阶版使用MongoDB
注:原复制集因主节点挂掉,不能继续写入数据被淘汰,更新为副本集
一个主库;两个从库组成,主库宕机时,这两个从库都可以被选为主库。但数据通过主库写入时,副本库会将数据抓取到副本集中进行存储。主库负责写入数据,副本节点负责读取数据。我们写代码时不需要区分主节点与副本节点,可以连接所有ip,MongoDB会自己分辨
通过心跳检测,如果主节点挂掉,优先发现主节点挂掉的副本节点会成为主节点,但主节点再恢复后不能再成为主节点,只能成为副本节点。但这里会出现一个问题,副本节点并不一定是计算能力最强的节点。而且主节点只能有一个
docker pull mongomkdir -p /app/docker/mongo1/db #创建挂载的db目录
mkdir -p /app/docker/mongo2/db #创建挂载的db目录
mkdir -p /app/docker/mongo3/db #创建挂载的db目录
#第一台:
docker run --name mongo-server1 -p 30001:27017 --restart=always -v /app/docker/mongo1/db:/data/db -v /etc/localtime:/etc/localtime -d mongo --replSet "rs0" --bind_ip_all
#第二台:
docker run --name mongo-server2 -p 30002:27018 --restart=always -v /app/docker/mongo2/db:/data/db -v /etc/localtime:/etc/localtime -d mongo --replSet "rs0" --bind_ip_all
#第三台:
docker run --name mongo-server3 -p 30003:27019 --restart=always -v /app/docker/mongo3/db:/data/db -v /etc/localtime:/etc/localtime -d mongo --replSet "rs0" --bind_ip_all#进入容器 进入主的容器
docker exec -it mongo-server1 bash
#连接客户端
docker exec -it 容器名称 mongosh
//这里localhost是因为我都是在同一个服务器上装的,都换成各自的ip就好
//初始化
rs.initiate()
//注册副本集
rs.add("localhost:30002")
#如果想要在从节点查询(默认是客户端直连是不可查询的)
如果想要在端口30002 从服务上执行查询,则连接上之后需要执行 db.getMongo().setSlaveOk();
仲裁节点不存储数据,仲裁会帮助选举出主节点,但如果仲裁集群挂掉,主节点也挂掉了,那就完蛋了。因为副本集群只能读取不能写入。而且主节点只能有一个
docker pull mongomkdir -p /app/docker/mongo1/db #创建挂载的db目录
mkdir -p /app/docker/mongo2/db #创建挂载的db目录
mkdir -p /app/docker/mongo3/db #创建挂载的db目录
#第一台:
docker run --name mongo-server1 -p 30001:27017 --restart=always -v /app/docker/mongo1/db:/data/db -v /etc/localtime:/etc/localtime -d mongo --replSet "rs0" --bind_ip_all
#第二台:
docker run --name mongo-server2 -p 30002:27018 --restart=always -v /app/docker/mongo2/db:/data/db -v /etc/localtime:/etc/localtime -d mongo --replSet "rs0" --bind_ip_all
#第三台:
docker run --name mongo-server3 -p 30003:27019 --restart=always -v /app/docker/mongo3/db:/data/db -v /etc/localtime:/etc/localtime -d mongo --replSet "rs0" --bind_ip_all#进入容器 进入主的容器
docker exec -it mongo-server1 bash
#连接客户端
docker exec -it 容器名称 mongosh
//这里localhost是因为我都是在同一个服务器上装的,都换成各自的ip就好
//初始化
rs.initiate()
//注册副本集
rs.add("localhost:30002")
//注册仲裁
rs.addArb("localhost:30003")
#如果想要在从节点查询(默认是客户端直连是不可查询的)
如果想要在端口30002 从服务上执行查询,则连接上之后需要执行 db.getMongo().setSlaveOk();
架构师必备,搞不懂分片完全有情可原,相当的复杂。大家创建分片时切记画好图再创建,不然会弄乱。
分片的意思就是将一个集合中的数据,拆成不同的分片集群来存储数据。接下来忘记副本集的概念,分片和副本集架构关系并不大
当然问题也会存在,比如某个分片挂掉,就会影响该分片内数据的读取,但只需要重启就好。如果 App Server,Config Service 任何一个整体挂掉,就不可用了,但都可以集群分布在不同机器上,问题不大。
192.168.1.201:~~~shell
docker run --name shardsvr00 -p 10031:27018 -d -v /home/mongodb/data/sh/shardsvr00:/data/db mongo --shardsvr --replSet "rs_shardsvr0" --bind_ip_alldocker run --name shardsvr10 -p 10041:27018 -d -v /home/mongodb/data/sh/shardsvr10:/data/db mongo --shardsvr --replSet "rs_shardsvr1" --bind_ip_all~~~192.168.1.202:~~~shell
docker run --name shardsvr01 -p 10032:27018 -d -v /home/mongodb/data/sh/shardsvr00:/data/db mongo --shardsvr --replSet "rs_shardsvr0" --bind_ip_all
docker run --name shardsvr11 -p 10042:27018 -d -v /home/mongodb/data/sh/shardsvr11:/data/db mongo --shardsvr --replSet "rs_shardsvr1" --bind_ip_all
~~~192.168.3.203:~~~shell
docker run --name shardsvr02 -p 10033:27018 -d -v /home/mongodb/data/sh/shardsvr00:/data/db mongo --shardsvr --replSet "rs_shardsvr0" --bind_ip_all
docker run --name shardsvr12 -p 10043:27018 -d -v /home/mongodb/data/sh/shardsvr12:/data/db mongo --shardsvr --replSet "rs_shardsvr1" --bind_ip_all
~~~### 2.5初始化副本集192.168.1.201执行docker exec -it shardsvr00 bash
mongo --host 192.168.1.201 --port 10031~~~shell
rs.initiate({_id: "rs_shardsvr0",members: [{ _id: 0, host : "192.168.1.201:10031" },{ _id: 1, host : "192.168.1.202:10032" },{ _id: 2, host : "192.168.1.203:10033" }]}
);
~~~docker exec -it shardsvr10 bash
mongo --host 192.168.1.201 --port 10041~~~shell
rs.initiate({_id: "rs_shardsvr0",members: [{ _id: 0, host : "192.168.1.201:10041" },{ _id: 1, host : "192.168.1.202:10042" },{ _id: 2, host : "192.168.1.203:10043" }]}
);
~~~### 2.6.创建mongos,连接mongos到分片集群192.168.1.201:docker run --name mongos0 -d -p 10011:27017 --entrypoint "mongos" mongo --configdb rs_configsvr/192.168.1.201:10021,192.168.1.202:10022,192.168.1.203:10023 --bind_ip_all192.168.3.202:docker run --name mongos1 -d -p 10012:27017 --entrypoint "mongos" mongo --configdb rs_configsvr/192.168.1.201:10021,192.168.1.202:10022,192.168.1.203:10023 --bind_ip_all### 2.7添加分片到集群192.168.3.201:docker exec -it mongos0 bash
mongo --host 192.168.1.201 --port 10011sh.addShard("rs_shardsvr0/192.168.1.201:10031,192.168.1.202:10032,192.168.1.203:10033")
sh.addShard("rs_shardsvr1/192.168.1.201:10041,192.168.1.202:10042,192.168.1.203:10043")## 数据库 启用 分片sh.enableSharding("test")## 分片集合对 test.order 的 _id 字段进行哈希分片:sh.shardCollection("test.order", {"_id": "hashed" })
docker run -it --rm \--name mongo-express \-p 8081:8081 \-e ME_CONFIG_OPTIONS_EDITORTHEME="ambiance" \-e ME_CONFIG_MONGODB_SERVER="192.168.1.201" \-e ME_CONFIG_MONGODB_PORT="10011" \-e ME_CONFIG_BASICAUTH_USERNAME="admin" \-e ME_CONFIG_BASICAUTH_PASSWORD="admin" \mongo-express