您的位置:首页 > 数据库 > Mongodb

Mongodb的副本、分片搭建方式

2015-06-18 11:20 726 查看
本文介绍副本和分片的两种搭建方式

由于主从模式很简单,而且Mongodb官网不推荐这种方式所以不再写这个模式的搭建过程了。

**

0、环境

**

本人机器资源有限,Linux环境由虚拟机搭建完成,而这两种模式完全可以在一台机器上来模拟,所以不启动多台机器了。

机器环境:CentOS6.6+VMware

Mongodb:2.6.9

IP:192.168.1.168

**

一、副本模式

**

我在一台机器上来模拟副本模式的搭建,所以将Mongo来复制为多个目录,通过启动不同的端口号来区分。

[20:24:53 fifi@CentOS6 test]$ ls
conf.bak  mongodb1  mongodb2  mongodb3


可以清理下data目录下的数据和log下的文件

整体架构如下:



1. 配置文件

mongodb1目录中的配置如下:

#mongodb1.conf
port=30001
dbpath=/home/fifi/test/mongodb1/data
logpath=/home/fifi/test/mongodb1/log/mongo.log
logappend=true
fork=true
replSet=myrepl
noprealloc=true


mongodb2、mongodb3对应的conf需要分别修改port、dbpath、logpath。

2.启动服务

我在每把mongodbN/bin/目录下的mongod改为了mongodN

[23:49:39 fifi@CentOS6 test]$ ll mongodb*/bin/mongod*
-rwxr-xr-x. 1 fifi fifi 23908720 Jun 17 23:28 mongodb1/bin/mongod1
-rwxr-xr-x. 1 fifi fifi 23908720 Jun 16 16:56 mongodb2/bin/mongod2
-rwxr-xr-x. 1 fifi fifi 23908720 Jun 16 16:57 mongodb3/bin/mongod3


其实没必要,只要自己清楚就行。

启动服务:

./mongodb1/bin/mongod1 -f mongodb1/mongodb.conf
./mongodb2/bin/mongod2 -f mongodb2/mongodb.conf
./mongodb3/bin/mongod3 -f mongodb3/mongodb.conf


3.客户端连接并配置

任意连接一个副本数据库即可,30001/30002/30003的一个就行

下文为具体操作工程,有些步骤的解析附在了注释中:

./mongodb1/bin/mongo --port 30001
#初始化配置
> cfg = { _id:"myrepl", members:[
... {_id:1, host:"192.168.1.168:30001", priority:2},
... {_id:2, host:"192.168.1.168:30002", priority:1},
... {_id:3, host:"192.168.1.168:30003", priority:2, arbiterOnly:true}
... ] };
#回车后显示如下,其中第一个_id必须与mongodb.conf配置中的replSet=myrepl对应上
{
"_id" : "myrepl",
"members" : [
{
"_id" : 1,
"host" : "192.168.1.168:30001",
"priority" : 2
},
{
"_id" : 2,
"host" : "192.168.1.168:30002",
"priority" : 1
},
{
"_id" : 3,
"host" : "192.168.1.168:30003",
"priority" : 2,
"arbiterOnly" : true
}
]
}
#使配置生效
> rs.initiate(cfg)
{
"info" : "Config now saved locally.  Should come online in about a minute.",
"ok" : 1
}
>
myrepl:SECONDARY>
myrepl:PRIMARY>
myrepl:PRIMARY>
#这里可以看到,30001这个数据库先是变为SECONDARY,然后变为PRIMARY,至此正好符合我们的预期。
#输入rs.status()来看一下副本状态,可以看到PRIMARY、SECONDARY、ARBITER都已就位(忽略部分信息)。
myrepl:PRIMARY> rs.status()
{
"set" : "myrepl",
"myState" : 1,
"members" : [
{
"_id" : 1,
"name" : "192.168.1.168:30001",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"self" : true
},
{
"_id" : 2,
"name" : "192.168.1.168:30002",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"syncingTo" : "192.168.1.168:30001"
},
{
"_id" : 3,
"name" : "192.168.1.168:30003",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
}
],
"ok" : 1
}


4.验证

客户端在连接的时候只需要注意端口号即可。

副本搭建好了,我们在主节点中插入和数据来验证下效果。

./mongodb1/bin/mongo --port 30001
myrepl:PRIMARY> db.tab.insert({idx:0})
WriteResult({ "nInserted" : 1 })
myrepl:PRIMARY> db.tab.find()
{ "_id" : ObjectId("55818d5d81f0b27bdfe0d373"), "idx" : 0 }


接下来我们去SECONDARY节点去看看:

./mongodb2/bin/mongo --port 30002
myrepl:SECONDARY> show tables
2015-06-17T23:09:24.442+0800 error: { "$err" : "not master and slaveOk=false", "code" : 13435 } at src/mongo/shell/query.js:131
myrepl:SECONDARY>

#这里注意:SECONDARY节点默认不可读,需要运行下以下函数
myrepl:SECONDARY> db.getMongo().setSlaveOk()
myrepl:SECONDARY> show tables
system.indexes
tab
myrepl:SECONDARY> db.tab.find()
{ "_id" : ObjectId("55818d5d81f0b27bdfe0d373"), "idx" : 0 }
#至此我们看到SECONDARY节点也正常。


最后去仲裁节点看看

./mongodb3/bin/mongo --port 30003
myrepl:ARBITER> db.getMongo().setSlaveOk()
myrepl:ARBITER> show tables;
2015-06-17T23:13:40.334+0800 error: {
"$err" : "not master or secondary; cannot currently read from this replSet member",
"code" : 13436
} at src/mongo/shell/query.js:131
myrepl:ARBITER>
#在这里仲裁节点只能做仲裁使用,不能存储任何数据


OK,副本模式搭建完成。

**

二、分片模式

分片模式,是将数据分在不同的分片上,如果有个分片挂掉了,整个数据就不完整了,一般情况下,每个分片都会搭建一个副本集来防止这样的情况。

而我同样在一台机器上来模拟这个分片模式,但是对不同的分片只用一个数据库(服务)来模拟副本集(副本的搭建和上面一样,只不过对每个副本集只启动了一个服务)。

对于config服务也是用一个服务来模拟。其实分片模式只能搭建1个或3个配置服务。配置服务只进行数据存放位置的记录,不进行数据存储。

1.整体架构



2.服务分配情况

同样,我用不同的目录来搭建对应的服务,并分配不同的端口号

[23:32:02 fifi@CentOS6 test]$ rm */data/*
[23:32:33 fifi@CentOS6 test]$ rm */log/*
[23:49:39 fifi@CentOS6 test]$ ll mongodb*/bin/mongod*
-rwxr-xr-x. 1 fifi fifi 23908720 Jun 16 17:00 mongodb0/bin/mongod0
-rwxr-xr-x. 1 fifi fifi 23908720 Jun 17 23:28 mongodb1/bin/mongod1
-rwxr-xr-x. 1 fifi fifi 23908720 Jun 16 16:56 mongodb4/bin/mongod4
-rwxr-xr-x. 1 fifi fifi 23908720 Jun 16 16:57 mongodb5/bin/mongod5
-rwxr-xr-x. 1 fifi fifi 23908720 Jun 16 17:26 mongodb6/bin/mongod6


3.开始搭建

大工程开始了,同志们保持头脑清醒

1)config服务:

[23:37:11 fifi@CentOS6 test]$ cd mongodb1
[23:37:38 fifi@CentOS6 mongodb1]$ ./bin/mongod1 --configsvr --dbpath data/ --port 30001 --logpath log/mongo.log --fork


2)mongos服务(路由)

[23:39:20 fifi@CentOS6 mongodb1]$ cd ../mongodb0
[23:40:18 fifi@CentOS6 mongodb0]$ ./bin/mongos --configdb 192.168.1.168:30001 --port 30000 --logpath log/mongo.log --fork


3)配置副本集

对于每个分片的服务我只启动一个服务来模拟

shard1的副本:

[23:43:55 fifi@CentOS6 mongodb0]$ cd ../mongodb4/
[23:44:23 fifi@CentOS6 mongodb4]$ ./bin/mongod4 --shardsvr --replSet shard1 --port 30004 --dbpath data/ --logpath log/mongo.log --fork


shard2的副本:

[23:44:47 fifi@CentOS6 mongodb4]$ cd ../mongodb5/
[23:46:12 fifi@CentOS6 mongodb5]$ ./bin/mongod5 --shardsvr --replSet shard2 --port 30005 --dbpath data/ --logpath log/mongo.log --fork


shard3的副本

[23:46:36 fifi@CentOS6 mongodb5]$ cd ../mongodb6/
[23:47:06 fifi@CentOS6 mongodb6]$ ./bin/mongod6 --shardsvr --replSet shard3 --port 30006 --dbpath data/ --logpath log/mongo.log --fork


看下每个服务的启动情况:

[23:49:48 fifi@CentOS6 test]$ ps xf

./bin/mongod5 --shardsvr --replSet shard2 --port 30005 --dbpath data/ --logpath log/mongo.log
./bin/mongod6 --shardsvr --replSet shard3 --port 30006 --dbpath data/ --logpath log/mongo.log
./bin/mongod4 --shardsvr --replSet shard1 --port 30004 --dbpath data/ --logpath log/mongo.log
./bin/mongos --configdb 192.168.1.168:30001 --port 30000 --logpath log/mongo.log --fork
./bin/mongod1 --configsvr --dbpath data/ --port 30001 --logpath log/mongo.log --fork


4)开始初始化副本集配置

随便找个客户端登陆,注意端口号即可

shard1的副本配置

[23:53:34 fifi@CentOS6 test]$ cd mongodb0/
[23:53:38 fifi@CentOS6 mongodb0]$ ./bin/mongo --port 30004
> cfg = { _id:"shard1", members:[
... {_id:0, host:"192.168.1.168:30004"}
... ]}
> rs.initiate(cfg)
> shard1:PRIMARY>


同样shard2的副本配置:

[23:55:22 fifi@CentOS6 mongodb0]$ ./bin/mongo --port 30005
> cfg = { _id:"shard2", members:[ {_id:0, host:"192.168.1.168:30005"} ]}
> rs.initiate(cfg)
> shard2:PRIMARY>


shard3的副本配置:

[23:56:28 fifi@CentOS6 mongodb0]$ ./bin/mongo --port 30006
> cfg = { _id:"shard3", members:[ {_id:0, host:"192.168.1.168:30006"} ]}
> rs.initiate(cfg)
>shard3:PRIMARY>


5)分片设置

[23:59:42 fifi@CentOS6 mongodb0]$ ./bin/mongo --port 30000
mongos> sh.addShard("shard1/192.168.1.168:30004")
mongos> sh.addShard("shard2/192.168.1.168:30005")
mongos> sh.addShard("shard3/192.168.1.168:30006")

#对集合创建索引(tab是我想进行分片的集合,可以在为空的状态下执行)
mongos> db.tab.ensureIndex({"idx":1})

#分片的集合
mongos> sh.enableSharding("test")

#片键
mongos> sh.shardCollection("test.tab", {"idx":1})

#分片状态
mongos> sh.status()
mongos> use admin
switched to db admin
mongos> db.runCommand( { listshards : 1 } );
{
"shards" : [
{
"_id" : "shard1",
"host" : "shard1/192.168.1.168:30004"
},
{
"_id" : "shard2",
"host" : "shard2/192.168.1.168:30005"
},
{
"_id" : "shard3",
"host" : "shard3/192.168.1.168:30006"
}
],
"ok" : 1
}


这步里面只列出了需要输入的命令,回车后的效果就没贴出来。

后面创建索引、对数据库启动分片以及片键的选择是非常重要的,是必须做的。

(如果片键选择错了,可以到admin.collections中修改)

6)验证

接下来,我们来登录mongos,然后对test.tab插入大量数据来看下效果。

#区区三万条数据
mongos> for (var i = 0; i <= 30000; i++) { db.tab.insert({idx:i});  }
WriteResult({ "nInserted" : 1 })
mongos>
mongos>
#分片的状态,略去一下不重要的信息
mongos> sh.status()
--- Sharding Status ---

databases:
{  "_id" : "test",  "partitioned" : true,  "primary" : "shard1" }
test.tab
shard key: { "idx" : 1 }
chunks:
shard2  1
shard1  1
shard3  1
#注意看这里的块范围
{ "idx" : { "$minKey" : 1 } } -->> { "idx" : 0 } on : shard2 Timestamp(2, 0)
{ "idx" : 0 } -->> { "idx" : 13549 } on : shard1 Timestamp(3, 1)
{ "idx" : 13549 } -->> { "idx" : { "$maxKey" : 1 } } on : shard3 Timestamp(3, 0)

#还有这个
mongos> db.tab.stats()
{
"sharded" : true,
"ns" : "test.tab",
"count" : 30001,
"avgObjSize" : 48.004266524449186,
"nindexes" : 2,
"nchunks" : 3,
"shards" : {
"shard1" : {
#shard1中的个数13549
"ns" : "test.tab",
"count" : 13549,
"size" : 650416,
},
"shard2" : {
#shard2中的个数0
"ns" : "test.tab",
"count" : 0,
"size" : 0,
},
"shard3" : {
#shard3中的个数16452
"ns" : "test.tab",
"count" : 16452,
"size" : 789760,
}
},
"ok" : 1
}
mongos>


13549+16452 = 30001,可以看到分片模式搭建成功了。

虽然shard2没有存放任何数据,不过不要紧,只要你插入的足够多,shard2中也会存放数据的。

**

参考网址:

**

网址一

网址二
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: