本文内容笔者均在本地操作成功。
1.主从复制 master :./mongod --dbpath=xxx --port=xxx --master slave:./mongod --dbpath=xxx --port=xxx --slave --source=MASTER_IP:MASTER_PORT 好处:数据备份/数据恢复/读写分离
2.副本集 该集群没有特定的主数据库。 如果哪个主数据库宕机了,集群中就会推选出一个从属数据库作为主数据库顶上,这就具备了自动故障恢复功能。 ./mongod --dbpath=xxx --port=xxx --replSet REPLSET_NAME ./mongod --dbpath=xxx --port=xxx --replSet REPLSET_NAME
... 进入任意数据库,执行: >var config={_id:"test_repl",members:[{_id:0,host:"127.0.0.1:2222"},{_id:1,host:"127.0.0.1:3333"}]}; >rs.initiate(config);
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
test_repl:PRIMARY>
此时还需要指定仲裁服务器,执行:
rs.addArb("127.0.0.1:4444");
rs.status();
查看现在系统中仲裁/主/从等的分配。
关闭任意数据库,然后通过rs.status()验证自动故障恢复功能。
3.分片
在mongodb里面存在另一种集群,就是分片技术,跟sql server的表分区类似,我们知道当数据量达到T级别的时候,我们的磁盘,内存就吃不消了,针对这样的场景我们该如何应对。
mongodb采用将集合进行拆分,然后将拆分的数据均摊到几个片上的一种解决方案。
人脸: 代表客户端,客户端肯定说,你数据库分片不分片跟我没关系,我叫你干啥就干啥,没什么好商量的。
mongos: 首先我们要了解”片键“的概念,也就是说拆分集合的依据是什么?按照什么键值进行拆分集合....
好了,mongos就是一个路由服务器,它会根据管理员设置的“片键”将数据分摊到自己管理的mongod集群,数据
和片的对应关系以及相应的配置信息保存在"config服务器"上。
mongod: 一个普通的数据库实例,如果不分片的话,我们会直接连上mongod。
实现过程:
1.开启config服务器
先前也说了,mongos要把mongod之间的配置放到config服务器里面,理所当然首先开启它。
nohup ./mongod --dbpath=/home/zd/mongodb2.4.4/mongodb-config/db/ --port=2222 &
2.开启mongos服务器
这里要注意的是我们开启的是mongos,不是mongod,同时指定下config服务器。
nohup ./mongos --port=3333 --configdb=127.0.0.1:2222 &
这里不需要指定dbpath,否则起不来
3.启动mongod服务器
对分片来说,也就是要添加片了。
nohup ./mongod --dbpath=/home/zd/mongodb2.4.4/mongodb-ins1/db/ --port=4444 &
nohup ./mongod --dbpath=/home/zd/mongodb2.4.4/mongodb-ins2/db/ --port=5555 &
4.服务配置
-先前图中也可以看到,我们client直接跟mongos打交道,也就说明我们要连接mongos服务器,然后将4444,5555的mongod交给mongos,添加分片也就是addshard()。
mongos> db.runCommand({"addshard":"127.0.0.1:4444",allowLocal:true})
{ "shardAdded" : "shard0000", "ok" : 1 }
mongos> db.runCommand({"addshard":"127.0.0.1:5555",allowLocal:true})
{ "shardAdded" : "shard0001", "ok" : 1 }
这里要注意的是,在addshard中,我们也可以添加副本集,这样能达到更高的稳定性。
-片已经集群了,但是mongos不知道该如何切分数据,也就是我们先前所说的片键,在mongodb中设置片键要做两步:
①:开启数据库分片功能,命令很简单 enablesharding(),这里我就开启test数据库。
mongos> db.runCommand({"enablesharding":"test"})
{ "ok" : 1 }
②:指定集合中分片的片键,这里我就指定为person.name字段。
mongos> db.runCommand({"shardcollection":"test.person","key":{"name":1}})
{ "collectionsharded" : "test.person", "ok" : 1 }
5.查看效果
好了,至此我们的分片操作全部结束,接下来我们通过mongos向mongodb插入10w记录,然后通过printShardingStatus命令查看mongodb的数据分片情况。
mongos> use test
switched to db test
mongos> for(var i=0;i<100000;i++){
... db.person.insert({"name":"jack"+i,"age":i})
... }
mongos> db.printShardingStatus()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"version" : 3,
"minCompatibleVersion" : 3,
"currentVersion" : 4,
"clusterId" : ObjectId("51d27eb0aa0fa9779621879e")
}
shards:
{ "_id" : "shard0000", "host" : "127.0.0.1:4444" }
{ "_id" : "shard0001", "host" : "127.0.0.1:5555" }
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "test", "partitioned" : true, "primary" : "shard0000" }
test.person
shard key: { "name" : 1 }
chunks:
shard0000 2
shard0001 1
{ "name" : { "$minKey" : 1 } } -->> { "name" : "jack0" } on : shard0000 { "t" : 2, "i" : 1 }
{ "name" : "jack0" } -->> { "name" : "jack9999" } on : shard0000 { "t" : 1, "i" : 3 }
{ "name" : "jack9999" } -->> { "name" : { "$maxKey" : 1 } } on : shard0001 { "t" : 2, "i" : 0 }
mongos>
这里主要看三点信息:
① shards: 我们清楚的看到已经别分为两个片了,shard0000和shard0001。
② databases: 这里有个partitioned字段表示是否分区,这里清楚的看到test已经分区。
③ chunks: 这个很有意思,我们发现集合被砍成三段:
无穷小 —— jack0,jack0 ——jack9999,jack9999——无穷大。
分区情况为:2:1,从后面的 on shardXXXX也能看得出。