MongoDB创建副本集

CentOS6平台安装MongoDB3.2副本集

汕城ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18980820575(备注:SSL证书合作)期待与您的合作!

一,3台机器全部安装部署mongod

1,下载安装包,并解压tgz

curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.10.tgz

tar xf mongodb-linux-x86_64-3.2.10.tgz

mv mongodb-linux-x86_64-3.2.10 /usr/local/mongodb

2,,可执行文件添加到 PATH 路径中:

export PATH=/usr/local/mongodb/bin:$PATH

echo 'export PATH=/usr/local/mongodb/bin:$PATH' > /etc/profile.d/mongodb.sh

3,关闭大页面内存

echo never > /sys/kernel/mm/transparent_hugepage/enabled

echo never > /sys/kernel/mm/transparent_hugepage/defrag

echo "if test -f /sys/kernel/mm/transparent_hugepage/enabled;then    

   echo never > /sys/kernel/mm/transparent_hugepage/enabled

fi

if test -f /sys/kernel/mm/transparent_hugepage/defrag;then

   echo never > /sys/kernel/mm/transparent_hugepage/defrag

fi" >> /etc/rc.d/rc.local

4,限制

ulimit -f unlimited  

ulimit -t unlimited  

ulimit -v unlimited  

ulimit -n 64000  

ulimit -m unlimited  

ulimit -u 64000  

5,创建数据库目录

mkdir -p /data0/mongodb/shardA/data

mkdir -p /data0/logs/mongodb/

6,运行MongoDB服务  

(1)编写配置文件

cat /data0/mongodb/shardA/mongo27017.conf

#mongodb shardA 27017

replSet=shardA

dbpath=/data0/mongodb/shardA/data

logpath=/data0/logs/mongodb/27017.log

#bind=192.168.9.168,127.0.0.1

port=27017

fork=true

maxConns=20000

logappend=true

smallfiles=true

(2)启动

/usr/local/mongodb/bin/mongod -f /data0/mongodb/shardA/mongo27017.conf

#其他方式启动

命令行指定dbpath和port

/usr/local/mongodb/bin/mongod --dbpath=/data0/mongodb/shardA --port 27017 &# 默认端口为27017

命令行指定dbpath和port,并启动web界面

/usr/local/mongodb/bin/mongod --dbpath=/data0/mongodb/shardA --port 27017 --rest &      #web默认端口为28017

7,查看是否启动正常

netstat -lnptu | grep 27017

ps auxf | grep mongod | grep -v grep

MongoDB后台管理shell

/usr/local/mongodb/bin/mongo 127.0.0.1:27017/test

/usr/local/mongodb/bin/mongo  --port 27017

二,配置副本集

1,#连接一台mongo

# /usr/local/mongodb/bin/mongo 192.168.9.168:27017

MongoDB shell version: 3.2.10

2,# 配置168为主,176为从,225为仲裁节点,priority最大为主节点,arbiterOnly仅作为仲裁

> cfg={_id:"shardA", members:[{_id:0,host:'192.168.9.168:27017',priority:2},{_id:1,host:'192.168.9.176:27017',priority:1},{_id:2,host:'192.168.9.225:27017',arbiterOnly:true}]};

{

"_id" : "shardA",

"members" : [

{

"_id" : 0,

"host" : "192.168.9.168:27017",

"priority" : 2

},

{

"_id" : 1,

"host" : "192.168.9.176:27017",

"priority" : 1

},

{

"_id" : 2,

"host" : "192.168.9.225:27017",

"arbiterOnly" : true

}

]

}

# 初始化

> rs.initiate(cfg)

{ "ok" : 1 }

# 也可以手动添加

> rs.initiate()

> rs.add("192.168.9.176:27017")

> rs.add("192.168.9.225:27017",{arbiterOnly:true})

{ "ok" : 1 }

# 删除节点

> rs.remove()

3,查看状态

#查看配置内容

> rs.conf()

#查看状态信息

> rs.status()

#查看是否为主节点

> db.isMaster()

4,主节点插入数据

mongo 192.168.9.176:27017

> show dbs

> use Atest

> for (i=0;i<=1000;i++) db.coltest.insert({count:i})

> show tables

> db.coltest.count()

> db.coltest.find()

mongo 192.168.9.168:27017

> rs.slaveOk()

> show dbs

> show tables

> db.coltest.count()

> db.coltest.find()

shardA:SECONDARY> db.coltest.insert({"count":"10003"})

WriteResult({ "writeError" : { "code" : 10107, "errmsg" : "not master" } })

三,故障转移测试

1,关闭主节点

mongo 192.168.9.176:27017

shardA:PRIMARY> use admin

switched to db admin

shardA:PRIMARY> db.shutdownServer()

server should be down...

2017-11-30T14:13:23.223+0800 I NETWORK  [thread1] trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed

2017-11-30T14:13:24.116+0800 I NETWORK  [thread1] Socket recv() errno:104 Connection reset by peer 127.0.0.1:27017

2017-11-30T14:13:24.116+0800 I NETWORK  [thread1] SocketException: remote: (NONE):0 error: 9001 socket exception [RECV_ERROR] server [127.0.0.1:27017]

2017-11-30T14:13:24.116+0800 I NETWORK  [thread1] reconnect 127.0.0.1:27017 (127.0.0.1) failed failed

2017-11-30T14:13:24.118+0800 I NETWORK  [thread1] trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed

2017-11-30T14:13:24.118+0800 W NETWORK  [thread1] Failed to connect to 127.0.0.1:27017, reason: errno:111 Connection refused

2017-11-30T14:13:24.118+0800 I NETWORK  [thread1] reconnect 127.0.0.1:27017 (127.0.0.1) failed failed

>

2,查看备用节点会成为主节点

shardA:SECONDARY>

shardA:PRIMARY> rs.status()

{

"set" : "shardA",

"date" : ISODate("2017-11-30T06:13:57.404Z"),

"myState" : 1,

"term" : NumberLong(3),

"heartbeatIntervalMillis" : NumberLong(2000),

"members" : [

{

"_id" : 0,

"name" : "192.168.9.168:27017",

"health" : 1,

"state" : 1,

"stateStr" : "PRIMARY",

"uptime" : 74322,

"optime" : {

"ts" : Timestamp(1512022413, 1),

"t" : NumberLong(3)

},

"optimeDate" : ISODate("2017-11-30T06:13:33Z"),

"infoMessage" : "could not find member to sync from",

"electionTime" : Timestamp(1512022412, 1),

"electionDate" : ISODate("2017-11-30T06:13:32Z"),

"configVersion" : 1,

"self" : true

},

{

"_id" : 1,

"name" : "192.168.9.176:27017",

"health" : 0,

"state" : 8,

"stateStr" : "(not reachable/healthy)",

"uptime" : 0,

"optime" : {

"ts" : Timestamp(0, 0),

"t" : NumberLong(-1)

},

"optimeDate" : ISODate("1970-01-01T00:00:00Z"),

"lastHeartbeat" : ISODate("2017-11-30T06:13:56.562Z"),

"lastHeartbeatRecv" : ISODate("2017-11-30T06:13:21.617Z"),

"pingMs" : NumberLong(0),

"lastHeartbeatMessage" : "Connection refused",

"configVersion" : -1

},

{

"_id" : 2,

"name" : "192.168.9.225:27017",

"health" : 1,

"state" : 7,

"stateStr" : "ARBITER",

"uptime" : 70496,

"lastHeartbeat" : ISODate("2017-11-30T06:13:56.543Z"),

"lastHeartbeatRecv" : ISODate("2017-11-30T06:13:52.776Z"),

"pingMs" : NumberLong(0),

"configVersion" : 1

}

],

"ok" : 1

}

shardA:PRIMARY>

3,重新启动原主节点,现主节点还会切过去

shardA:SECONDARY> db.isMaster()

{

"hosts" : [

"192.168.9.168:27017",

"192.168.9.176:27017"

],

"arbiters" : [

"192.168.9.225:27017"

],

"setName" : "shardA",

"setVersion" : 1,

"ismaster" : false,

"secondary" : true,

"primary" : "192.168.9.176:27017",

"me" : "192.168.9.168:27017",

"maxBsonObjectSize" : 16777216,

"maxMessageSizeBytes" : 48000000,

"maxWriteBatchSize" : 1000,

"localTime" : ISODate("2017-11-30T06:20:47.355Z"),

"maxWireVersion" : 4,

"minWireVersion" : 0,

"ok" : 1

}

4,关闭副本集

五,维护相关

1,先关闭从节点、仲裁节点。或者先关闭仲裁节点,最后关闭从节点。则:主节点自动变为从节点

2,先关闭主节点,则从节点自动变为主节点,在仲裁节点关闭之前,新主节点不能关闭

初始化的时候主备节点受priority的影响

priority: 是优先级,默认为1,优先级0为被动节点,不能成为活跃节点。优先级不为0则按照由大到小选出活跃节点。

rs辅助函数

> rs.help()

rs.status()                                { replSetGetStatus : 1 } checks repl set status

rs.initiate()                              { replSetInitiate : null } initiates set with default settings

rs.initiate(cfg)                           { replSetInitiate : cfg } initiates set with configuration cfg

rs.conf()                                  get the current configuration object from local.system.replset

rs.reconfig(cfg)                           updates the configuration of a running replica set with cfg (disconnects)

rs.add(hostportstr)                        add a new member to the set with default attributes (disconnects)

rs.add(membercfgobj)                       add a new member to the set with extra attributes (disconnects)

rs.addArb(hostportstr)                     add a new member which is arbiterOnly:true (disconnects)

rs.stepDown([stepdownSecs, catchUpSecs])   step down as primary (disconnects)

rs.syncFrom(hostportstr)                   make a secondary sync from the given member

rs.freeze(secs)                            make a node ineligible to become primary for the time specified

rs.remove(hostportstr)                     remove a host from the replica set (disconnects)

rs.slaveOk()                               allow queries on secondary nodes

rs.printReplicationInfo()                  check oplog size and time range

rs.printSlaveReplicationInfo()             check replica set members and replication lag

db.isMaster()                              check who is primary

reconfiguration helpers disconnect from the database so the shell will display

an error, even if the command succeeds.

六,设计副本集

1,副本集重要的一个概念是"大多数",大多数为一半以上的成员

比如5个成员的副本集,有3个为网络不可达,仍有二个可以正常工作,但达不到大多数的要求,所以无法选出主节点,如果 有个是主节点,会切换为备节点;

主要防止,3个网络不可达,为3个可通信,防止出现2个主节点;

2,推荐模式有:

一个数据中心奇数成员

俩个数据中心奇数成员,将大多数放在一个数据中心

三个数据中心,俩个相等数量成员的数据中心,一个为决定主节点的数据中心

3,选举机制

当一个备份节点无法与主节点连通时,它会联系并请求其他的副本集成员将自己选举为自己。

其它成员会做几项理性的检查:

(1)自身是否能够与主节点通信

(2)希望被选举为主节点的备份节点的数据是否为最新

(3)有没有其他更高优先级的成员可以被选举为主节点

七,成员配置项

1,选举仲裁者

只参与选举,并不保存数据

(1)最多只能有一个仲裁者

(2)如果节点数为奇数,则不需要仲裁者

# 添加仲裁成员

rs.addArb("192.168.9.168:27017")

rs.add({_id:2,host:'192.168.9.225:27017',arbiterOnly:true})

2,优先级

优先级取值范围0-100,默认为1,0为永远不可以成为主节点,这样的称为被动成员

优先级越高,且拥有最新的数据,那么会被选举为主节点

3,隐藏成员

客户端不会向隐藏成员发送请求,隐藏成员也不会作为复制源

hidden:true 只有优先级0的成员 才能被隐藏

4,延迟备份节点

八,同步

复制用于多台服务器之间的备份数据。使用操作日志oplog实现的。

oplog是主节点local数据库中一个固定集合,备份节点通过查询这个集合就可以知道需要进行复制的操作

1,初始化同步

(1)成员会做一些记录前的准备工作:选择一个成员作为同步源,在local.me中为自己创建一个标识符,删除所有已存在的数据库,重新同步

(2)克隆,将同步源的所有记录全部复制到本地

(3)进入oplog同步的第一步,克隆中的所有操作都会被记录到oplog中

(4)oplog同步的第二步,用于将第一个oplog同步中的操作记录下来

(5)本地数据应该与主节点在某个时间点的数据集完全一致了,可以创建索引

(6)当前节点的数据如果仍落后于同步源,那么oplog同步过程的最后一步就是将创建索引期间的所有操作全部同步过来,防止该成员成为备份节点

(7)当前成员完成初始化同步,切换到普通同步状态

九,心跳

成员每隔2s会向其他成员发送一个心跳请求

成员状态:

1,STARTUP    

成员刚启动时处于这个状态。mongodb会尝试加载成员的副本集配置。加载成功后,会进入STARTUP2

2,STARTUP2    

整个初始化同步过程 都处于这个状态

3,RECOVERING

4,ARBITER

5,DOWN

6,UNKNOWN

7,REMOVED

8,ROLLBACK

9,FATAL

十,管理

1,以单机模式启动成员

(1)查看命令行参数

> db.serverCmdLineOpts()

(1)如果要对这台服务器维护,可以重启;重启时不适用 replSet选项。这样会成为一个单机的mongod,可以进行读和写

(2)可以改变监听端口,dbpath值不变

(3)维护完后,以最原始的参数重新启动后会自动与副本集的其他成员进行同步。

2,副本集配置

(1)创建副本集

# 配置168为主,176为从,225为仲裁节点,priority最大为主节点,arbiterOnly仅作为仲裁

> cfg={_id:"shardA", members:[{_id:0,host:'192.168.9.168:27017',priority:2},{_id:1,host:'192.168.9.176:27017',priority:1},{_id:2,host:'192.168.9.225:27017',arbiterOnly:true}]};

# 初始化

> rs.initiate(cfg)

(2)修改副本集成员

a)增加成员

rs.add("192.168.9.169:27017")

文档形式添加指定复杂的配置

rs.add({_id:4,host:'192.168.9.169:27017',priority:1})

b)移除成员

rs.remove("192.168.9.169:27017")

c)通过rs.config修改

> var config = rs.config()

> config.members[0].host = "192.168.9.179:27017"

> rs.reconfig(config)

注意点:

不能修改成员的_id字段

不能将接收rs.reconfig命令的成员的优先级设为0

不能将仲裁成员变为非仲裁成员

不能将"buildIndexes":false的成员修改为"buildIndexes":true

3,创建比较大的副本集

副本集的最多只能拥有12个成员,其中只有7个成员拥有投票权

如果要创建7个以上成员的副本集,只有7个成员可以拥有投票权,需要其他成员的投票数量设置为0

> rs.add({"_id":7,"host":server-7:27017,"votes":0})

4,修改成员状态

# 主节点变为备节点

# 默认为60s

> rs.stepDown(time)

# 阻止选举,始终处于备节点

> rs.freeze(time)

# 强制进入维护模式

> db.adminCommand({"replSetMaintenance":true})

# 退出进入维护模式

> db.adminCommand({"replSetMaintenance":false})

5,状态

# 查看同步状态

> db.printSlaveReplicationInfo()

# 查看同步源

> db.adminCommand({"replSetGetStatus":1}).syncingTo

192.168.9.176:27017

# 指定复制源

> secondary.adminCommand({"replSetSyncFrom":"server0:27017"})

# 禁用复制链

# 复制延迟查看

#  主节点上

> db.printReplicationInfo()

# 备节点上

> db.printSlaveReplicationInfo()

报错:

shardA:SECONDARY> show dbs

2017-11-30T13:57:10.376+0800 E QUERY    [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435 } :

_getErrorWithCode@src/mongo/shell/utils.js:25:13

Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1

shellHelper.show@src/mongo/shell/utils.js:761:19

shellHelper@src/mongo/shell/utils.js:651:15

@(shellhelp2):1:1

原因:为了保护应用程序,以免意外连接到备节点,读取到过期数据。备份节点默认会拒绝请求。

解决:设置从备份节点读取数据没有问题.salveOk是对连接设置的,不是对数据库设置的。。

> rs.slaveOk()


当前标题:MongoDB创建副本集
本文来源:http://scyanting.com/article/gpdesj.html