千家信息网

mongodb 2.4 不同server节点的replica set 搭建过程(一)

发表于:2024-11-26 作者:千家信息网编辑
千家信息网最后更新 2024年11月26日,Mongodb支持在多个机器中通过异步复制达到故障转移和实现冗余,多机器之间同一时刻只有一台是用于写操作,正是由于这个特性,为mongodb提供了数据一致性的保证,担当primary角色的机器能把读操
千家信息网最后更新 2024年11月26日mongodb 2.4 不同server节点的replica set 搭建过程(一)

Mongodb支持在多个机器中通过异步复制达到故障转移和实现冗余,多机器之间同一时刻只有一台是用于写操作,正是由于这个特性,为mongodb提供了数据一致性的保证,担当primary角色的机器能把读操作分发给slave


Mongodb高可用分两种:


Master-slave 主从复制


只需要在某一个服务启动时加上--master参数,而另外一个服务加上-slave-source参数,即可实现同步,mongodb的最新版本已经不在支持此方案了


Replica sets 复制集:


Mongodb是从1.6版本开发了新功能replica sets,这个比master-slave功能更加强大一些,增加了故障自动切换和自动修复成员节点,各个DB之间的数据完全一致,大大降低了维护成本。Auto shared已经明确说明不在支持replication paris,建议使用replica setreplica set故障切换完全自动化


假设一个三节点的mongodb集群

三个节点server-1-2-3无论哪一个节点出现故障,其他节点马上会将业务接转过来而无需停机操作


主要学习replica set 复制集


replica set可以实现自动的failover和自动的recovery


replica set由两个或者更多的节点组成,实现彼此的复制。


replica set自动选择primary节点,没有一个节点是固定的primary


mongos会自动发现一个replica setprimary节点发生变化,并将写操作发送给这个新的primary节点。


通常用于下面几个场景


数据冗余。


自动failover,提供高可用性的服务。


分散读的负载。


简化维护(相对于master-slave来说)。


灾难恢复。


首先还是启动mongod,用于replica set的参数有两个:


--replSet ,复制集的名称。


--oplogSize ,操作日志的大小,单位为MB。(一般是磁盘空间的5%);


Mongodb的版本:


[root@anenjoy mongodb]# /usr/local/mongodb/bin/mongo -version


MongoDB shell version: 2.4.8


实验中三台虚拟机的IP


192.168.1.247


192.168.1.248


192.168.1.250


先在各个server主机上搭建mongodb的安装,配置存储路径


安装就是解压包,不再细述


第三步:启动mongodb


命令参数:


SERVER -1


/usr/local/mongodb/bin/mongod --port 27017 --replSet res1 --keyFile /data/mon_db/key/res1 --oplogSize 100 --dbpath=/data/mon_db/res1/ --logpath=/usr/local/mongodb/log/mongodb.log --logappend --fork


参数详解:--port 是端口号


--replSet replica set的标识参数,后跟set名称


--keyFile 就是标识进群的私钥文件


--oplogSize replica操作的日志,是可以crapped collection,可循环使用的,大小100MB


--dbpath 数据文件的存储路径


--logpath 日志文件路径 --logappend是日志追加


--fork 后台运行程序


SERVER -2


/usr/local/mongodb/bin/mongod --port 27018 --replSet res1 --keyFile /data/mon_db/key/res2 --oplogSize 100 --dbpath=/data/mon_db/res2/ --logpath=/usr/local/mongodb/log/mongodb.log --logappend --fork



SERVER -3


/usr/local/mongodb/bin/mongod --port 27019 --replSet res1 --keyFile /data/mon_db/key/res3 --oplogSize 100 --dbpath=/data/mon_db/res3/ --logpath=/usr/local/mongodb/log/mongodb.log --logappend --fork


各自启动,注意实时观察log文件的变化,看是否有问题产生(tail mongodb.log -f)

如果遇到error信息:


[rsStart] replSet can't get local.system.replset config from self or any seed (EMPTYCONFIG)

表示你还没有执行初始化,这个暂时不用考虑


第四步:初始化


登录任意一台servermongodb数据库


[root@test02 bin]# /usr/local/mongodb/bin/mongo --port 27017


MongoDB shell version: 2.4.8


connecting to: 127.0.0.1:27017/test


>


配置初始化文件


config_res1={_id:'res1',members:[


{_id:0,host:'192.168.1.248:27017',priority:2},


{_id:1,host:'192.168.1.247:27018',priority:0}


{_id:2,host:'192.168.1.250:27019',priority:1}]


}


"_id" : "res1",


"members" : [


{


"_id" : 0,


"host" : "192.168.1.248:27017",


"priority" : 2


},


{


"_id" : 1,


"host" : "192.168.1.247:27018",


"priority" : 0


},


{


"_id" : 2,


"host" : "192.168.1.250:27019",


"priority" : 1


}


]


}


Priority 优先级,值越大,表示是primary,当primary宕机时,就会使用priority 值次之的当primary 角色


> rs.initiate(config_res1);


{


"info" : "Config now saved locally. Should come online in about a minute.",


"ok" : 1


}


_id:'res1'这个_id:的值必须是你set集合的名称,就是--replSet的集合名称,否则就是提示你


Error message 信息


"errmsg" : "couldn't initiate : set name does not match the set name host 192.168.1.247:27018 expects"


之后查看状态


rs.status();


{


"set" : "res1", ###set 集名称


"date" : ISODate("2013-12-04T00:37:08Z"), 创建日期


"myState" : 1,


"members" : [


{


"_id" : 0,


"name" : "192.168.1.248:27017",


"health" : 1, 1表示正常访问,0异常


"state" : 1, 1表示是primary 2表示secondary


"stateStr" : "PRIMARY", primary 主库


"uptime" : 1632,


"optime" : Timestamp(1386116964, 1),


"optimeDate" : ISODate("2013-12-04T00:29:24Z"),


"self" : true


},


{


"_id" : 1,


"name" : "192.168.1.247:27018",


"health" : 1,


"state" : 2,


"stateStr" : "SECONDARY",


"uptime" : 461,


"optime" : Timestamp(1386116964, 1),


"optimeDate" : ISODate("2013-12-04T00:29:24Z"),


"lastHeartbeat" : ISODate("2013-12-04T00:37:07Z"),


"lastHeartbeatRecv" : ISODate("2013-12-04T00:37:07Z"),


"pingMs" : 0,


"syncingTo" : "192.168.1.248:27017"


},


{


"_id" : 2,


"name" : "192.168.1.250:27019",


"health" : 1,


"state" : 2,


"stateStr" : "SECONDARY",


"uptime" : 461,


"optime" : Timestamp(1386116964, 1),


"optimeDate" : ISODate("2013-12-04T00:29:24Z"),


"lastHeartbeat" : ISODate("2013-12-04T00:37:08Z"),


"lastHeartbeatRecv" : ISODate("2013-12-04T00:37:08Z"),


"pingMs" : 1,


"syncingTo" : "192.168.1.248:27017"


}


],


"ok" : 1


}


同步好信息之后,查看另外两个mongodb的日志,就会发现


Fri Dec 6 15:48:48.380 [conn33] end connection 192.168.1.247:25633 (1 connection now open)


Fri Dec 6 15:48:48.381 [initandlisten] connection accepted from 192.168.1.247:25635 #35 (2 connections now open)


Fri Dec 6 15:48:48.383 [conn35] authenticate db: local { authenticate: 1, nonce: "6d6fb8a5d540c164", user: "__system", key: "51b0f27144ec17860f1ca2bd245807ce" }


表示正常的


也可以使用


res1:PRIMARY> rs.isMaster();查看replica set的信息


{


"setName" : "res1",


"ismaster" : true,


"secondary" : false,


"hosts" : [


"192.168.1.248:27017",


"192.168.1.250:27019"


],


"passives" : [


"192.168.1.247:27018"


],


"primary" : "192.168.1.248:27017",


"me" : "192.168.1.248:27017",


"maxBsonObjectSize" : 16777216,


"maxMessageSizeBytes" : 48000000,


"localTime" : ISODate("2013-12-04T00:42:57.347Z"),


"ok" : 1


Replica set的配置文件,也可以用来更改、增加节点信息


res1:PRIMARY> rs.conf();

{


"_id" : "res1",


"version" : 1,


"members" : [


{


"_id" : 0,


"host" : "192.168.1.248:27017",


"priority" : 2


},


{


"_id" : 1,


"host" : "192.168.1.247:27018",


"priority" : 0


},


{


"_id" : 2,


"host" : "192.168.1.250:27019"


}


]


}


以上步骤,就是replica set的一个搭建的过程,接下来就是操作和验证


五:主从操作的oplog日志


Mongodbreplica set架构是通过一个日志来存储写操作的,这个日志就是'oplog'。Oplog是一个固定长度的capped collection,它存放于local数据库下,用于记录replica sets的操作记录。Oplog的日志大小是可以调整的,就在我们启动的时候使用--oplogSize 参数指定的,单位是MB


res1:PRIMARY> show dbs;


admin (empty)


local 0.203125GB (有oplogcollection,是有数据的)


先在primary上创建库,secondary是无法读写操作的(等下可以解决读的问题)


Use test1


db.appstore.save({'e_name':'frank','e_id':1101,'class_id':1});


db.appstore.find();


{ "_id" : ObjectId("529e7c88d4d317e4bd3eece9"), "e_name" : "frank", "e_id" : 1101, "class_id" : 1 }


之后,你会看到另外两台mongodblog日志的变化,有追加:


Fri Dec 6 15:56:22.338 [FileAllocator] allocating new datafile /data/mon_db/res2/test1.ns, filling with zeroes...


Fri Dec 6 15:56:22.474 [FileAllocator] done allocating datafile /data/mon_db/res2/test1.ns, size: 16MB, took 0.136 secs


Fri Dec 6 15:56:22.474 [FileAllocator] allocating new datafile /data/mon_db/res2/test1.0, filling with zeroes...


Fri Dec 6 15:56:23.850 [FileAllocator] done allocating datafile /data/mon_db/res2/test1.0, size: 64MB, took 1.376 secs


Fri Dec 6 15:56:23.852 [repl writer worker 1] build index test1.appstore { _id: 1 }


Fri Dec 6 15:56:23.852 [FileAllocator] allocating new datafile /data/mon_db/res2/test1.1, filling with zeroes...


Fri Dec 6 15:56:23.853 [repl writer worker 1] build index done. scanned 0 total records. 0 secs


Fri Dec 6 15:56:27.006 [FileAllocator] done allocating datafile /data/mon_db/res2/test1.1, size: 128MB, took 3.153 secs


Fri Dec 6 15:56:27.007 [rsSyncNotifier] repl: old cursor isDead, will initiate a new one


如果想在secondary上查看数据,默认情况下:


[root@test04 ~]# /usr/local/mongodb/bin/mongo --port 27018


MongoDB shell version: 2.4.8


connecting to: 127.0.0.1:27018/test


res1:SECONDARY> show dbs;show dbs;


admin (empty)


local 0.203125GB


test1 0.203125GB


Ok,可以看到我们刚创建的test1库,


res1:SECONDARY> use test1;

switched to db test1


res1:SECONDARY> show collections


Fri Dec 6 15:59:10.758 error: { "$err" : "not master and slaveOk=false", "code" : 13435 } at src/mongo/shell/query.js:128


OK,提示error


解决办法:


res1:SECONDARY> db.getMongo().setSlaveOk(); (自带的函数)


res1:SECONDARY> show collections;show collections;


appstore


System.indexes


res1:SECONDARY> db.appstore.find();db.appstore.find();


{ "_id" : ObjectId("529e7c88d4d317e4bd3eece9"), "e_name" : "frank", "e_id" : 1101, "class_id" : 1 }


如果说你想写数据,就会提示 not master


db.appstore.insert({'e_name':1102,'e_id':1102});


not master


OK.这样就可以实现读写的分离



怎样查看oplog的日志


use local;


show collections;


oplog.rs


slaves


startup_log


system.indexes


System.replset


就是查看oplog.rs collection


res1:PRIMARY> db.oplog.rs.find();


{ "ts" : Timestamp(1386116964, 1), "h" : NumberLong(0), "v" : 2, "op" : "n", "ns" : "", "o" : { "msg" : "initiating set" } }


{ "ts" : Timestamp(1386118280, 1), "h" : NumberLong("8972935208244346897"), "v" : 2, "op" : "i", "ns" : "test1.appstore", "o" : { "_id" : ObjectId("529e7c88d4d317e4bd3eece9"), "e_name" : "frank", "e_id" : 1101, "class_id" : 1 } }


相关解释:


Ts 表示某个操作的时间戳


Op:表示操作类型,一般包括


I insert 插入


D delete 删除


Uupdate 更新


Ns 命名空间,也就是你操作的collection name


O document(文档),就是你插入的数据信息


查看Mster上的oplog元数据信息:


res1:PRIMARY> db.printReplicationInfo();


configured oplog size: 100MB


log length start to end: 1316secs (0.37hrs)


oplog first event time: Wed Dec 04 2013 08:29:24 GMT+0800 (CST)


oplog last event time: Wed Dec 04 2013 08:51:20 GMT+0800 (CST)


now: Wed Dec 04 2013 09:14:20 GMT+0800 (CST)


Oplog size 是你oplog 的总大小,是可循环的


log length start to end oplog日志的启用时间段,单位 秒


oplog first event time 第一个事务产生的时间


oplog last event time 最后一个事务产生的时间


Now现在的时间


查看slave的数据同步状态


res1:PRIMARY> db.printSlaveReplicationInfo();


source: 192.168.1.247:27018


syncedTo: Wed Dec 04 2013 08:51:20 GMT+0800 (CST)


= 1620 secs ago (0.45hrs)


source: 192.168.1.250:27019


syncedTo: Wed Dec 04 2013 08:51:20 GMT+0800 (CST)


= 1620 secs ago (0.45hrs)


SourceslaveIP和端口信息


SyncedTo:目前的同步情况,延迟了多久等信息


local数据库内,不仅有oplog的集合,还有一个集合是记录set 配置信息


db.system.replset.find();


或者是 rs.conf() 都可以查看到


以上步骤是replica set的搭建过程和相关的查看语句,如有不足之处,还请指点

replica set 节点的增、删、改和故障切换参考:http://1413570.blog.51cto.com/1403570/1337622


0