Docker_MongoDB集群
MongoDB集群之复制
简述
一个主,两个从库组成,主库宕机时,这两个从库都可以被选为主库。
假设复制集内投票成员数量为N,则大多数为 N/2 + 1,当复制集内存活成员数量不足大多数时,整个复制集将无法 选举出Primary,复制集将无法提供写服务,处于只读状态。
安装
#创建3个mongo容器
docker create --name mongo01 -p 27017:27017 -v mongo-data-01:/data/db mongo:4.0.3 -replSet "rs0" --bind_ip_all
docker create --name mongo02 -p 27018:27017 -v mongo-data-02:/data/db mongo:4.0.3 -replSet "rs0" --bind_ip_all
docker create --name mongo03 -p 27019:27017 -v mongo-data-03:/data/db mongo:4.0.3 -replSet "rs0" --bind_ip_all
#启动容器
docker start mongo01 mongo02 mongo03
#进入容器操作
docker exec -it mongo01 /bin/bash
#登录到mongo服务
mongo 172.16.55.185:27017
#初始化复制集集群
rs.initiate( {
_id : "rs0",
members: [
{ _id: 0, host: "172.16.55.185:27017" },
{ _id: 1, host: "172.16.55.185:27018" },
{ _id: 2, host: "172.16.55.185:27019" }
]
})
#响应
{
"ok" : 1,
#成功
"operationTime" : Timestamp(1551619334, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1551619334, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
测试
#在主库插入数据
rs0:PRIMARY> use test
rs0:PRIMARY> db.user.insert({"id":1001,"name":"zhangsan"})
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.user.find()
{ "_id" : ObjectId("5c7bd5965504bcd309686907"), "id" : 1001, "name" : "zhangsan" }
#在复制库查询数据
mongo 172.16.55.185:27018
rs0:SECONDARY> use test
rs0:SECONDARY> db.user.find()
Error: error: { #出错,默认情况下从库是不允许读写操作的
...
}
rs0:SECONDARY> rs.slaveOk() #设置允许从库读取数据
rs0:SECONDARY> db.user.find()
{ "_id" : ObjectId("5c7bd5965504bcd309686907"), "id" : 1001, "name" : "zhangsan" }
节点宕机处理
当集群中的节点数为偶数时,如一主一从情况下,任意一节点宕机都无法选举出Priamry,无法提供写操作,加入 arbiter节点后即可解决该问题。
docker create --name mongo04 -p 27020:27017 -v mongo-data-04:/data/db mongo:4.0.3 -replSet "rs0" --bind_ip_all
docker start mongo04
#在主节点执行
rs0:PRIMARY> rs.addArb("172.16.55.185:27020")
{
"ok" : 1,
"operationTime" : Timestamp(1551627454, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1551627454, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
#查询集群状态
rs.status()
通过测试,添加arbiter节点后,如果集群节点数不满足N/2+1时,arbiter节点可作为“凑数”节点,可以选出主节点, 继续提供服务。
MongoDB集群之分片集群
简介
分片(sharding)是MongoDB用来将大型集合分割到不同服务器(或者说一个集群)上所采用的方法。尽管分片起 源于关系型数据库分区,但MongoDB分片完全又是另一回事。
垂直扩展:增加更多的CPU和存储资源来扩展容量。
水平扩展:将数据集分布在多个服务器上。水平扩展即分片。
Mongos本身并不持久化数据,Sharded cluster所有的元数据都会存储到Config Server,而用户的数据会分散存储 到各个shard。Mongos启动后,会从配置服务器加载元数据,开始提供服务,将用户的请求正确路由到对应的分片。
当数据写入时,MongoDB Cluster根据分片键设计写入数据。当外部语句发起数据查询时,MongoDB根据数据分布 自动路由至指定节点返回数据。
安装
#创建3个config节点
docker create --name configsvr01 -p 17000:27019 -v mongoconfigsvr-data01:/data/configdb mongo:4.0.3 --configsvr --replSet "rs_configsvr" --bind_ip_all
docker create --name configsvr02 -p 17001:27019 -v mongoconfigsvr-data02:/data/configdb mongo:4.0.3 --configsvr --replSet "rs_configsvr" --bind_ip_all
docker create --name configsvr03 -p 17002:27019 -v mongoconfigsvr-data03:/data/configdb mongo:4.0.3 --configsvr --replSet "rs_configsvr" --bind_ip_all
#启动服务
docker start configsvr01 configsvr02 configsvr03
#进去容器进行操作
docker exec -it configsvr01 /bin/bash
mongo 172.16.55.185:17000
#集群初始化
rs.initiate(
{
_id: "rs_configsvr",
configsvr: true,
members: [
{ _id : 0, host : "172.16.55.185:17000" },
{ _id : 1, host : "172.16.55.185:17001" },
{ _id : 2, host : "172.16.55.185:17002" }
]
}
)
#创建2个shard集群,每个集群都有3个数据节点
#集群一
docker create --name shardsvr01 -p 37000:27018 -v mongoshardsvr-data-01:/data/db mongo:4.0.3 --replSet "rs_shardsvr1" --bind_ip_all --shardsvr
docker create --name shardsvr02 -p 37001:27018 -v mongoshardsvr-data-02:/data/db mongo:4.0.3 --replSet "rs_shardsvr1" --bind_ip_all --shardsvr
docker create --name shardsvr03 -p 37002:27018 -v mongoshardsvr-data-03:/data/db mongo:4.0.3 --replSet "rs_shardsvr1" --bind_ip_all --shardsvr
#集群二
docker create --name shardsvr04 -p 37003:27018 -v mongoshardsvr-data-04:/data/db mongo:4.0.3 --replSet "rs_shardsvr2" --bind_ip_all --shardsvr
docker create --name shardsvr05 -p 37004:27018 -v mongoshardsvr-data-05:/data/db mongo:4.0.3 --replSet "rs_shardsvr2" --bind_ip_all --shardsvr
docker create --name shardsvr06 -p 37005:27018 -v mongoshardsvr-data-06:/data/db mongo:4.0.3 --replSet "rs_shardsvr2" --bind_ip_all --shardsvr
#启动容器
docker start shardsvr01 shardsvr02 shardsvr03
docker start shardsvr04 shardsvr05 shardsvr06
#进去容器执行
docker exec -it shardsvr01 /bin/bash
mongo 172.16.55.185:37000
#初始化集群 rs.initiate(
{
_id: "rs_shardsvr1",
members: [
{ _id : 0, host : "172.16.55.185:37000" },
{ _id : 1, host : "172.16.55.185:37001" },
{ _id : 2, host : "172.16.55.185:37002" }
]
}
)
#初始化集群二
mongo 172.16.55.185:37003
rs.initiate(
{
_id: "rs_shardsvr2",
members: [
{ _id : 0, host : "172.16.55.185:37003" },
{ _id : 1, host : "172.16.55.185:37004" },
{ _id : 2, host : "172.16.55.185:37005" }
]
}
)
#创建mongos节点容器,需要指定config服务
docker create --name mongos -p 6666:27017 --entrypoint "mongos" mongo:4.0.3 -configdb rs_configsvr/172.16.55.185:17000,172.16.55.185:17001,172.16.55.185:17002 -bind_ip_all
docker start mongos
#进入容器执行
docker exec -it mongos bash
mongo 172.16.55.185:6666
#添加shard节点 sh.addShard("rs_shardsvr1/172.16.55.185:37000,172.16.55.185:37001,172.16.55.185:37002 ") sh.addShard("rs_shardsvr2/172.16.55.185:37003,172.16.55.185:37004,172.16.55.185:37005 ")
#启用分片
sh.enableSharding("test")
#设置分片规则,按照_id的hash进行区分
sh.shardCollection("test.order", {"_id": "hashed" })
#插入测试数据
use test
for (i = 1; i <= 1000; i=i+1){
db.order.insert({'id':i , 'price': 100+i})
}
#分别在2个shard集群中查询数据进行测试
db.order.count()
#集群操作(在mongos中执行)
use config
db.databases.find() #列出所有数据库分片情况
db.collections.find() #查看分片的片键
sh.status() #查询分片集群的状态信息