副本集集群是一组Mongo服务,维护了相同的数据集,提供了高可用及数据冗余的能力。
# 模拟集群搭建
# 3个mongodb服务的副本集集群
# 一个服务器中通过端口号区分不同的mongodb实例
# 假设:
node1: hadoop 27001
node2: hadoop 27002
node3: hadoop 27003
# 创建mongodb的数据存放目录
[root@hadoop mongodb-linux-x86_64-3.6.2]# mkdir -p /data/rs/{node1,node2,node3}
# 启动3个mongodb服务实例 并指定所属副本集名称
[root@hadoop mongodb-linux-x86_64-3.6.2]# bin/mongod --dbpath=/data/rs/node1 --port 27001 --bind_ip_all --replSet rs
[root@hadoop mongodb-linux-x86_64-3.6.2]# bin/mongod --dbpath=/data/rs/node2 --port 27002 --bind_ip_all --replSet rs
[root@hadoop mongodb-linux-x86_64-3.6.2]# bin/mongod --dbpath=/data/rs/node3 --port 27003 --bind_ip_all --replSet rs
# 简单的配置 将3个mongodb的服务加入到rs的副本集集群中
[root@hadoop mongodb-linux-x86_64-3.6.2]# bin/mongo 127.0.0.1:27002
rs.initiate( {
_id : "rs",
members: [
{ _id: 0, host: "192.168.21.159:27001" },
{ _id: 1, host: "192.168.21.159:27002" },
{ _id: 2, host: "192.168.21.159:27003" }
]
})
# ---------------------------------------------------------------
#mongodb的服务加入到rs的副本集集群成功
{
"ok" : 1,
"operationTime" : Timestamp(1553824956, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1553824956, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
#---------------------------------------------------------------------
# 查看各个节点状态
rs:SECONDARY> rs.status()
#测试
#主节点添加数据
rs:SECONDARY>use baizhi
rs:PRIMARY> db.users.insert({"name":"zs"})
############集群中默认不支持副本集的操作
# 使副节点支持查询操作
rs:SECONDARY> db.getMongo().setSlaveOk()
##查看数据库发现副本集中也存在了刚添加的数据库
rs:SECONDARY> show dbs
admin 0.000GB
baizhi 0.000GB
config 0.000GB
local 0.000GB
rs:SECONDARY> use baizhi
switched to db baizhi
rs:SECONDARY> show collections;
users
rs:SECONDARY> db.users.find()
{ "_id" : ObjectId("5c9d7d809cf418b4849d21c5"), "name" : "zs" }
rs:SECONDARY>
注意:3.4版本后,config server需要搭建集群
# 模拟集群搭建
# 各个节点分别对应不同的端口号
shard1 192.168.128.156:28001
shard2 192.168.128.156:28002
shard3 192.168.128.156:28003
config1 192.168.128.156:28004
config2 192.168.128.156:28005
config3 192.168.128.156:28006
mongos 192.168.128.156:28007
mkdir -p /data/{shard1,shard2,shard3}
mkdir -p /data/{config1,config2,config3}
mkdir -p /data/mongos
mongodb/bin/mongod --port 28001 --dbpath=/data/shard1/ --bind_ip 192.168.21.159 --shardsvr
mongodb/bin/mongod --port 28002 --dbpath=/data/shard2/ --bind_ip 192.168.21.159 --shardsvr
mongodb/bin/mongod --port 28003 --dbpath=/data/shard3/ --bind_ip 192.168.21.159 --shardsvr
# 启动----------------------------------
mongodb/bin/mongod --port 28004 --dbpath=/data/config1/ --bind_ip 192.168.21.159 --configsvr --replSet rs
mongodb/bin/mongod --port 28005 --dbpath=/data/config2/ --bind_ip 192.168.21.159 --configsvr --replSet rs
mongodb/bin/mongod --port 28006 --dbpath=/data/config3/ --bind_ip 192.168.21.159 --configsvr --replSet rs
# 配置副本集-------------------------
[root@localhost mongodb]# bin/mongo 192.168.21.159:28004
rs.initiate( {
_id : "rs",
members: [
{ _id: 0, host: "192.168.21.159:28004" },
{ _id: 1, host: "192.168.21.159:28005" },
{ _id: 2, host: "192.168.21.159:28006" }
]
})
# 查看配置服务器副本集状态----------------------------
rs:SECONDARY> rs.status();
{
"set" : "rs",
"date" : ISODate("2018-01-19T01:42:20.535Z"),
"myState" : 1,
"term" : NumberLong(1),
"configsvr" : true,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1516326131, 1),
"t" : NumberLong(1)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1516326131, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1516326131, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1516326131, 1),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 0,
"name" : "192.168.128.156:28004",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 175,
"optime" : {
"ts" : Timestamp(1516326131, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-01-19T01:42:11Z"),
"electionTime" : Timestamp(1516326018, 1),
"electionDate" : ISODate("2018-01-19T01:40:18Z"),
"configVersion" : 1,
"self" : true
},
{
"_id" : 1,
"name" : "192.168.128.156:28005",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 133,
"optime" : {
"ts" : Timestamp(1516326131, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1516326131, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-01-19T01:42:11Z"),
"optimeDurableDate" : ISODate("2018-01-19T01:42:11Z"),
"lastHeartbeat" : ISODate("2018-01-19T01:42:18.777Z"),
"lastHeartbeatRecv" : ISODate("2018-01-19T01:42:19.933Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "192.168.128.156:28004",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "192.168.128.156:28006",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 133,
"optime" : {
"ts" : Timestamp(1516326131, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1516326131, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-01-19T01:42:11Z"),
"optimeDurableDate" : ISODate("2018-01-19T01:42:11Z"),
"lastHeartbeat" : ISODate("2018-01-19T01:42:18.778Z"),
"lastHeartbeatRecv" : ISODate("2018-01-19T01:42:20.030Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "192.168.128.156:28004",
"configVersion" : 1
}
],
"ok" : 1,
"operationTime" : Timestamp(1516326131, 1),
"$gleStats" : {
"lastOpTime" : Timestamp(1516326007, 1),
"electionId" : ObjectId("7fffffff0000000000000001")
},
"$clusterTime" : {
"clusterTime" : Timestamp(1516326131, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
mongodb/bin/mongos --port 28007 --bind_ip 192.168.21.159 --configdb rs/192.168.21.159:28004,192.168.21.159:28005,192.168.21.159:28006
# 使用客户端命令连接分片集群
mongodb/bin/mongo 192.168.128.159:28007
# 设置chunk大小
use config
db.settings.save( { _id:"chunksize", value: 1 } )
# 添加分片节点
use admin
db.runCommand({addShard:"192.168.21.159:28001"});
db.runCommand({addShard:"192.168.21.159:28002"});
db.runCommand({addShard:"192.168.21.159:28003"});
#查看分片集群状态
sh.status()
#重新启动服务
mongodb/bin/mongo 192.168.128.159:28007
# MongoDB分片是针对集合的,要想使集合支持分片,首先需要使其数据库支持分片,为数据库testdb启动分片
sh.enableSharding("testdb");
# 为分片字段建立索引,同时为集合指定片键
use testdb
db.users.ensureIndex({name:1});
# 启用集合分片,为其指定片键
sh.shardCollection("testdb.users",{name:1});
# 连接mongos,插入50W数据测试下分片
for(var i = 0;i<500000;i++){
db.users.insert({"name":"zs"+i,"age":i});
}
mongos> sh.status();
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5a6163a5130c3601a3a20db4")
}
shards:
{ "_id" : "shard0000", "host" : "192.168.21.159:28001", "state" : 1 }
{ "_id" : "shard0001", "host" : "192.168.21.159:28002", "state" : 1 }
{ "_id" : "shard0002", "host" : "192.168.21.159:28003", "state" : 1 }
active mongoses:
"3.6.2" : 1
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: yes
Collections with active migrations:
testdb.users started at Fri Jan 19 2018 11:25:25 GMT+0800 (CST)
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
5 : Success
databases:
{ "_id" : "config", "primary" : "config", "partitioned" : true }
config.system.sessions
shard key: { "_id" : 1 }
unique: false
balancing: true
chunks:
shard0000 1
{ "_id" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 } } on : shard0000 Timestamp(1, 0)
{ "_id" : "testdb", "primary" : "shard0000", "partitioned" : true }
testdb.users
shard key: { "name" : 1 }
unique: false
balancing: true
chunks:
shard0000 3
shard0001 3
shard0002 5
{ "name" : { "$minKey" : 1 } } -->> { "name" : "zs1" } on : shard0002 Timestamp(5, 0)
{ "name" : "zs1" } -->> { "name" : "zs108900" } on : shard0002 Timestamp(6, 2)
{ "name" : "zs108900" } -->> { "name" : "zs17318" } on : shard0002 Timestamp(6, 3)
{ "name" : "zs17318" } -->> { "name" : "zs19072" } on : shard0002 Timestamp(6, 4)
{ "name" : "zs19072" } -->> { "name" : "zs28146" } on : shard0001 Timestamp(5, 1)
{ "name" : "zs28146" } -->> { "name" : "zs42" } on : shard0001 Timestamp(4, 3)
{ "name" : "zs42" } -->> { "name" : "zs5163" } on : shard0001 Timestamp(4, 4)
{ "name" : "zs5163" } -->> { "name" : "zs60703" } on : shard0002 Timestamp(6, 0)
{ "name" : "zs60703" } -->> { "name" : "zs6978" } on : shard0000 Timestamp(6, 1)
{ "name" : "zs6978" } -->> { "name" : "zs8724" } on : shard0000 Timestamp(5, 4)
{ "name" : "zs8724" } -->> { "name" : { "$maxKey" : 1 } } on : shard0000 Timestamp(1, 3)
注意:在集群环境中查询数据总数量不能用count 需要用聚合函数
db.users.aggregate([{$group:{_id:null,count:{$sum:1}}}])