Mongodb

Mongodb

Mongodb的sharding模式实战

mongodbzhangdh 发表了文章 • 0 个评论 • 544 次浏览 • 2016-12-30 14:12 • 来自相关话题

Sharding模式结构图:

下面是安装配置实例的系统说明(8台机器,4个分片):

注意:上表中颜色相同的代表在同一台服务器上,其实也可以每个成员单放一台机器,但是比如像arbiter(仲裁节点),configserver(配置服务器),mongos(路由)本身消耗资源不是很大,可以复用,但是一台服务器最好只运行一个mongod。所以我们采用的一台服务器只运行了一个mongod和1至2个其他组成员,注意,一台服务器上不要运行同一组的多个成员,这样就起不到冗余的作用了。

//shard1

10.0.0.28 10.0.0.26

# sudo mkdir -p /var/soft/data/shard1

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard1 –bind_ip 0.0.0.0 –port 27040 –dbpath /var/soft/data/shard1/ -logpath /var/soft/log/shard1.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 
10.0.0.30

# sudo mkdir -p /var/soft/data/arbiter1/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard1 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter1/ -logpath /var/soft/log/arbiter1.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.26 上执行

> config = {_id: ‘shard1’, members: [{_id: 0, host: ‘mongodb26:27040’}, {_id: 1, host: ‘mongodb28:27040’},{_id: 2, host: ‘mongodb30:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//shard2

10.0.0.30 10.0.0.31

# sudo mkdir -p /var/soft/data/shard2

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard2 –bind_ip 0.0.0.0 –port 27050 –dbpath /var/soft/data/shard2/ -logpath /var/soft/log/shard2.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 在10.0.0.32上执行

# sudo mkdir -p  /var/soft/data/arbiter2/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard2 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter2/ -logpath /var/soft/log/arbiter2.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.31 上执行

> config = {_id: ‘shard2’, members: [{_id: 0, host: ‘mongodb30:27050’}, {_id: 1, host: ‘mongodb31:27050’},{_id: 2, host: ‘mongodb32:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//shard3

10.0.0.32 10.0.0.33

# sudo mkdir -p /var/soft/data/shard3

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard3 –bind_ip 0.0.0.0 –port 27060 –dbpath /var/soft/data/shard3/ -logpath /var/soft/log/shard3.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 
在 10.0.0.34上执行

# sudo mkdir -p  /var/soft/data/arbiter3/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard3 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter3/ -logpath /var/soft/log/arbiter3.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.33 上执行

> config = {_id: ‘shard3’, members: [{_id: 0, host: ‘mongodb32:27060’}, {_id: 1, host: ‘mongodb33:27060’},{_id: 2, host: ‘mongodb34:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//shard4

10.0.0.34 10.0.0.35

# sudo mkdir -p /var/soft/data/shard4

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard4 –bind_ip 0.0.0.0 –port 27070 –dbpath /var/soft/data/shard4/ -logpath /var/soft/log/shard4.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 
在10.0.0.26上执行

# sudo mkdir -p  /var/soft/data/arbiter4/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard4 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter4/ -logpath /var/soft/log/arbiter4.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.35 上执行

> config = {_id: ‘shard4’, members: [{_id: 0, host: ‘mongodb34:27070’}, {_id: 1, host: ‘mongodb35:27070’},{_id: 2, host: ‘mongodb26:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//配置configserver:

在10.0.0.28 10.0.0.33 10.0.0.35

# sudo mkdir -p /var/soft/data/config

# sudo mkdir -p /var/soft/log/config

# /var/soft/mongodb2.2/bin/mongod –bind_ip 0.0.0.0 –fork –configsvr –port 20000 –dbpath /var/soft/data/config –logpath /var/soft/log/config/config.log –logappend

 
// 添加mongos

# sudo mkdir -p /var/soft/log/mongos

在10.0.0.30上执行

# /var/soft/mongodb2.2/bin/mongos  –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

 
在10.0.0.28上执行

# /var/soft/mongodb2.2/bin/mongos  –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

 
在10.0.0.32上执行

# /var/soft/mongodb2.2/bin/mongos  –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

 在 10.0.0.30上执行

# /var/soft/mongodb2.2/bin/mongo  –port 30000

> db.runCommand({addshard : “shard1/mongodb26:27040,mongodb28:27040″,name:”shard1”,maxsize:504800});

> db.runCommand({addshard : “shard2/mongodb30:27050,mongodb31:27050″,name:”shard2”,maxsize:504800});

> db.runCommand({addshard : “shard3/mongodb32:27060,mongodb33:27060″,name:”shard3”,maxsize:504800});

> db.runCommand({addshard : “shard4/mongodb34:27070,mongodb35:27070″,name:”shard4”,maxsize:504800});

>db.runCommand( { listshards : 1 } )

如果列出了以上四个你加的shards,表示shards已经配置成功

> db.printShardingStatus();

 
按研发人员要求建立shard:

# /var/soft/mongodb2.2/bin/mongos –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

> db.runCommand( { movePrimary: “recsys0”, to: “shard1” })

> db.runCommand( { movePrimary: “recsys1”, to: “shard2” })

> db.runCommand( { movePrimary: “recsys2”, to: “shard3” })

> db.runCommand( { movePrimary: “recsys3”, to: “shard4” })


分片设置:

对于我们公司来说,我们使用的手动分片,不是auto-sharding,所以也不需要执行类似db.runCommand({enablesharding:库名})这样的命令。我们只是在4个不同的shard上建立4个库。至于读写操作会对应哪个库,由程序来判断。

那么建库的时候要登陆mongos来建,建好一个库,mongos来自动给你分配是建立在哪个shard上,但是如果你对自动分配的shard不满意可以运行命令来把它移动到别的shard上。

例如:我在mongos上建立了一个库叫recsys0库。运行db.printShardingStatus()命令我们可以看到这个recsys0是建到了哪个shard,如果建到了shard4,你觉得不满意,你想改到shard1,那么可以运行命令,db.runCommand( { movePrimary: “recsys0”, to: “shard1” }),这个库就会从shard4挪到shard1上。可通过db.printShardingStatus()再次检查。

 维护方面:

每个分片是一个replica set复制集,所以问题的处理与之前的replica set篇相同。

 出现过的问题:

Recsys1库明明配置的是在shard2上,但是shard1上也写入了少量数据,比较奇怪,于是在shard1用mongosniff –source NET eth0 –port 27040来抓取query,看看写入Recsys1库的query来自于哪里,于是发现是来自于一个mongos,其他的mongos均正常,这台mongos直接use Recsys1就进入的是shard1,但是执行db.printShardingStatus()没发现异常,怀疑是bug,结果关闭了这台mongos服务,解决问题。
  查看全部
Sharding模式结构图:

下面是安装配置实例的系统说明(8台机器,4个分片):

注意:上表中颜色相同的代表在同一台服务器上,其实也可以每个成员单放一台机器,但是比如像arbiter(仲裁节点),configserver(配置服务器),mongos(路由)本身消耗资源不是很大,可以复用,但是一台服务器最好只运行一个mongod。所以我们采用的一台服务器只运行了一个mongod和1至2个其他组成员,注意,一台服务器上不要运行同一组的多个成员,这样就起不到冗余的作用了。

//shard1

10.0.0.28 10.0.0.26

# sudo mkdir -p /var/soft/data/shard1

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard1 –bind_ip 0.0.0.0 –port 27040 –dbpath /var/soft/data/shard1/ -logpath /var/soft/log/shard1.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 
10.0.0.30

# sudo mkdir -p /var/soft/data/arbiter1/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard1 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter1/ -logpath /var/soft/log/arbiter1.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.26 上执行

> config = {_id: ‘shard1’, members: [{_id: 0, host: ‘mongodb26:27040’}, {_id: 1, host: ‘mongodb28:27040’},{_id: 2, host: ‘mongodb30:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//shard2

10.0.0.30 10.0.0.31

# sudo mkdir -p /var/soft/data/shard2

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard2 –bind_ip 0.0.0.0 –port 27050 –dbpath /var/soft/data/shard2/ -logpath /var/soft/log/shard2.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 在10.0.0.32上执行

# sudo mkdir -p  /var/soft/data/arbiter2/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard2 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter2/ -logpath /var/soft/log/arbiter2.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.31 上执行

> config = {_id: ‘shard2’, members: [{_id: 0, host: ‘mongodb30:27050’}, {_id: 1, host: ‘mongodb31:27050’},{_id: 2, host: ‘mongodb32:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//shard3

10.0.0.32 10.0.0.33

# sudo mkdir -p /var/soft/data/shard3

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard3 –bind_ip 0.0.0.0 –port 27060 –dbpath /var/soft/data/shard3/ -logpath /var/soft/log/shard3.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 
在 10.0.0.34上执行

# sudo mkdir -p  /var/soft/data/arbiter3/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard3 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter3/ -logpath /var/soft/log/arbiter3.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.33 上执行

> config = {_id: ‘shard3’, members: [{_id: 0, host: ‘mongodb32:27060’}, {_id: 1, host: ‘mongodb33:27060’},{_id: 2, host: ‘mongodb34:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//shard4

10.0.0.34 10.0.0.35

# sudo mkdir -p /var/soft/data/shard4

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard4 –bind_ip 0.0.0.0 –port 27070 –dbpath /var/soft/data/shard4/ -logpath /var/soft/log/shard4.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 
在10.0.0.26上执行

# sudo mkdir -p  /var/soft/data/arbiter4/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard4 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter4/ -logpath /var/soft/log/arbiter4.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.35 上执行

> config = {_id: ‘shard4’, members: [{_id: 0, host: ‘mongodb34:27070’}, {_id: 1, host: ‘mongodb35:27070’},{_id: 2, host: ‘mongodb26:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//配置configserver:

在10.0.0.28 10.0.0.33 10.0.0.35

# sudo mkdir -p /var/soft/data/config

# sudo mkdir -p /var/soft/log/config

# /var/soft/mongodb2.2/bin/mongod –bind_ip 0.0.0.0 –fork –configsvr –port 20000 –dbpath /var/soft/data/config –logpath /var/soft/log/config/config.log –logappend

 
// 添加mongos

# sudo mkdir -p /var/soft/log/mongos

在10.0.0.30上执行

# /var/soft/mongodb2.2/bin/mongos  –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

 
在10.0.0.28上执行

# /var/soft/mongodb2.2/bin/mongos  –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

 
在10.0.0.32上执行

# /var/soft/mongodb2.2/bin/mongos  –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

 在 10.0.0.30上执行

# /var/soft/mongodb2.2/bin/mongo  –port 30000

> db.runCommand({addshard : “shard1/mongodb26:27040,mongodb28:27040″,name:”shard1”,maxsize:504800});

> db.runCommand({addshard : “shard2/mongodb30:27050,mongodb31:27050″,name:”shard2”,maxsize:504800});

> db.runCommand({addshard : “shard3/mongodb32:27060,mongodb33:27060″,name:”shard3”,maxsize:504800});

> db.runCommand({addshard : “shard4/mongodb34:27070,mongodb35:27070″,name:”shard4”,maxsize:504800});

>db.runCommand( { listshards : 1 } )

如果列出了以上四个你加的shards,表示shards已经配置成功

> db.printShardingStatus();

 
按研发人员要求建立shard:

# /var/soft/mongodb2.2/bin/mongos –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

> db.runCommand( { movePrimary: “recsys0”, to: “shard1” })

> db.runCommand( { movePrimary: “recsys1”, to: “shard2” })

> db.runCommand( { movePrimary: “recsys2”, to: “shard3” })

> db.runCommand( { movePrimary: “recsys3”, to: “shard4” })


分片设置:

对于我们公司来说,我们使用的手动分片,不是auto-sharding,所以也不需要执行类似db.runCommand({enablesharding:库名})这样的命令。我们只是在4个不同的shard上建立4个库。至于读写操作会对应哪个库,由程序来判断。

那么建库的时候要登陆mongos来建,建好一个库,mongos来自动给你分配是建立在哪个shard上,但是如果你对自动分配的shard不满意可以运行命令来把它移动到别的shard上。

例如:我在mongos上建立了一个库叫recsys0库。运行db.printShardingStatus()命令我们可以看到这个recsys0是建到了哪个shard,如果建到了shard4,你觉得不满意,你想改到shard1,那么可以运行命令,db.runCommand( { movePrimary: “recsys0”, to: “shard1” }),这个库就会从shard4挪到shard1上。可通过db.printShardingStatus()再次检查。

 维护方面:

每个分片是一个replica set复制集,所以问题的处理与之前的replica set篇相同。

 出现过的问题:

Recsys1库明明配置的是在shard2上,但是shard1上也写入了少量数据,比较奇怪,于是在shard1用mongosniff –source NET eth0 –port 27040来抓取query,看看写入Recsys1库的query来自于哪里,于是发现是来自于一个mongos,其他的mongos均正常,这台mongos直接use Recsys1就进入的是shard1,但是执行db.printShardingStatus()没发现异常,怀疑是bug,结果关闭了这台mongos服务,解决问题。
 

Mongodb的replica set模式实战

mongodbzhangdh 发表了文章 • 0 个评论 • 555 次浏览 • 2016-12-30 14:09 • 来自相关话题

Replica Set架构图:

三节点replica set配置安装(无仲裁节点):

Replica set 【10.10.11.101-10.10.11.103】

10.10.11.101-10.10.11.103这三台按下面的安装:

# mkdir -p /u01/mongodb/data/replset/

# mkdir -p /u01/mongodb/log/

# /usr/local/mongodb/bin/mongod –replSet myrepl –fork –port 40001 –dbpath /u01/mongodb/data/replset/ –logpath /u01/mongodb/log/replset.log –logappend –oplogSize=4096

然后在建立集群,想让哪台当主就登陆哪台的服务器的mongo,然后添加如下配置

# /usr/local/mongodb/bin/mongo -port 40001

> config = {_id: ‘myrepl’, members: [{_id: 0, host: ‘10.10.11.101:40001’}, {_id: 1, host: ‘10.10.11.102:40001’},{_id: 3, host: ‘10.10.11.103:40001’}]}

> rs.initiate(config)

配置完毕后退出再登陆会显示primary字样

# /usr/local/mongodb/bin/mongo -port 40001

MongoDB shell version: 2.2.2

connecting to: 127.0.0.1:40001/test

myrepl:PRIMARY>

而另外两个则显示myrepl:SECONDARY

三节点replica set配置安装(有仲裁节点):

三节点无仲裁的好处就是一个master写,两个slave读。缺点是,我现在只有两台机器,也想做replica set,这样就出现了问题,如果只有两台的话,如果master宕机的话,那么只有slave一台,投票算法无法进行,所以slave无法提升为master只能只读,但是如果有一个仲裁节点的话,就可以完成切换,仲裁节点只负责投票不需要同步数据。

添加仲裁节点也很简单

配置好1主1从节点后添加rs.add(‘10.10.11.103:40001’, true)或者用rs.addArb(‘10.10.11.103:40001’);

也可在第一次配置时添加

> config = {_id: ‘myrepl’, members: [{_id: 0, host: ‘10.10.11.101:40001’}, {_id: 1, host: ‘10.10.11.102:40001’},{_id: 3, host: ‘10.10.11.103:40001’, arbiterOnly: true}]}

> rs.initiate(config)

 

读写分离:

默认做好Replica set的时候,slave是不开读的只能做故障切换用,这样比较浪费,为了分担主上的压力,应该让slave可读,方法是在slave服务器上执行rs.slaveOk()

 

手动切换master:

如果当前master出现问题,我们想把它降级成slave,那么非常简单,我们只用登陆master上执行rs.stepDown(10),这个命令的意思是10秒不会参与选举master,当执行完后复制集会从其他slave中选一个提升为master。其实手动切换master除了这个命令还有个方法就是比较复杂,就是修改config,设置优先级,然后重新加载。还有个命令某些时候会用到rs.freeze(10)是在slave上使用的,意思是10秒内不参与master的选举,如果我们在手动切换master的时候,我们不想让某些slave做master可以使用这个命令。

 

replica set相关命令:

> rs.status():查看复制集状态信息

> rs.conf():查看复制集配置信息

 

replica set节点的删除与添加:

假设我们现在需要对其中一个节点10.10.11.103进行维护,那我们需要,需要执行的命令如下

登陆master

执行rs.remove(“10.10.11.103:40001”)

等维护完之后再执行rs.add(“10.10.11.103:40001”)添加节点即可,但是如果下线时间太久,导致oplog已经被覆盖,那么用rs.add添加节点后10.10.11.103的同步将会停止。而且会有报错Thu Feb 28 09:58:00 [rsBackgroundSync] replSet not trying to sync from 10.10.11.102:40001, it is vetoed for 133 more seconds。

 

replica set节点同步失败处理方法:

接着上面的话题,如果同步出现问题,有两个方法解决

将一台同步完好的节点remove然后将数据目录scp过来再启动
将那个不同步的节点的数据目录删除,然后启动,mongodb会自动为你做好同步

 

replica set何时会切换失效:

这是一个很重要的知识点,就是replica set的成员节点,一旦宕机数量超过一半的时候,PRIMARY会自动降级成为SECONDARY,这时集群里只能只读,这时为了防止由于网络原因集群被分割成多块选出多个主。所以为了保证剩余的机器仍可切换为主,可添加多个仲裁节点。

例如:1主+2从+1仲裁

一共4个节点,一半就是2,那么如果2个从库宕机之后,那个主就会自动降级为从,这时这个replica set是不可写入的,所以不可用。

那么要解决这个问题就可以采用:1主+2从+2仲裁,这样的话宕2个从库达不到节点总数的一半,所以也不会对集群有影响。

 

修改slave的同步源(mongo 2.2新特性):

集群搭好之后,一般来说slave都是从master那里同步,如果slave很多的话master压力很大,我们可以让某些slave从其他的slave来同步数据,使用rs.syncFrom(“10.10.11.103:40001”)语句来执行这台slave从哪台同步,要注意如果这台slave重启后这个设置会失效。 查看全部
Replica Set架构图:

三节点replica set配置安装(无仲裁节点):

Replica set 【10.10.11.101-10.10.11.103】

10.10.11.101-10.10.11.103这三台按下面的安装:

# mkdir -p /u01/mongodb/data/replset/

# mkdir -p /u01/mongodb/log/

# /usr/local/mongodb/bin/mongod –replSet myrepl –fork –port 40001 –dbpath /u01/mongodb/data/replset/ –logpath /u01/mongodb/log/replset.log –logappend –oplogSize=4096

然后在建立集群,想让哪台当主就登陆哪台的服务器的mongo,然后添加如下配置

# /usr/local/mongodb/bin/mongo -port 40001

> config = {_id: ‘myrepl’, members: [{_id: 0, host: ‘10.10.11.101:40001’}, {_id: 1, host: ‘10.10.11.102:40001’},{_id: 3, host: ‘10.10.11.103:40001’}]}

> rs.initiate(config)

配置完毕后退出再登陆会显示primary字样

# /usr/local/mongodb/bin/mongo -port 40001

MongoDB shell version: 2.2.2

connecting to: 127.0.0.1:40001/test

myrepl:PRIMARY>

而另外两个则显示myrepl:SECONDARY

三节点replica set配置安装(有仲裁节点):

三节点无仲裁的好处就是一个master写,两个slave读。缺点是,我现在只有两台机器,也想做replica set,这样就出现了问题,如果只有两台的话,如果master宕机的话,那么只有slave一台,投票算法无法进行,所以slave无法提升为master只能只读,但是如果有一个仲裁节点的话,就可以完成切换,仲裁节点只负责投票不需要同步数据。

添加仲裁节点也很简单

配置好1主1从节点后添加rs.add(‘10.10.11.103:40001’, true)或者用rs.addArb(‘10.10.11.103:40001’);

也可在第一次配置时添加

> config = {_id: ‘myrepl’, members: [{_id: 0, host: ‘10.10.11.101:40001’}, {_id: 1, host: ‘10.10.11.102:40001’},{_id: 3, host: ‘10.10.11.103:40001’, arbiterOnly: true}]}

> rs.initiate(config)

 

读写分离:

默认做好Replica set的时候,slave是不开读的只能做故障切换用,这样比较浪费,为了分担主上的压力,应该让slave可读,方法是在slave服务器上执行rs.slaveOk()

 

手动切换master:

如果当前master出现问题,我们想把它降级成slave,那么非常简单,我们只用登陆master上执行rs.stepDown(10),这个命令的意思是10秒不会参与选举master,当执行完后复制集会从其他slave中选一个提升为master。其实手动切换master除了这个命令还有个方法就是比较复杂,就是修改config,设置优先级,然后重新加载。还有个命令某些时候会用到rs.freeze(10)是在slave上使用的,意思是10秒内不参与master的选举,如果我们在手动切换master的时候,我们不想让某些slave做master可以使用这个命令。

 

replica set相关命令:

> rs.status():查看复制集状态信息

> rs.conf():查看复制集配置信息

 

replica set节点的删除与添加:

假设我们现在需要对其中一个节点10.10.11.103进行维护,那我们需要,需要执行的命令如下

登陆master

执行rs.remove(“10.10.11.103:40001”)

等维护完之后再执行rs.add(“10.10.11.103:40001”)添加节点即可,但是如果下线时间太久,导致oplog已经被覆盖,那么用rs.add添加节点后10.10.11.103的同步将会停止。而且会有报错Thu Feb 28 09:58:00 [rsBackgroundSync] replSet not trying to sync from 10.10.11.102:40001, it is vetoed for 133 more seconds。

 

replica set节点同步失败处理方法:

接着上面的话题,如果同步出现问题,有两个方法解决

将一台同步完好的节点remove然后将数据目录scp过来再启动
将那个不同步的节点的数据目录删除,然后启动,mongodb会自动为你做好同步

 

replica set何时会切换失效:

这是一个很重要的知识点,就是replica set的成员节点,一旦宕机数量超过一半的时候,PRIMARY会自动降级成为SECONDARY,这时集群里只能只读,这时为了防止由于网络原因集群被分割成多块选出多个主。所以为了保证剩余的机器仍可切换为主,可添加多个仲裁节点。

例如:1主+2从+1仲裁

一共4个节点,一半就是2,那么如果2个从库宕机之后,那个主就会自动降级为从,这时这个replica set是不可写入的,所以不可用。

那么要解决这个问题就可以采用:1主+2从+2仲裁,这样的话宕2个从库达不到节点总数的一半,所以也不会对集群有影响。

 

修改slave的同步源(mongo 2.2新特性):

集群搭好之后,一般来说slave都是从master那里同步,如果slave很多的话master压力很大,我们可以让某些slave从其他的slave来同步数据,使用rs.syncFrom(“10.10.11.103:40001”)语句来执行这台slave从哪台同步,要注意如果这台slave重启后这个设置会失效。

Mongodb主从模式实战

mongodbzhangdh 发表了文章 • 0 个评论 • 570 次浏览 • 2016-12-30 14:04 • 来自相关话题

主从模式架构图:
 
主从配置安装:

10.10.11.101(master)

10.10.11.102(slave)

Master:

# tar zxvf mongodb-linux-x86_64-2.2.2.tgz

# ln -s mongodb-linux-x86_64-2.2.2 mongodb

# mkdir -p /u01/mongodata/db/geomaster/

# mkdir -p /u01/mongodata/log/

# /usr/local/mongodb/bin/mongod –fork –port 40000 –dbpath /u01/mongodata/db/geomaster/ –logpath /u01/mongodata/log/geomaster.log –logappend –master

 
Slave:

# tar zxvf mongodb-linux-x86_64-2.2.2.tgz

# ln -s mongodb-linux-x86_64-2.2.2 mongodb

# mkdir -p /u01/mongodata/db/geomaster/

# mkdir -p /u01/mongodata/log/

# /usr/local/mongodb/bin/mongod –fork –port 40000 –dbpath /u01/mongodata/db/geoslave/ –logpath /u01/mongodata/log/geosalve.log –logappend –slave –source 10.10.11.101:40000

 
参数说明:

mongod为mongoDB的server程序,启动参数使用的主要有如下几个

–fork  fork出一个server端的daemon进程

–port  server监听端口

–dbpath  数据文件目录

–logpath  日志文件路径

–logappend  日志追加到日志文件中,而不是覆盖写入

 
mongod在主从情况下可以设置的参数有:

–master  master模式

–salve  salve模式

–source  salve模式下指定master<server:port>

–only  只复制某一个数据库

–salvedelay 从库从主库中同步延时

–autoresync 假如从库数据不同步,自动同步

 

主从配置完毕后测试:

Master:

# /usr/local/mongodb/bin/mongo -port 40000

>use test;

>db.createCollection(“table1″);

>db.test.table1.insert({tag:”test”});

>db.test.table1.find();

 

slave:

# /usr/local/mongodb/bin/mongo -port 40000

>db.test.table1.find();

有数据,说明同步成功

同步后在master上用db.currentOp()也能看到slave的线程

 

主从相关命令:

db.isMaster():主从都可执行,用这个命令判断是不是master

db.getReplicationInfo():主上执行,获取主从信息

db.printReplicationInfo():主从都可执行,获取主从信息

db.printSlaveReplicationInfo();:从库执行,查看主从延时

 

同步失败处理方法:

如果同步失败,可使用如下命令同步所有数据:

同步出现问题,日志会有如下记录

Tue Feb 19 16:31:45 [replslave] all sources dead: data too stale halted replication, sleeping for 5 seconds

都是每5秒重试,一直在重试,那么如果要解决只能执行下面的命令全部同步一下

>use admin

>db.runCommand ( { “resync”: 1 } )

也可在启动从库时添加—autoresync参数

 

同步原理:

同步就是master上把对数据的更改操作记录到oplog中,然后slave抓取master的oplog执行。从这点看Oplog的功能和mysql的mysql-bin.的功能类似。Mysql-bin以二进制日志的形式存在,但是oplog是以一个mongodb的表的形式存在,该表在local库表名为oplog.$main,该表为循环写入形,所以不用定时清理。

 

修改oplog大小:

我们在首次启动mongodb服务的时候如果没有设置oplog的大小,那么它的默认值将是所在硬盘的5%,那么如果我们想要改变大小呢,必须重启,然后在启动的时候设置oplogsize,不过还有个小问题,因为之前的oplog已经存在了,所以修改完大小启动会报错,Tue Feb 19 15:43:19 [initandlisten] cmdline oplogsize (10) different than existing (1779),解决方法就是将mongodb数据目录下的local.*删除,参见:http://api.mongodb.org/wiki/cu ... .html

由于删除后oplog是重建的,slave的时间点信息比master上oplog的开始时间点要小,所以从库只能做全同步才能继续同步。但是有个问题,如果主库数据非常多的话,做一次全同步是一件非常耗时的事,况且数据也没有丢失。那么现在有个小技巧:

关闭slave的mongo服务
Master上在我们删除*之后,不要急着启动服务,先用linux的date命令更改系统时间,让时间小于slave上同步的最后时间,也就是slave执行db.printSlaveReplicationInfo()看到的时间
然后启动主库和从库方能继续同步 查看全部
主从模式架构图:
 
主从配置安装:

10.10.11.101(master)

10.10.11.102(slave)

Master:

# tar zxvf mongodb-linux-x86_64-2.2.2.tgz

# ln -s mongodb-linux-x86_64-2.2.2 mongodb

# mkdir -p /u01/mongodata/db/geomaster/

# mkdir -p /u01/mongodata/log/

# /usr/local/mongodb/bin/mongod –fork –port 40000 –dbpath /u01/mongodata/db/geomaster/ –logpath /u01/mongodata/log/geomaster.log –logappend –master

 
Slave:

# tar zxvf mongodb-linux-x86_64-2.2.2.tgz

# ln -s mongodb-linux-x86_64-2.2.2 mongodb

# mkdir -p /u01/mongodata/db/geomaster/

# mkdir -p /u01/mongodata/log/

# /usr/local/mongodb/bin/mongod –fork –port 40000 –dbpath /u01/mongodata/db/geoslave/ –logpath /u01/mongodata/log/geosalve.log –logappend –slave –source 10.10.11.101:40000

 
参数说明:

mongod为mongoDB的server程序,启动参数使用的主要有如下几个

–fork  fork出一个server端的daemon进程

–port  server监听端口

–dbpath  数据文件目录

–logpath  日志文件路径

–logappend  日志追加到日志文件中,而不是覆盖写入

 
mongod在主从情况下可以设置的参数有:

–master  master模式

–salve  salve模式

–source  salve模式下指定master<server:port>

–only  只复制某一个数据库

–salvedelay 从库从主库中同步延时

–autoresync 假如从库数据不同步,自动同步

 

主从配置完毕后测试:

Master:

# /usr/local/mongodb/bin/mongo -port 40000

>use test;

>db.createCollection(“table1″);

>db.test.table1.insert({tag:”test”});

>db.test.table1.find();

 

slave:

# /usr/local/mongodb/bin/mongo -port 40000

>db.test.table1.find();

有数据,说明同步成功

同步后在master上用db.currentOp()也能看到slave的线程

 

主从相关命令:

db.isMaster():主从都可执行,用这个命令判断是不是master

db.getReplicationInfo():主上执行,获取主从信息

db.printReplicationInfo():主从都可执行,获取主从信息

db.printSlaveReplicationInfo();:从库执行,查看主从延时

 

同步失败处理方法:

如果同步失败,可使用如下命令同步所有数据:

同步出现问题,日志会有如下记录

Tue Feb 19 16:31:45 [replslave] all sources dead: data too stale halted replication, sleeping for 5 seconds

都是每5秒重试,一直在重试,那么如果要解决只能执行下面的命令全部同步一下

>use admin

>db.runCommand ( { “resync”: 1 } )

也可在启动从库时添加—autoresync参数

 

同步原理:

同步就是master上把对数据的更改操作记录到oplog中,然后slave抓取master的oplog执行。从这点看Oplog的功能和mysql的mysql-bin.的功能类似。Mysql-bin以二进制日志的形式存在,但是oplog是以一个mongodb的表的形式存在,该表在local库表名为oplog.$main,该表为循环写入形,所以不用定时清理。

 

修改oplog大小:

我们在首次启动mongodb服务的时候如果没有设置oplog的大小,那么它的默认值将是所在硬盘的5%,那么如果我们想要改变大小呢,必须重启,然后在启动的时候设置oplogsize,不过还有个小问题,因为之前的oplog已经存在了,所以修改完大小启动会报错,Tue Feb 19 15:43:19 [initandlisten] cmdline oplogsize (10) different than existing (1779),解决方法就是将mongodb数据目录下的local.*删除,参见:http://api.mongodb.org/wiki/cu ... .html

由于删除后oplog是重建的,slave的时间点信息比master上oplog的开始时间点要小,所以从库只能做全同步才能继续同步。但是有个问题,如果主库数据非常多的话,做一次全同步是一件非常耗时的事,况且数据也没有丢失。那么现在有个小技巧:

关闭slave的mongo服务
Master上在我们删除*之后,不要急着启动服务,先用linux的date命令更改系统时间,让时间小于slave上同步的最后时间,也就是slave执行db.printSlaveReplicationInfo()看到的时间
然后启动主库和从库方能继续同步

Mongodb 基于验证的副本集

mongodbA128_huanggr 发表了文章 • 0 个评论 • 548 次浏览 • 2016-04-08 18:56 • 来自相关话题

做基于验证的副本集
1、准备三台虚拟机 192.168.1.237,192.168.1.231,192.168.1.232


2、分别在每台机器上建立mongodb副本集文件夹,建用户
groupadd mongo
useradd -g mongo -d /data/mongodb mongo

#存放mongodb数据文件
mkdir -p /data/mongodb/replset/data
mkdir /data/mongodb/conf
chown -R mongo.monog /data/mongodb


#进入mongodb文件夹 ;本次实验用提mongodb3.2.4 官方建议用3.2版本 
#下载地址 wget http://downloads.mongodb.org/l ... 4.tgz

tar xvf mongodb-linux-x86_64-3.2.4.tgz -C /data/mongodb
cd  /data/mongodb && mv mongodb-linux-x86_64-3.0.6 mongodb

配置文件 
cat conf/mongod.conf 
#port
port = 27017
#data dir
dbpath = /data/mongodb/replset/data
#log dir
logpath = /data/mongodb/replset/mongo.log
logappend = true
#Daemon
fork = true
#auth = true #此处是开验证的,暂时不开,所以用#隔开

在每台机器上用mongo用户启动mongodb
su - mongo
/data/mongodb/mongodb/bin/mongod --config /data/mongodb/conf/mongod1.conf --replSet repset &   
#上面的repset是副本集名称

接下来是配置副本集

[root@mongo mongodb]# ./mongodb/bin/mongo
MongoDB shell version: 3.2.4
connecting to: test
Server has startup warnings: 
2016-04-08T11:19:00.306+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2016-04-08T11:19:00.306+0800 I CONTROL  [initandlisten] 

repset:PRIMARY> use admin
switched to db admin
repset:PRIMARY> config = { _id:"repset", members:[
... ... ... {_id:0,host:"192.168.1.237:27018",priority:8},
... ... ... {_id:1,host:"192.168.1.231:27018",priority:8},
... ... ... {_id:2,host:"192.168.1.232:27018",priority:8}]};
以上的priority:8 是权重 三个节点都 是同样的权重。

回车返回以下信息:
{
        "_id" : "repset",
        "members" : [
                {
                        "_id" : 0,
                        "host" : "192.168.1.237:27018" ,
                        "priority" : 8
                },
                {
                        "_id" : 1,
                        "host" : "192.168.1.231:27018",
                        "priority" : 8
                },
                {
                        "_id" : 2,
                        "host" : "192.168.1.232:27018",
                        "priority" : 8
                }
        ]
}


#初始化副本集配置
repset:PRIMARY> rs.initiate(config);
返回OK

#查看集群节点的状态 主节点"stateStr" :"PRIMARY"  其它两个副节点 "stateStr" : "SECONDARY"
repset:PRIMARY> rs.status();
{
        "set" : "repset",
        "date" : ISODate("2016-04-08T03:24:18.758Z"),
        "myState" : 1,
        "members" : [
                {
                        "_id" : 0,
                        "name" : "192.168.1.237:27018",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 402,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "electionTime" : Timestamp(1460085562, 1),
                        "electionDate" : ISODate("2016-04-08T03:19:22Z"),
                        "configVersion" : 1,
                        "self" : true
                },
                {
                        "_id" : 1,
                        "name" : "192.168.1.231:27018",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 295,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "lastHeartbeat" : ISODate("2016-04-08T03:24:17.870Z"),
                        "lastHeartbeatRecv" : ISODate("2016-04-08T03:24:16.818Z"),
                        "pingMs" : 1,
                        "lastHeartbeatMessage" : "could not find member to sync from",
                        "configVersion" : 1
                },
                {
                        "_id" : 2,
                        "name" : "192.168.1.232:27018",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 205,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "lastHeartbeat" : ISODate("2016-04-08T03:24:17.895Z"),
                        "lastHeartbeatRecv" : ISODate("2016-04-08T03:24:18.434Z"),
                        "pingMs" : 1,
                        "configVersion" : 1
                }
        ],
        "ok" : 1
}


OK看到上面的信息就代表副本集配置成功了!
接下来呢就是创建管理用户了

去到主节点上操作创建用户,请注意从上面 的信息来看,我们知道192.168.1.237是目前副本集的主节点,它的状态是PRIMARY,我要建用户要进它里面去创建

/data/mongodb/mongodb/bin/mongo --port 27018 #注意了 如果你是用默认端口27017 那就不用指定--port
repset:PRIMARY> use admin #建用户要切换到admin用户

建系统管理用户
db.createUser(
   {
     user: "root",
     pwd: "loho_mongo",
     roles:[{role:"root",db:"admin"}]
   });

建数据库管理员

db.createUser(
   {
     user: "dbroot",
     pwd: "mongodb",
     roles:[{role:"userAdminAnyDatabase",db:"admin"}]
   });

建好管理用户我们 停掉副本集群 
先停主节点 kill -2 `pgrep mongo`
再把其它两个节点停了,注意一定要用kill -2 不要用kill -9 
把各个节点上的mongod.conf配置文件 改一下,开启验证
#port
port = 27017
#data dir
dbpath = /data/mongodb/replset/data
#log dir
logpath = /data/mongodb/replset/mongo.log
logappend = true
#Daemon
fork = true
auth = true

接下来是做keyFile 文件 在主节点上
openssl  rand -base64 90 >/data/mongodb/keyfile
chmod 600 /data/mongodb/keyfile

把主节点 上的 keyFile拷贝到副本节点 上 然后启动mongodb,注意把keyfile放统一目录,方便管理。
启动mongo,注意一点就是现在副本集的权重都是一样的,启动后主节点有可能又是另外一个节点,其它副节点是没有读和写的权限的
./mongodb/bin/mongod --config /data/mongodb/conf/mongod.conf --keyFile /data/mongodb/replset/keyfile --replSet repset &

三个节点启后 就看到了 副本集群又恢复了 这时要用之前创建的管理账号验证登陆才能去做建库 建用户的操作了

主节点登陆
/data/mongodb/mongodb/bin/mongo --port 27018
repset:PRIMARY>use admin
repset:PRIMARY>db.auth("root","loho_mongo") #验证管理用户,返回1是验证成功的
1

然后就可以做操作了,程序用户得另建例如
repset:PRIMARY>use jd
repset:PRIMARY>db.usr.insert({'name':'hello_world'});
repset:PRIMARY>db.createUser(
          {
      user: "jd_cx",
      pwd: "jd_2016",
      roles:
        [{role : "readWrite",    db:"jd"}]
    }
 );


程序连接mogodb复制集的方法(开发要看的!)http://www.mongoing.com/archives/2642



  查看全部
做基于验证的副本集
1、准备三台虚拟机 192.168.1.237,192.168.1.231,192.168.1.232


2、分别在每台机器上建立mongodb副本集文件夹,建用户
groupadd mongo
useradd -g mongo -d /data/mongodb mongo

#存放mongodb数据文件
mkdir -p /data/mongodb/replset/data
mkdir /data/mongodb/conf
chown -R mongo.monog /data/mongodb


#进入mongodb文件夹 ;本次实验用提mongodb3.2.4 官方建议用3.2版本 
#下载地址 wget http://downloads.mongodb.org/l ... 4.tgz

tar xvf mongodb-linux-x86_64-3.2.4.tgz -C /data/mongodb
cd  /data/mongodb && mv mongodb-linux-x86_64-3.0.6 mongodb

配置文件 
cat conf/mongod.conf 
#port
port = 27017
#data dir
dbpath = /data/mongodb/replset/data
#log dir
logpath = /data/mongodb/replset/mongo.log
logappend = true
#Daemon
fork = true
#auth = true #此处是开验证的,暂时不开,所以用#隔开

在每台机器上用mongo用户启动mongodb
su - mongo
/data/mongodb/mongodb/bin/mongod --config /data/mongodb/conf/mongod1.conf --replSet repset &   
#上面的repset是副本集名称

接下来是配置副本集

[root@mongo mongodb]# ./mongodb/bin/mongo
MongoDB shell version: 3.2.4
connecting to: test
Server has startup warnings: 
2016-04-08T11:19:00.306+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2016-04-08T11:19:00.306+0800 I CONTROL  [initandlisten] 

repset:PRIMARY> use admin
switched to db admin
repset:PRIMARY> config = { _id:"repset", members:[
... ... ... {_id:0,host:"192.168.1.237:27018",priority:8},
... ... ... {_id:1,host:"192.168.1.231:27018",priority:8},
... ... ... {_id:2,host:"192.168.1.232:27018",priority:8}]};
以上的priority:8 是权重 三个节点都 是同样的权重。

回车返回以下信息:
{
        "_id" : "repset",
        "members" : [
                {
                        "_id" : 0,
                        "host" : "192.168.1.237:27018" ,
                        "priority" : 8
                },
                {
                        "_id" : 1,
                        "host" : "192.168.1.231:27018",
                        "priority" : 8
                },
                {
                        "_id" : 2,
                        "host" : "192.168.1.232:27018",
                        "priority" : 8
                }
        ]
}


#初始化副本集配置
repset:PRIMARY> rs.initiate(config);
返回OK

#查看集群节点的状态 主节点"stateStr" :"PRIMARY"  其它两个副节点 "stateStr" : "SECONDARY"
repset:PRIMARY> rs.status();
{
        "set" : "repset",
        "date" : ISODate("2016-04-08T03:24:18.758Z"),
        "myState" : 1,
        "members" : [
                {
                        "_id" : 0,
                        "name" : "192.168.1.237:27018",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 402,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "electionTime" : Timestamp(1460085562, 1),
                        "electionDate" : ISODate("2016-04-08T03:19:22Z"),
                        "configVersion" : 1,
                        "self" : true
                },
                {
                        "_id" : 1,
                        "name" : "192.168.1.231:27018",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 295,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "lastHeartbeat" : ISODate("2016-04-08T03:24:17.870Z"),
                        "lastHeartbeatRecv" : ISODate("2016-04-08T03:24:16.818Z"),
                        "pingMs" : 1,
                        "lastHeartbeatMessage" : "could not find member to sync from",
                        "configVersion" : 1
                },
                {
                        "_id" : 2,
                        "name" : "192.168.1.232:27018",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 205,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "lastHeartbeat" : ISODate("2016-04-08T03:24:17.895Z"),
                        "lastHeartbeatRecv" : ISODate("2016-04-08T03:24:18.434Z"),
                        "pingMs" : 1,
                        "configVersion" : 1
                }
        ],
        "ok" : 1
}


OK看到上面的信息就代表副本集配置成功了!
接下来呢就是创建管理用户了

去到主节点上操作创建用户,请注意从上面 的信息来看,我们知道192.168.1.237是目前副本集的主节点,它的状态是PRIMARY,我要建用户要进它里面去创建

/data/mongodb/mongodb/bin/mongo --port 27018 #注意了 如果你是用默认端口27017 那就不用指定--port
repset:PRIMARY> use admin #建用户要切换到admin用户

建系统管理用户
db.createUser(
   {
     user: "root",
     pwd: "loho_mongo",
     roles:[{role:"root",db:"admin"}]
   });

建数据库管理员

db.createUser(
   {
     user: "dbroot",
     pwd: "mongodb",
     roles:[{role:"userAdminAnyDatabase",db:"admin"}]
   });

建好管理用户我们 停掉副本集群 
先停主节点 kill -2 `pgrep mongo`
再把其它两个节点停了,注意一定要用kill -2 不要用kill -9 
把各个节点上的mongod.conf配置文件 改一下,开启验证
#port
port = 27017
#data dir
dbpath = /data/mongodb/replset/data
#log dir
logpath = /data/mongodb/replset/mongo.log
logappend = true
#Daemon
fork = true
auth = true

接下来是做keyFile 文件 在主节点上
openssl  rand -base64 90 >/data/mongodb/keyfile
chmod 600 /data/mongodb/keyfile

把主节点 上的 keyFile拷贝到副本节点 上 然后启动mongodb,注意把keyfile放统一目录,方便管理。
启动mongo,注意一点就是现在副本集的权重都是一样的,启动后主节点有可能又是另外一个节点,其它副节点是没有读和写的权限的
./mongodb/bin/mongod --config /data/mongodb/conf/mongod.conf --keyFile /data/mongodb/replset/keyfile --replSet repset &

三个节点启后 就看到了 副本集群又恢复了 这时要用之前创建的管理账号验证登陆才能去做建库 建用户的操作了

主节点登陆
/data/mongodb/mongodb/bin/mongo --port 27018
repset:PRIMARY>use admin
repset:PRIMARY>db.auth("root","loho_mongo") #验证管理用户,返回1是验证成功的
1

然后就可以做操作了,程序用户得另建例如
repset:PRIMARY>use jd
repset:PRIMARY>db.usr.insert({'name':'hello_world'});
repset:PRIMARY>db.createUser(
          {
      user: "jd_cx",
      pwd: "jd_2016",
      roles:
        [{role : "readWrite",    db:"jd"}]
    }
 );


程序连接mogodb复制集的方法(开发要看的!)http://www.mongoing.com/archives/2642



 

Mongodb的sharding模式实战

mongodbzhangdh 发表了文章 • 0 个评论 • 544 次浏览 • 2016-12-30 14:12 • 来自相关话题

Sharding模式结构图:

下面是安装配置实例的系统说明(8台机器,4个分片):

注意:上表中颜色相同的代表在同一台服务器上,其实也可以每个成员单放一台机器,但是比如像arbiter(仲裁节点),configserver(配置服务器),mongos(路由)本身消耗资源不是很大,可以复用,但是一台服务器最好只运行一个mongod。所以我们采用的一台服务器只运行了一个mongod和1至2个其他组成员,注意,一台服务器上不要运行同一组的多个成员,这样就起不到冗余的作用了。

//shard1

10.0.0.28 10.0.0.26

# sudo mkdir -p /var/soft/data/shard1

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard1 –bind_ip 0.0.0.0 –port 27040 –dbpath /var/soft/data/shard1/ -logpath /var/soft/log/shard1.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 
10.0.0.30

# sudo mkdir -p /var/soft/data/arbiter1/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard1 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter1/ -logpath /var/soft/log/arbiter1.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.26 上执行

> config = {_id: ‘shard1’, members: [{_id: 0, host: ‘mongodb26:27040’}, {_id: 1, host: ‘mongodb28:27040’},{_id: 2, host: ‘mongodb30:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//shard2

10.0.0.30 10.0.0.31

# sudo mkdir -p /var/soft/data/shard2

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard2 –bind_ip 0.0.0.0 –port 27050 –dbpath /var/soft/data/shard2/ -logpath /var/soft/log/shard2.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 在10.0.0.32上执行

# sudo mkdir -p  /var/soft/data/arbiter2/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard2 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter2/ -logpath /var/soft/log/arbiter2.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.31 上执行

> config = {_id: ‘shard2’, members: [{_id: 0, host: ‘mongodb30:27050’}, {_id: 1, host: ‘mongodb31:27050’},{_id: 2, host: ‘mongodb32:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//shard3

10.0.0.32 10.0.0.33

# sudo mkdir -p /var/soft/data/shard3

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard3 –bind_ip 0.0.0.0 –port 27060 –dbpath /var/soft/data/shard3/ -logpath /var/soft/log/shard3.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 
在 10.0.0.34上执行

# sudo mkdir -p  /var/soft/data/arbiter3/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard3 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter3/ -logpath /var/soft/log/arbiter3.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.33 上执行

> config = {_id: ‘shard3’, members: [{_id: 0, host: ‘mongodb32:27060’}, {_id: 1, host: ‘mongodb33:27060’},{_id: 2, host: ‘mongodb34:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//shard4

10.0.0.34 10.0.0.35

# sudo mkdir -p /var/soft/data/shard4

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard4 –bind_ip 0.0.0.0 –port 27070 –dbpath /var/soft/data/shard4/ -logpath /var/soft/log/shard4.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 
在10.0.0.26上执行

# sudo mkdir -p  /var/soft/data/arbiter4/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard4 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter4/ -logpath /var/soft/log/arbiter4.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.35 上执行

> config = {_id: ‘shard4’, members: [{_id: 0, host: ‘mongodb34:27070’}, {_id: 1, host: ‘mongodb35:27070’},{_id: 2, host: ‘mongodb26:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//配置configserver:

在10.0.0.28 10.0.0.33 10.0.0.35

# sudo mkdir -p /var/soft/data/config

# sudo mkdir -p /var/soft/log/config

# /var/soft/mongodb2.2/bin/mongod –bind_ip 0.0.0.0 –fork –configsvr –port 20000 –dbpath /var/soft/data/config –logpath /var/soft/log/config/config.log –logappend

 
// 添加mongos

# sudo mkdir -p /var/soft/log/mongos

在10.0.0.30上执行

# /var/soft/mongodb2.2/bin/mongos  –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

 
在10.0.0.28上执行

# /var/soft/mongodb2.2/bin/mongos  –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

 
在10.0.0.32上执行

# /var/soft/mongodb2.2/bin/mongos  –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

 在 10.0.0.30上执行

# /var/soft/mongodb2.2/bin/mongo  –port 30000

> db.runCommand({addshard : “shard1/mongodb26:27040,mongodb28:27040″,name:”shard1”,maxsize:504800});

> db.runCommand({addshard : “shard2/mongodb30:27050,mongodb31:27050″,name:”shard2”,maxsize:504800});

> db.runCommand({addshard : “shard3/mongodb32:27060,mongodb33:27060″,name:”shard3”,maxsize:504800});

> db.runCommand({addshard : “shard4/mongodb34:27070,mongodb35:27070″,name:”shard4”,maxsize:504800});

>db.runCommand( { listshards : 1 } )

如果列出了以上四个你加的shards,表示shards已经配置成功

> db.printShardingStatus();

 
按研发人员要求建立shard:

# /var/soft/mongodb2.2/bin/mongos –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

> db.runCommand( { movePrimary: “recsys0”, to: “shard1” })

> db.runCommand( { movePrimary: “recsys1”, to: “shard2” })

> db.runCommand( { movePrimary: “recsys2”, to: “shard3” })

> db.runCommand( { movePrimary: “recsys3”, to: “shard4” })


分片设置:

对于我们公司来说,我们使用的手动分片,不是auto-sharding,所以也不需要执行类似db.runCommand({enablesharding:库名})这样的命令。我们只是在4个不同的shard上建立4个库。至于读写操作会对应哪个库,由程序来判断。

那么建库的时候要登陆mongos来建,建好一个库,mongos来自动给你分配是建立在哪个shard上,但是如果你对自动分配的shard不满意可以运行命令来把它移动到别的shard上。

例如:我在mongos上建立了一个库叫recsys0库。运行db.printShardingStatus()命令我们可以看到这个recsys0是建到了哪个shard,如果建到了shard4,你觉得不满意,你想改到shard1,那么可以运行命令,db.runCommand( { movePrimary: “recsys0”, to: “shard1” }),这个库就会从shard4挪到shard1上。可通过db.printShardingStatus()再次检查。

 维护方面:

每个分片是一个replica set复制集,所以问题的处理与之前的replica set篇相同。

 出现过的问题:

Recsys1库明明配置的是在shard2上,但是shard1上也写入了少量数据,比较奇怪,于是在shard1用mongosniff –source NET eth0 –port 27040来抓取query,看看写入Recsys1库的query来自于哪里,于是发现是来自于一个mongos,其他的mongos均正常,这台mongos直接use Recsys1就进入的是shard1,但是执行db.printShardingStatus()没发现异常,怀疑是bug,结果关闭了这台mongos服务,解决问题。
  查看全部
Sharding模式结构图:

下面是安装配置实例的系统说明(8台机器,4个分片):

注意:上表中颜色相同的代表在同一台服务器上,其实也可以每个成员单放一台机器,但是比如像arbiter(仲裁节点),configserver(配置服务器),mongos(路由)本身消耗资源不是很大,可以复用,但是一台服务器最好只运行一个mongod。所以我们采用的一台服务器只运行了一个mongod和1至2个其他组成员,注意,一台服务器上不要运行同一组的多个成员,这样就起不到冗余的作用了。

//shard1

10.0.0.28 10.0.0.26

# sudo mkdir -p /var/soft/data/shard1

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard1 –bind_ip 0.0.0.0 –port 27040 –dbpath /var/soft/data/shard1/ -logpath /var/soft/log/shard1.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 
10.0.0.30

# sudo mkdir -p /var/soft/data/arbiter1/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard1 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter1/ -logpath /var/soft/log/arbiter1.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.26 上执行

> config = {_id: ‘shard1’, members: [{_id: 0, host: ‘mongodb26:27040’}, {_id: 1, host: ‘mongodb28:27040’},{_id: 2, host: ‘mongodb30:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//shard2

10.0.0.30 10.0.0.31

# sudo mkdir -p /var/soft/data/shard2

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard2 –bind_ip 0.0.0.0 –port 27050 –dbpath /var/soft/data/shard2/ -logpath /var/soft/log/shard2.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 在10.0.0.32上执行

# sudo mkdir -p  /var/soft/data/arbiter2/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard2 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter2/ -logpath /var/soft/log/arbiter2.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.31 上执行

> config = {_id: ‘shard2’, members: [{_id: 0, host: ‘mongodb30:27050’}, {_id: 1, host: ‘mongodb31:27050’},{_id: 2, host: ‘mongodb32:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//shard3

10.0.0.32 10.0.0.33

# sudo mkdir -p /var/soft/data/shard3

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard3 –bind_ip 0.0.0.0 –port 27060 –dbpath /var/soft/data/shard3/ -logpath /var/soft/log/shard3.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 
在 10.0.0.34上执行

# sudo mkdir -p  /var/soft/data/arbiter3/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard3 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter3/ -logpath /var/soft/log/arbiter3.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.33 上执行

> config = {_id: ‘shard3’, members: [{_id: 0, host: ‘mongodb32:27060’}, {_id: 1, host: ‘mongodb33:27060’},{_id: 2, host: ‘mongodb34:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//shard4

10.0.0.34 10.0.0.35

# sudo mkdir -p /var/soft/data/shard4

# sudo mkdir -p /var/soft/log

# sudo  /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard4 –bind_ip 0.0.0.0 –port 27070 –dbpath /var/soft/data/shard4/ -logpath /var/soft/log/shard4.log –logappend –nojournal –oplogSize=4096 –fork –noprealloc

 
在10.0.0.26上执行

# sudo mkdir -p  /var/soft/data/arbiter4/

# sudo mkdir -p /var/soft/log

# /var/soft/mongodb2.2/bin/mongod –shardsvr –replSet shard4 –bind_ip 0.0.0.0 –port 27000 –dbpath /var/soft/data/arbiter4/ -logpath /var/soft/log/arbiter4.log –logappend –nojournal –oplogSize=4096 –fork

 
在10.0.0.35 上执行

> config = {_id: ‘shard4’, members: [{_id: 0, host: ‘mongodb34:27070’}, {_id: 1, host: ‘mongodb35:27070’},{_id: 2, host: ‘mongodb26:27000’, arbiterOnly: true}]}

> rs.initiate(config);

 
//配置configserver:

在10.0.0.28 10.0.0.33 10.0.0.35

# sudo mkdir -p /var/soft/data/config

# sudo mkdir -p /var/soft/log/config

# /var/soft/mongodb2.2/bin/mongod –bind_ip 0.0.0.0 –fork –configsvr –port 20000 –dbpath /var/soft/data/config –logpath /var/soft/log/config/config.log –logappend

 
// 添加mongos

# sudo mkdir -p /var/soft/log/mongos

在10.0.0.30上执行

# /var/soft/mongodb2.2/bin/mongos  –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

 
在10.0.0.28上执行

# /var/soft/mongodb2.2/bin/mongos  –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

 
在10.0.0.32上执行

# /var/soft/mongodb2.2/bin/mongos  –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

 在 10.0.0.30上执行

# /var/soft/mongodb2.2/bin/mongo  –port 30000

> db.runCommand({addshard : “shard1/mongodb26:27040,mongodb28:27040″,name:”shard1”,maxsize:504800});

> db.runCommand({addshard : “shard2/mongodb30:27050,mongodb31:27050″,name:”shard2”,maxsize:504800});

> db.runCommand({addshard : “shard3/mongodb32:27060,mongodb33:27060″,name:”shard3”,maxsize:504800});

> db.runCommand({addshard : “shard4/mongodb34:27070,mongodb35:27070″,name:”shard4”,maxsize:504800});

>db.runCommand( { listshards : 1 } )

如果列出了以上四个你加的shards,表示shards已经配置成功

> db.printShardingStatus();

 
按研发人员要求建立shard:

# /var/soft/mongodb2.2/bin/mongos –port 30000 –configdb mongodb28:20000,mongodb33:20000,mongodb35:20000 –logpath /var/soft/log/mongos/mongos.log –logappend –fork

> db.runCommand( { movePrimary: “recsys0”, to: “shard1” })

> db.runCommand( { movePrimary: “recsys1”, to: “shard2” })

> db.runCommand( { movePrimary: “recsys2”, to: “shard3” })

> db.runCommand( { movePrimary: “recsys3”, to: “shard4” })


分片设置:

对于我们公司来说,我们使用的手动分片,不是auto-sharding,所以也不需要执行类似db.runCommand({enablesharding:库名})这样的命令。我们只是在4个不同的shard上建立4个库。至于读写操作会对应哪个库,由程序来判断。

那么建库的时候要登陆mongos来建,建好一个库,mongos来自动给你分配是建立在哪个shard上,但是如果你对自动分配的shard不满意可以运行命令来把它移动到别的shard上。

例如:我在mongos上建立了一个库叫recsys0库。运行db.printShardingStatus()命令我们可以看到这个recsys0是建到了哪个shard,如果建到了shard4,你觉得不满意,你想改到shard1,那么可以运行命令,db.runCommand( { movePrimary: “recsys0”, to: “shard1” }),这个库就会从shard4挪到shard1上。可通过db.printShardingStatus()再次检查。

 维护方面:

每个分片是一个replica set复制集,所以问题的处理与之前的replica set篇相同。

 出现过的问题:

Recsys1库明明配置的是在shard2上,但是shard1上也写入了少量数据,比较奇怪,于是在shard1用mongosniff –source NET eth0 –port 27040来抓取query,看看写入Recsys1库的query来自于哪里,于是发现是来自于一个mongos,其他的mongos均正常,这台mongos直接use Recsys1就进入的是shard1,但是执行db.printShardingStatus()没发现异常,怀疑是bug,结果关闭了这台mongos服务,解决问题。
 

Mongodb的replica set模式实战

mongodbzhangdh 发表了文章 • 0 个评论 • 555 次浏览 • 2016-12-30 14:09 • 来自相关话题

Replica Set架构图:

三节点replica set配置安装(无仲裁节点):

Replica set 【10.10.11.101-10.10.11.103】

10.10.11.101-10.10.11.103这三台按下面的安装:

# mkdir -p /u01/mongodb/data/replset/

# mkdir -p /u01/mongodb/log/

# /usr/local/mongodb/bin/mongod –replSet myrepl –fork –port 40001 –dbpath /u01/mongodb/data/replset/ –logpath /u01/mongodb/log/replset.log –logappend –oplogSize=4096

然后在建立集群,想让哪台当主就登陆哪台的服务器的mongo,然后添加如下配置

# /usr/local/mongodb/bin/mongo -port 40001

> config = {_id: ‘myrepl’, members: [{_id: 0, host: ‘10.10.11.101:40001’}, {_id: 1, host: ‘10.10.11.102:40001’},{_id: 3, host: ‘10.10.11.103:40001’}]}

> rs.initiate(config)

配置完毕后退出再登陆会显示primary字样

# /usr/local/mongodb/bin/mongo -port 40001

MongoDB shell version: 2.2.2

connecting to: 127.0.0.1:40001/test

myrepl:PRIMARY>

而另外两个则显示myrepl:SECONDARY

三节点replica set配置安装(有仲裁节点):

三节点无仲裁的好处就是一个master写,两个slave读。缺点是,我现在只有两台机器,也想做replica set,这样就出现了问题,如果只有两台的话,如果master宕机的话,那么只有slave一台,投票算法无法进行,所以slave无法提升为master只能只读,但是如果有一个仲裁节点的话,就可以完成切换,仲裁节点只负责投票不需要同步数据。

添加仲裁节点也很简单

配置好1主1从节点后添加rs.add(‘10.10.11.103:40001’, true)或者用rs.addArb(‘10.10.11.103:40001’);

也可在第一次配置时添加

> config = {_id: ‘myrepl’, members: [{_id: 0, host: ‘10.10.11.101:40001’}, {_id: 1, host: ‘10.10.11.102:40001’},{_id: 3, host: ‘10.10.11.103:40001’, arbiterOnly: true}]}

> rs.initiate(config)

 

读写分离:

默认做好Replica set的时候,slave是不开读的只能做故障切换用,这样比较浪费,为了分担主上的压力,应该让slave可读,方法是在slave服务器上执行rs.slaveOk()

 

手动切换master:

如果当前master出现问题,我们想把它降级成slave,那么非常简单,我们只用登陆master上执行rs.stepDown(10),这个命令的意思是10秒不会参与选举master,当执行完后复制集会从其他slave中选一个提升为master。其实手动切换master除了这个命令还有个方法就是比较复杂,就是修改config,设置优先级,然后重新加载。还有个命令某些时候会用到rs.freeze(10)是在slave上使用的,意思是10秒内不参与master的选举,如果我们在手动切换master的时候,我们不想让某些slave做master可以使用这个命令。

 

replica set相关命令:

> rs.status():查看复制集状态信息

> rs.conf():查看复制集配置信息

 

replica set节点的删除与添加:

假设我们现在需要对其中一个节点10.10.11.103进行维护,那我们需要,需要执行的命令如下

登陆master

执行rs.remove(“10.10.11.103:40001”)

等维护完之后再执行rs.add(“10.10.11.103:40001”)添加节点即可,但是如果下线时间太久,导致oplog已经被覆盖,那么用rs.add添加节点后10.10.11.103的同步将会停止。而且会有报错Thu Feb 28 09:58:00 [rsBackgroundSync] replSet not trying to sync from 10.10.11.102:40001, it is vetoed for 133 more seconds。

 

replica set节点同步失败处理方法:

接着上面的话题,如果同步出现问题,有两个方法解决

将一台同步完好的节点remove然后将数据目录scp过来再启动
将那个不同步的节点的数据目录删除,然后启动,mongodb会自动为你做好同步

 

replica set何时会切换失效:

这是一个很重要的知识点,就是replica set的成员节点,一旦宕机数量超过一半的时候,PRIMARY会自动降级成为SECONDARY,这时集群里只能只读,这时为了防止由于网络原因集群被分割成多块选出多个主。所以为了保证剩余的机器仍可切换为主,可添加多个仲裁节点。

例如:1主+2从+1仲裁

一共4个节点,一半就是2,那么如果2个从库宕机之后,那个主就会自动降级为从,这时这个replica set是不可写入的,所以不可用。

那么要解决这个问题就可以采用:1主+2从+2仲裁,这样的话宕2个从库达不到节点总数的一半,所以也不会对集群有影响。

 

修改slave的同步源(mongo 2.2新特性):

集群搭好之后,一般来说slave都是从master那里同步,如果slave很多的话master压力很大,我们可以让某些slave从其他的slave来同步数据,使用rs.syncFrom(“10.10.11.103:40001”)语句来执行这台slave从哪台同步,要注意如果这台slave重启后这个设置会失效。 查看全部
Replica Set架构图:

三节点replica set配置安装(无仲裁节点):

Replica set 【10.10.11.101-10.10.11.103】

10.10.11.101-10.10.11.103这三台按下面的安装:

# mkdir -p /u01/mongodb/data/replset/

# mkdir -p /u01/mongodb/log/

# /usr/local/mongodb/bin/mongod –replSet myrepl –fork –port 40001 –dbpath /u01/mongodb/data/replset/ –logpath /u01/mongodb/log/replset.log –logappend –oplogSize=4096

然后在建立集群,想让哪台当主就登陆哪台的服务器的mongo,然后添加如下配置

# /usr/local/mongodb/bin/mongo -port 40001

> config = {_id: ‘myrepl’, members: [{_id: 0, host: ‘10.10.11.101:40001’}, {_id: 1, host: ‘10.10.11.102:40001’},{_id: 3, host: ‘10.10.11.103:40001’}]}

> rs.initiate(config)

配置完毕后退出再登陆会显示primary字样

# /usr/local/mongodb/bin/mongo -port 40001

MongoDB shell version: 2.2.2

connecting to: 127.0.0.1:40001/test

myrepl:PRIMARY>

而另外两个则显示myrepl:SECONDARY

三节点replica set配置安装(有仲裁节点):

三节点无仲裁的好处就是一个master写,两个slave读。缺点是,我现在只有两台机器,也想做replica set,这样就出现了问题,如果只有两台的话,如果master宕机的话,那么只有slave一台,投票算法无法进行,所以slave无法提升为master只能只读,但是如果有一个仲裁节点的话,就可以完成切换,仲裁节点只负责投票不需要同步数据。

添加仲裁节点也很简单

配置好1主1从节点后添加rs.add(‘10.10.11.103:40001’, true)或者用rs.addArb(‘10.10.11.103:40001’);

也可在第一次配置时添加

> config = {_id: ‘myrepl’, members: [{_id: 0, host: ‘10.10.11.101:40001’}, {_id: 1, host: ‘10.10.11.102:40001’},{_id: 3, host: ‘10.10.11.103:40001’, arbiterOnly: true}]}

> rs.initiate(config)

 

读写分离:

默认做好Replica set的时候,slave是不开读的只能做故障切换用,这样比较浪费,为了分担主上的压力,应该让slave可读,方法是在slave服务器上执行rs.slaveOk()

 

手动切换master:

如果当前master出现问题,我们想把它降级成slave,那么非常简单,我们只用登陆master上执行rs.stepDown(10),这个命令的意思是10秒不会参与选举master,当执行完后复制集会从其他slave中选一个提升为master。其实手动切换master除了这个命令还有个方法就是比较复杂,就是修改config,设置优先级,然后重新加载。还有个命令某些时候会用到rs.freeze(10)是在slave上使用的,意思是10秒内不参与master的选举,如果我们在手动切换master的时候,我们不想让某些slave做master可以使用这个命令。

 

replica set相关命令:

> rs.status():查看复制集状态信息

> rs.conf():查看复制集配置信息

 

replica set节点的删除与添加:

假设我们现在需要对其中一个节点10.10.11.103进行维护,那我们需要,需要执行的命令如下

登陆master

执行rs.remove(“10.10.11.103:40001”)

等维护完之后再执行rs.add(“10.10.11.103:40001”)添加节点即可,但是如果下线时间太久,导致oplog已经被覆盖,那么用rs.add添加节点后10.10.11.103的同步将会停止。而且会有报错Thu Feb 28 09:58:00 [rsBackgroundSync] replSet not trying to sync from 10.10.11.102:40001, it is vetoed for 133 more seconds。

 

replica set节点同步失败处理方法:

接着上面的话题,如果同步出现问题,有两个方法解决

将一台同步完好的节点remove然后将数据目录scp过来再启动
将那个不同步的节点的数据目录删除,然后启动,mongodb会自动为你做好同步

 

replica set何时会切换失效:

这是一个很重要的知识点,就是replica set的成员节点,一旦宕机数量超过一半的时候,PRIMARY会自动降级成为SECONDARY,这时集群里只能只读,这时为了防止由于网络原因集群被分割成多块选出多个主。所以为了保证剩余的机器仍可切换为主,可添加多个仲裁节点。

例如:1主+2从+1仲裁

一共4个节点,一半就是2,那么如果2个从库宕机之后,那个主就会自动降级为从,这时这个replica set是不可写入的,所以不可用。

那么要解决这个问题就可以采用:1主+2从+2仲裁,这样的话宕2个从库达不到节点总数的一半,所以也不会对集群有影响。

 

修改slave的同步源(mongo 2.2新特性):

集群搭好之后,一般来说slave都是从master那里同步,如果slave很多的话master压力很大,我们可以让某些slave从其他的slave来同步数据,使用rs.syncFrom(“10.10.11.103:40001”)语句来执行这台slave从哪台同步,要注意如果这台slave重启后这个设置会失效。

Mongodb主从模式实战

mongodbzhangdh 发表了文章 • 0 个评论 • 570 次浏览 • 2016-12-30 14:04 • 来自相关话题

主从模式架构图:
 
主从配置安装:

10.10.11.101(master)

10.10.11.102(slave)

Master:

# tar zxvf mongodb-linux-x86_64-2.2.2.tgz

# ln -s mongodb-linux-x86_64-2.2.2 mongodb

# mkdir -p /u01/mongodata/db/geomaster/

# mkdir -p /u01/mongodata/log/

# /usr/local/mongodb/bin/mongod –fork –port 40000 –dbpath /u01/mongodata/db/geomaster/ –logpath /u01/mongodata/log/geomaster.log –logappend –master

 
Slave:

# tar zxvf mongodb-linux-x86_64-2.2.2.tgz

# ln -s mongodb-linux-x86_64-2.2.2 mongodb

# mkdir -p /u01/mongodata/db/geomaster/

# mkdir -p /u01/mongodata/log/

# /usr/local/mongodb/bin/mongod –fork –port 40000 –dbpath /u01/mongodata/db/geoslave/ –logpath /u01/mongodata/log/geosalve.log –logappend –slave –source 10.10.11.101:40000

 
参数说明:

mongod为mongoDB的server程序,启动参数使用的主要有如下几个

–fork  fork出一个server端的daemon进程

–port  server监听端口

–dbpath  数据文件目录

–logpath  日志文件路径

–logappend  日志追加到日志文件中,而不是覆盖写入

 
mongod在主从情况下可以设置的参数有:

–master  master模式

–salve  salve模式

–source  salve模式下指定master<server:port>

–only  只复制某一个数据库

–salvedelay 从库从主库中同步延时

–autoresync 假如从库数据不同步,自动同步

 

主从配置完毕后测试:

Master:

# /usr/local/mongodb/bin/mongo -port 40000

>use test;

>db.createCollection(“table1″);

>db.test.table1.insert({tag:”test”});

>db.test.table1.find();

 

slave:

# /usr/local/mongodb/bin/mongo -port 40000

>db.test.table1.find();

有数据,说明同步成功

同步后在master上用db.currentOp()也能看到slave的线程

 

主从相关命令:

db.isMaster():主从都可执行,用这个命令判断是不是master

db.getReplicationInfo():主上执行,获取主从信息

db.printReplicationInfo():主从都可执行,获取主从信息

db.printSlaveReplicationInfo();:从库执行,查看主从延时

 

同步失败处理方法:

如果同步失败,可使用如下命令同步所有数据:

同步出现问题,日志会有如下记录

Tue Feb 19 16:31:45 [replslave] all sources dead: data too stale halted replication, sleeping for 5 seconds

都是每5秒重试,一直在重试,那么如果要解决只能执行下面的命令全部同步一下

>use admin

>db.runCommand ( { “resync”: 1 } )

也可在启动从库时添加—autoresync参数

 

同步原理:

同步就是master上把对数据的更改操作记录到oplog中,然后slave抓取master的oplog执行。从这点看Oplog的功能和mysql的mysql-bin.的功能类似。Mysql-bin以二进制日志的形式存在,但是oplog是以一个mongodb的表的形式存在,该表在local库表名为oplog.$main,该表为循环写入形,所以不用定时清理。

 

修改oplog大小:

我们在首次启动mongodb服务的时候如果没有设置oplog的大小,那么它的默认值将是所在硬盘的5%,那么如果我们想要改变大小呢,必须重启,然后在启动的时候设置oplogsize,不过还有个小问题,因为之前的oplog已经存在了,所以修改完大小启动会报错,Tue Feb 19 15:43:19 [initandlisten] cmdline oplogsize (10) different than existing (1779),解决方法就是将mongodb数据目录下的local.*删除,参见:http://api.mongodb.org/wiki/cu ... .html

由于删除后oplog是重建的,slave的时间点信息比master上oplog的开始时间点要小,所以从库只能做全同步才能继续同步。但是有个问题,如果主库数据非常多的话,做一次全同步是一件非常耗时的事,况且数据也没有丢失。那么现在有个小技巧:

关闭slave的mongo服务
Master上在我们删除*之后,不要急着启动服务,先用linux的date命令更改系统时间,让时间小于slave上同步的最后时间,也就是slave执行db.printSlaveReplicationInfo()看到的时间
然后启动主库和从库方能继续同步 查看全部
主从模式架构图:
 
主从配置安装:

10.10.11.101(master)

10.10.11.102(slave)

Master:

# tar zxvf mongodb-linux-x86_64-2.2.2.tgz

# ln -s mongodb-linux-x86_64-2.2.2 mongodb

# mkdir -p /u01/mongodata/db/geomaster/

# mkdir -p /u01/mongodata/log/

# /usr/local/mongodb/bin/mongod –fork –port 40000 –dbpath /u01/mongodata/db/geomaster/ –logpath /u01/mongodata/log/geomaster.log –logappend –master

 
Slave:

# tar zxvf mongodb-linux-x86_64-2.2.2.tgz

# ln -s mongodb-linux-x86_64-2.2.2 mongodb

# mkdir -p /u01/mongodata/db/geomaster/

# mkdir -p /u01/mongodata/log/

# /usr/local/mongodb/bin/mongod –fork –port 40000 –dbpath /u01/mongodata/db/geoslave/ –logpath /u01/mongodata/log/geosalve.log –logappend –slave –source 10.10.11.101:40000

 
参数说明:

mongod为mongoDB的server程序,启动参数使用的主要有如下几个

–fork  fork出一个server端的daemon进程

–port  server监听端口

–dbpath  数据文件目录

–logpath  日志文件路径

–logappend  日志追加到日志文件中,而不是覆盖写入

 
mongod在主从情况下可以设置的参数有:

–master  master模式

–salve  salve模式

–source  salve模式下指定master<server:port>

–only  只复制某一个数据库

–salvedelay 从库从主库中同步延时

–autoresync 假如从库数据不同步,自动同步

 

主从配置完毕后测试:

Master:

# /usr/local/mongodb/bin/mongo -port 40000

>use test;

>db.createCollection(“table1″);

>db.test.table1.insert({tag:”test”});

>db.test.table1.find();

 

slave:

# /usr/local/mongodb/bin/mongo -port 40000

>db.test.table1.find();

有数据,说明同步成功

同步后在master上用db.currentOp()也能看到slave的线程

 

主从相关命令:

db.isMaster():主从都可执行,用这个命令判断是不是master

db.getReplicationInfo():主上执行,获取主从信息

db.printReplicationInfo():主从都可执行,获取主从信息

db.printSlaveReplicationInfo();:从库执行,查看主从延时

 

同步失败处理方法:

如果同步失败,可使用如下命令同步所有数据:

同步出现问题,日志会有如下记录

Tue Feb 19 16:31:45 [replslave] all sources dead: data too stale halted replication, sleeping for 5 seconds

都是每5秒重试,一直在重试,那么如果要解决只能执行下面的命令全部同步一下

>use admin

>db.runCommand ( { “resync”: 1 } )

也可在启动从库时添加—autoresync参数

 

同步原理:

同步就是master上把对数据的更改操作记录到oplog中,然后slave抓取master的oplog执行。从这点看Oplog的功能和mysql的mysql-bin.的功能类似。Mysql-bin以二进制日志的形式存在,但是oplog是以一个mongodb的表的形式存在,该表在local库表名为oplog.$main,该表为循环写入形,所以不用定时清理。

 

修改oplog大小:

我们在首次启动mongodb服务的时候如果没有设置oplog的大小,那么它的默认值将是所在硬盘的5%,那么如果我们想要改变大小呢,必须重启,然后在启动的时候设置oplogsize,不过还有个小问题,因为之前的oplog已经存在了,所以修改完大小启动会报错,Tue Feb 19 15:43:19 [initandlisten] cmdline oplogsize (10) different than existing (1779),解决方法就是将mongodb数据目录下的local.*删除,参见:http://api.mongodb.org/wiki/cu ... .html

由于删除后oplog是重建的,slave的时间点信息比master上oplog的开始时间点要小,所以从库只能做全同步才能继续同步。但是有个问题,如果主库数据非常多的话,做一次全同步是一件非常耗时的事,况且数据也没有丢失。那么现在有个小技巧:

关闭slave的mongo服务
Master上在我们删除*之后,不要急着启动服务,先用linux的date命令更改系统时间,让时间小于slave上同步的最后时间,也就是slave执行db.printSlaveReplicationInfo()看到的时间
然后启动主库和从库方能继续同步

Mongodb 基于验证的副本集

mongodbA128_huanggr 发表了文章 • 0 个评论 • 548 次浏览 • 2016-04-08 18:56 • 来自相关话题

做基于验证的副本集
1、准备三台虚拟机 192.168.1.237,192.168.1.231,192.168.1.232


2、分别在每台机器上建立mongodb副本集文件夹,建用户
groupadd mongo
useradd -g mongo -d /data/mongodb mongo

#存放mongodb数据文件
mkdir -p /data/mongodb/replset/data
mkdir /data/mongodb/conf
chown -R mongo.monog /data/mongodb


#进入mongodb文件夹 ;本次实验用提mongodb3.2.4 官方建议用3.2版本 
#下载地址 wget http://downloads.mongodb.org/l ... 4.tgz

tar xvf mongodb-linux-x86_64-3.2.4.tgz -C /data/mongodb
cd  /data/mongodb && mv mongodb-linux-x86_64-3.0.6 mongodb

配置文件 
cat conf/mongod.conf 
#port
port = 27017
#data dir
dbpath = /data/mongodb/replset/data
#log dir
logpath = /data/mongodb/replset/mongo.log
logappend = true
#Daemon
fork = true
#auth = true #此处是开验证的,暂时不开,所以用#隔开

在每台机器上用mongo用户启动mongodb
su - mongo
/data/mongodb/mongodb/bin/mongod --config /data/mongodb/conf/mongod1.conf --replSet repset &   
#上面的repset是副本集名称

接下来是配置副本集

[root@mongo mongodb]# ./mongodb/bin/mongo
MongoDB shell version: 3.2.4
connecting to: test
Server has startup warnings: 
2016-04-08T11:19:00.306+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2016-04-08T11:19:00.306+0800 I CONTROL  [initandlisten] 

repset:PRIMARY> use admin
switched to db admin
repset:PRIMARY> config = { _id:"repset", members:[
... ... ... {_id:0,host:"192.168.1.237:27018",priority:8},
... ... ... {_id:1,host:"192.168.1.231:27018",priority:8},
... ... ... {_id:2,host:"192.168.1.232:27018",priority:8}]};
以上的priority:8 是权重 三个节点都 是同样的权重。

回车返回以下信息:
{
        "_id" : "repset",
        "members" : [
                {
                        "_id" : 0,
                        "host" : "192.168.1.237:27018" ,
                        "priority" : 8
                },
                {
                        "_id" : 1,
                        "host" : "192.168.1.231:27018",
                        "priority" : 8
                },
                {
                        "_id" : 2,
                        "host" : "192.168.1.232:27018",
                        "priority" : 8
                }
        ]
}


#初始化副本集配置
repset:PRIMARY> rs.initiate(config);
返回OK

#查看集群节点的状态 主节点"stateStr" :"PRIMARY"  其它两个副节点 "stateStr" : "SECONDARY"
repset:PRIMARY> rs.status();
{
        "set" : "repset",
        "date" : ISODate("2016-04-08T03:24:18.758Z"),
        "myState" : 1,
        "members" : [
                {
                        "_id" : 0,
                        "name" : "192.168.1.237:27018",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 402,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "electionTime" : Timestamp(1460085562, 1),
                        "electionDate" : ISODate("2016-04-08T03:19:22Z"),
                        "configVersion" : 1,
                        "self" : true
                },
                {
                        "_id" : 1,
                        "name" : "192.168.1.231:27018",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 295,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "lastHeartbeat" : ISODate("2016-04-08T03:24:17.870Z"),
                        "lastHeartbeatRecv" : ISODate("2016-04-08T03:24:16.818Z"),
                        "pingMs" : 1,
                        "lastHeartbeatMessage" : "could not find member to sync from",
                        "configVersion" : 1
                },
                {
                        "_id" : 2,
                        "name" : "192.168.1.232:27018",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 205,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "lastHeartbeat" : ISODate("2016-04-08T03:24:17.895Z"),
                        "lastHeartbeatRecv" : ISODate("2016-04-08T03:24:18.434Z"),
                        "pingMs" : 1,
                        "configVersion" : 1
                }
        ],
        "ok" : 1
}


OK看到上面的信息就代表副本集配置成功了!
接下来呢就是创建管理用户了

去到主节点上操作创建用户,请注意从上面 的信息来看,我们知道192.168.1.237是目前副本集的主节点,它的状态是PRIMARY,我要建用户要进它里面去创建

/data/mongodb/mongodb/bin/mongo --port 27018 #注意了 如果你是用默认端口27017 那就不用指定--port
repset:PRIMARY> use admin #建用户要切换到admin用户

建系统管理用户
db.createUser(
   {
     user: "root",
     pwd: "loho_mongo",
     roles:[{role:"root",db:"admin"}]
   });

建数据库管理员

db.createUser(
   {
     user: "dbroot",
     pwd: "mongodb",
     roles:[{role:"userAdminAnyDatabase",db:"admin"}]
   });

建好管理用户我们 停掉副本集群 
先停主节点 kill -2 `pgrep mongo`
再把其它两个节点停了,注意一定要用kill -2 不要用kill -9 
把各个节点上的mongod.conf配置文件 改一下,开启验证
#port
port = 27017
#data dir
dbpath = /data/mongodb/replset/data
#log dir
logpath = /data/mongodb/replset/mongo.log
logappend = true
#Daemon
fork = true
auth = true

接下来是做keyFile 文件 在主节点上
openssl  rand -base64 90 >/data/mongodb/keyfile
chmod 600 /data/mongodb/keyfile

把主节点 上的 keyFile拷贝到副本节点 上 然后启动mongodb,注意把keyfile放统一目录,方便管理。
启动mongo,注意一点就是现在副本集的权重都是一样的,启动后主节点有可能又是另外一个节点,其它副节点是没有读和写的权限的
./mongodb/bin/mongod --config /data/mongodb/conf/mongod.conf --keyFile /data/mongodb/replset/keyfile --replSet repset &

三个节点启后 就看到了 副本集群又恢复了 这时要用之前创建的管理账号验证登陆才能去做建库 建用户的操作了

主节点登陆
/data/mongodb/mongodb/bin/mongo --port 27018
repset:PRIMARY>use admin
repset:PRIMARY>db.auth("root","loho_mongo") #验证管理用户,返回1是验证成功的
1

然后就可以做操作了,程序用户得另建例如
repset:PRIMARY>use jd
repset:PRIMARY>db.usr.insert({'name':'hello_world'});
repset:PRIMARY>db.createUser(
          {
      user: "jd_cx",
      pwd: "jd_2016",
      roles:
        [{role : "readWrite",    db:"jd"}]
    }
 );


程序连接mogodb复制集的方法(开发要看的!)http://www.mongoing.com/archives/2642



  查看全部
做基于验证的副本集
1、准备三台虚拟机 192.168.1.237,192.168.1.231,192.168.1.232


2、分别在每台机器上建立mongodb副本集文件夹,建用户
groupadd mongo
useradd -g mongo -d /data/mongodb mongo

#存放mongodb数据文件
mkdir -p /data/mongodb/replset/data
mkdir /data/mongodb/conf
chown -R mongo.monog /data/mongodb


#进入mongodb文件夹 ;本次实验用提mongodb3.2.4 官方建议用3.2版本 
#下载地址 wget http://downloads.mongodb.org/l ... 4.tgz

tar xvf mongodb-linux-x86_64-3.2.4.tgz -C /data/mongodb
cd  /data/mongodb && mv mongodb-linux-x86_64-3.0.6 mongodb

配置文件 
cat conf/mongod.conf 
#port
port = 27017
#data dir
dbpath = /data/mongodb/replset/data
#log dir
logpath = /data/mongodb/replset/mongo.log
logappend = true
#Daemon
fork = true
#auth = true #此处是开验证的,暂时不开,所以用#隔开

在每台机器上用mongo用户启动mongodb
su - mongo
/data/mongodb/mongodb/bin/mongod --config /data/mongodb/conf/mongod1.conf --replSet repset &   
#上面的repset是副本集名称

接下来是配置副本集

[root@mongo mongodb]# ./mongodb/bin/mongo
MongoDB shell version: 3.2.4
connecting to: test
Server has startup warnings: 
2016-04-08T11:19:00.306+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2016-04-08T11:19:00.306+0800 I CONTROL  [initandlisten] 

repset:PRIMARY> use admin
switched to db admin
repset:PRIMARY> config = { _id:"repset", members:[
... ... ... {_id:0,host:"192.168.1.237:27018",priority:8},
... ... ... {_id:1,host:"192.168.1.231:27018",priority:8},
... ... ... {_id:2,host:"192.168.1.232:27018",priority:8}]};
以上的priority:8 是权重 三个节点都 是同样的权重。

回车返回以下信息:
{
        "_id" : "repset",
        "members" : [
                {
                        "_id" : 0,
                        "host" : "192.168.1.237:27018" ,
                        "priority" : 8
                },
                {
                        "_id" : 1,
                        "host" : "192.168.1.231:27018",
                        "priority" : 8
                },
                {
                        "_id" : 2,
                        "host" : "192.168.1.232:27018",
                        "priority" : 8
                }
        ]
}


#初始化副本集配置
repset:PRIMARY> rs.initiate(config);
返回OK

#查看集群节点的状态 主节点"stateStr" :"PRIMARY"  其它两个副节点 "stateStr" : "SECONDARY"
repset:PRIMARY> rs.status();
{
        "set" : "repset",
        "date" : ISODate("2016-04-08T03:24:18.758Z"),
        "myState" : 1,
        "members" : [
                {
                        "_id" : 0,
                        "name" : "192.168.1.237:27018",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 402,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "electionTime" : Timestamp(1460085562, 1),
                        "electionDate" : ISODate("2016-04-08T03:19:22Z"),
                        "configVersion" : 1,
                        "self" : true
                },
                {
                        "_id" : 1,
                        "name" : "192.168.1.231:27018",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 295,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "lastHeartbeat" : ISODate("2016-04-08T03:24:17.870Z"),
                        "lastHeartbeatRecv" : ISODate("2016-04-08T03:24:16.818Z"),
                        "pingMs" : 1,
                        "lastHeartbeatMessage" : "could not find member to sync from",
                        "configVersion" : 1
                },
                {
                        "_id" : 2,
                        "name" : "192.168.1.232:27018",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 205,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "lastHeartbeat" : ISODate("2016-04-08T03:24:17.895Z"),
                        "lastHeartbeatRecv" : ISODate("2016-04-08T03:24:18.434Z"),
                        "pingMs" : 1,
                        "configVersion" : 1
                }
        ],
        "ok" : 1
}


OK看到上面的信息就代表副本集配置成功了!
接下来呢就是创建管理用户了

去到主节点上操作创建用户,请注意从上面 的信息来看,我们知道192.168.1.237是目前副本集的主节点,它的状态是PRIMARY,我要建用户要进它里面去创建

/data/mongodb/mongodb/bin/mongo --port 27018 #注意了 如果你是用默认端口27017 那就不用指定--port
repset:PRIMARY> use admin #建用户要切换到admin用户

建系统管理用户
db.createUser(
   {
     user: "root",
     pwd: "loho_mongo",
     roles:[{role:"root",db:"admin"}]
   });

建数据库管理员

db.createUser(
   {
     user: "dbroot",
     pwd: "mongodb",
     roles:[{role:"userAdminAnyDatabase",db:"admin"}]
   });

建好管理用户我们 停掉副本集群 
先停主节点 kill -2 `pgrep mongo`
再把其它两个节点停了,注意一定要用kill -2 不要用kill -9 
把各个节点上的mongod.conf配置文件 改一下,开启验证
#port
port = 27017
#data dir
dbpath = /data/mongodb/replset/data
#log dir
logpath = /data/mongodb/replset/mongo.log
logappend = true
#Daemon
fork = true
auth = true

接下来是做keyFile 文件 在主节点上
openssl  rand -base64 90 >/data/mongodb/keyfile
chmod 600 /data/mongodb/keyfile

把主节点 上的 keyFile拷贝到副本节点 上 然后启动mongodb,注意把keyfile放统一目录,方便管理。
启动mongo,注意一点就是现在副本集的权重都是一样的,启动后主节点有可能又是另外一个节点,其它副节点是没有读和写的权限的
./mongodb/bin/mongod --config /data/mongodb/conf/mongod.conf --keyFile /data/mongodb/replset/keyfile --replSet repset &

三个节点启后 就看到了 副本集群又恢复了 这时要用之前创建的管理账号验证登陆才能去做建库 建用户的操作了

主节点登陆
/data/mongodb/mongodb/bin/mongo --port 27018
repset:PRIMARY>use admin
repset:PRIMARY>db.auth("root","loho_mongo") #验证管理用户,返回1是验证成功的
1

然后就可以做操作了,程序用户得另建例如
repset:PRIMARY>use jd
repset:PRIMARY>db.usr.insert({'name':'hello_world'});
repset:PRIMARY>db.createUser(
          {
      user: "jd_cx",
      pwd: "jd_2016",
      roles:
        [{role : "readWrite",    db:"jd"}]
    }
 );


程序连接mogodb复制集的方法(开发要看的!)http://www.mongoing.com/archives/2642



 
Mongodb数据库技术