天天看点

MongoDB主从/集群/分片

本文内容笔者均在本地操作成功。

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采用将集合进行拆分,然后将拆分的数据均摊到几个片上的一种解决方案。

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也能看得出。