MongoDB replica sets (复制集)配置与搭建
#------------------------------------------------------------------------------
192.168.1.128:27001 standard
192.168.1.129:27001 standard
192.168.1.130:27001 standard
#以下两台互为双主 147 148均为VIP 正常情况下只启用147 若147故障 将漂移至
148服务器 继续提供仲裁服务
192.168.1.147:27001 arbiter192.168.1.148:27001 arbiter
#------------------------------------------------------------------------------一:节点类型
standard:常规节点 它存储一份完整的数据副本 参与选举投票 有可能成为primary节点;
passive: 存储了完整的数据副本 参与投票 不能成为primary节点;
arbiter: 仲裁节点 只参与投票 不接收复制的数据 也不能成为primary节点。
一个repica sets节点数量最好为奇数(odd)
二:安装MongoDB
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.4.12.tgz
tar zvfx mongodb-linux-x86_64-2.4.12.tgz
mv mongodb-linux-x86_64-2.4.12 /usr/local/mongodb
/usr/sbin/groupadd -g 802 mongodb
/usr/sbin/useradd -g mongodb mongodb -u 802 -s /sbin/nologin
mkdir -p /data/mongodb/{mongodb_data,mongodb_log}
chown -R mongodb.mongodb /data/mongodb/{mongodb_data,mongodb_log}
echo "export PATH=\$PATH:/usr/local/mongodb/bin/" >> /etc/profile
echo "/usr/local/mongodb/mongod.sh restart" >> /etc/rc.local
source /etc/profile
启动MongoDB
192.168.1.128 192.168.1.129 192.168.1.130 三个节点启动方式如下:
vi /usr/local/mongodb/mongod.conf
#date:2015-02-26
#created by zhangluya
INSTALL="/usr/local/mongodb"
#source function library
. /etc/init.d/functions
START_M(){
if [ ! -e ${INSTALL}/mongodb.pid ];then
numactl --interleave=all ${INSTALL}/bin/mongod -f ${INSTALL}/mongod.conf
action "MongoDB start is ..................^_^ " /bin/true
else
echo -e "-------------------------------------------------------------------"
echo -e "\033[1;33m Mongodb process is already exist!!! \033[0m"
echo -e "-------------------------------------------------------------------"
fi
}
STOP_M(){
if [ -e ${INSTALL}/mongodb.pid ];then
kill -2 `cat ${INSTALL}/mongodb.pid`
rm -rf ${INSTALL}/mongodb.pid
action "MongoDB stop is .................. -_-!" /bin/true
else
echo -e "-------------------------------------------------------------------"
echo -e "\033[1;33m MongoDB process is not found!!!! \033[0m"
echo -e "-------------------------------------------------------------------"
fi
}
case "$1" in
start|START)
START_M
;;
stop|STOP)
STOP_M
;;
restart)
STOP_M
START_M
;;
*)
echo "Usage:`basename $0` {start|stop|restart}"
exit 1
esac
#-------------------------------------------------------------------------------------------------
img_20150226:SECONDARY> db.getMongo().setSlaveOk();
img_20150226:SECONDARY> show tables;
查看连接数:
img_20150226:SECONDARY> db.serverStatus().connections;
{ "current" : 4, "available" : 9996, "totalCreated" : NumberLong(107) }
mongodb 添加和删除节点
--dbpath 数据文件路径
--logpath 日志文件路径
--port 端口号 默认是27017
--replSet 复制集的名字,一个replica sets中的每个节点的这个参数都要用一个复制集名字,这里是test.
--replSet test/ 这个后面跟的是其他standard节点的ip和端口
--maxConns 最大连接数
--fork 后台运行
--logappend 日志文件循环使用,如果日志文件已满,那么新日志覆盖最久日志
--keyFile 标识同一集群的认证私钥
--oplogSize 日志操作文件的大
--nojournal 关闭日志 日志选项在64位机器上默认为开启
-h [--help] 显示所有帮助信息
--version 显示版本信息
-f [--config] arg 从配置文件启动MongoDb,配置文件中可以配置启动参数
-v [--verbose]
--quiet 不显示系统信息,如系统版本信息,当前登录信息等
--port 启动服务端口,默认是27017
--bind_ip 配置可连接本机的IP列表,默认是侦听所有IP
--maxConns 配置最大的连接数,默认是20000
--objcheck 是否检查客户端输入数据的有效性
--logpath 配置日志路径,这个路径必须是一个有效的文件,不能是文件夹
--logappend 用追加方式来替代覆盖方式输出日志
--pidfilepath full path to pidfile(if not set, no pidfile is created)
--keyFile 配置集群认证密钥
--auth 开启登录认证模式
--cpu 开启定期显示CPU和IOWait利用状态
--diaglog 0=off 1=W 2=R 3=both 7=W+some reads
--dbpath 配置数据文件的存放路径
--directoryperdb 如果需要为每个目录创建一个独立的文件夹,启动时可以输入此参数
--ipv6 开启对IPv6的支持
--journal 开启日志
--journalCommitInterval how often to group/batch commit(ms)
--journalOptions 日志诊断参数
--jsonp 允许JSONP通过http协议(有安全风险)
--noauth 关闭登录验证
--nohttpinterface 关闭http监控接口
--nojournal 关闭日志,日志选项在64位机器上默认为开启
--noprealloc 禁用数据文件预分配项,此选项往往会影响性能
--noscripting 关闭script引擎
--notablescan 关闭全表扫描
--nssize 新数据库.ns文件的大小,默认是16M
--profile 0=off 1=slow,2=all
--quota 限定每个数据库数据文件的个数,默认是8
--qoutaFiles 制定每个数据库的数据文件个数,需要输入-qouta参数
--repair 开启修复功能
--repairpath repair文件的存放目录,默认是dbpath
--rest 开启简单的rest接口
--slowms value of slow for profile and console log (defalut 100)
--smallfiles 使用较小的默认文件大小
--syncdelay 磁盘的同步时间(0为不同步,不推荐)
--sysinfo 打印系统诊断信息
--upgrade 在需要时更新数据库
source /etc/profile
启动MongoDB
192.168.1.128 192.168.1.129 192.168.1.130 三个节点启动方式如下:
vi /usr/local/mongodb/mongod.conf
#--------------------------------------------------------------------
pidfilepath = /usr/local/mongodb/mongodb.pid
dbpath = /data/mongodb/mongodb_data
logpath = /data/mongodb/mongodb_log/mongodb.log
logappend = true
port = 27001
fork = true
journal = true
replSet = img_20150226
maxConns = 10000
pidfilepath = /usr/local/mongodb/mongodb.pid
dbpath = /data/mongodb/mongodb_data
logpath = /data/mongodb/mongodb_log/mongodb.log
logappend = true
port = 27001
fork = true
journal = true
replSet = img_20150226
maxConns = 10000
#-------------------------------------------------------------------------------------------------
#!/bin/bash#date:2015-02-26
#created by zhangluya
INSTALL="/usr/local/mongodb"
#source function library
. /etc/init.d/functions
START_M(){
if [ ! -e ${INSTALL}/mongodb.pid ];then
numactl --interleave=all ${INSTALL}/bin/mongod -f ${INSTALL}/mongod.conf
action "MongoDB start is ..................^_^ " /bin/true
else
echo -e "-------------------------------------------------------------------"
echo -e "\033[1;33m Mongodb process is already exist!!! \033[0m"
echo -e "-------------------------------------------------------------------"
fi
}
STOP_M(){
if [ -e ${INSTALL}/mongodb.pid ];then
kill -2 `cat ${INSTALL}/mongodb.pid`
rm -rf ${INSTALL}/mongodb.pid
action "MongoDB stop is .................. -_-!" /bin/true
else
echo -e "-------------------------------------------------------------------"
echo -e "\033[1;33m MongoDB process is not found!!!! \033[0m"
echo -e "-------------------------------------------------------------------"
fi
}
case "$1" in
start|START)
START_M
;;
stop|STOP)
STOP_M
;;
restart)
STOP_M
START_M
;;
*)
echo "Usage:`basename $0` {start|stop|restart}"
exit 1
esac
#-------------------------------------------------------------------------------------------------
chmod a+x /usr/local/mongodb/mongod.sh
echo "/usr/local/mongodb/mongod.sh restart" >> /etc/rc.local
三:配置数据库
192.168.1.128 服务器执行:
/usr/local/mongodb/bin/mongo --host 192.168.1.128:27001
#初始化节点
rs.initiate({"_id":"img_20150226",members:[
{"_id":1,"host":"192.168.1.128:27001"},
{"_id":2,"host":"192.168.1.129:27001"},
{"_id":3,"host":"192.168.1.130:27001"},
]})
#为集群添加仲裁节点(非PRIMARY不能动态添加节点)
img_20150226:PRIMARY> rs.addArb("192.168.1.147:27001")
#查看状态
img_20150226:PRIMARY> rs.status()
{
"set" : "img_20150226",
"date" : ISODate("2015-02-27T07:10:42Z"),
"myState" : 1,
"members" : [
{
"_id" : 1,
"name" : "192.168.1.128:27001",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2517,
"optime" : Timestamp(1425021028, 1),
"optimeDate" : ISODate("2015-02-27T07:10:28Z"),
"self" : true
},
{
"_id" : 2,
"name" : "192.168.1.129:27001",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 407,
"optime" : Timestamp(1425021028, 1),
"optimeDate" : ISODate("2015-02-27T07:10:28Z"),
"lastHeartbeat" : ISODate("2015-02-27T07:10:41Z"),
"lastHeartbeatRecv" : ISODate("2015-02-27T07:10:41Z"),
"pingMs" : 0,
"syncingTo" : "192.168.1.128:27001"
},
{
"_id" : 3,
"name" : "192.168.1.130:27001",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 405,
"optime" : Timestamp(1425021028, 1),
"optimeDate" : ISODate("2015-02-27T07:10:28Z"),
"lastHeartbeat" : ISODate("2015-02-27T07:10:41Z"),
"lastHeartbeatRecv" : ISODate("2015-02-27T07:10:42Z"),
"pingMs" : 0,
"syncingTo" : "192.168.1.128:27001"
},
{
"_id" : 4,
"name" : "192.168.1.147:27001",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 14,
"lastHeartbeat" : ISODate("2015-02-27T07:10:40Z"),
"lastHeartbeatRecv" : ISODate("2015-02-27T07:10:42Z"),
"pingMs" : 0
}
],
"ok" : 1
}
测试:192.168.1.128 上执行
img_20150226:PRIMARY> db.luya.insert({name:1})
img_20150226:PRIMARY> show dbs
local 523.822265625GB
luya 0.203125GB
img_20150226:PRIMARY> show dbs
local 523.822265625GB
luya 0.203125GB
192.168.1.129 查看: 确认成功
img_20150226:SECONDARY> show dbs;
local 523.822265625GB
luya 0.203125GB
192.168.1.147 仲裁节点不存储数据 只负责故障转移的群体投票
img_20150226:ARBITER> show dbs;
local 0.078125GB
添加集群节点:primary节点执行
test:PRIMARY> rs.add("10.0.0.113:27018");
{ "down" : [ "10.0.0.113:27018" ], "ok" : 1 }
#查看当前谁是PRIMARY
img_20150226:ARBITER> rs.isMaster()
{
"setName" : "img_20150226",
"ismaster" : false,
"secondary" : false,
"hosts" : [
"192.168.1.130:27001",
"192.168.1.129:27001",
"192.168.1.128:27001"
],
"arbiters" : [
"192.168.1.147:27001"
],
"primary" : "192.168.1.128:27001",
"arbiterOnly" : true,
"me" : "192.168.1.147:27001",
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"localTime" : ISODate("2015-02-27T07:20:26.908Z"),
"ok" : 1
}
读写分离:副本节点默认是不能读的 我们想从副本节点读取数据 需要设置一下
img_20150226:SECONDARY> show tables;
Fri Feb 27 15:21:38.631 error: { "$err" : "not master and slaveOk=false", "code" : 13435 } at src/mongo/shell/query.js:128
echo "/usr/local/mongodb/mongod.sh restart" >> /etc/rc.local
三:配置数据库
192.168.1.128 服务器执行:
/usr/local/mongodb/bin/mongo --host 192.168.1.128:27001
#初始化节点
rs.initiate({"_id":"img_20150226",members:[
{"_id":1,"host":"192.168.1.128:27001"},
{"_id":2,"host":"192.168.1.129:27001"},
{"_id":3,"host":"192.168.1.130:27001"},
]})
#为集群添加仲裁节点(非PRIMARY不能动态添加节点)
img_20150226:PRIMARY> rs.addArb("192.168.1.147:27001")
#查看状态
img_20150226:PRIMARY> rs.status()
{
"set" : "img_20150226",
"date" : ISODate("2015-02-27T07:10:42Z"),
"myState" : 1,
"members" : [
{
"_id" : 1,
"name" : "192.168.1.128:27001",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2517,
"optime" : Timestamp(1425021028, 1),
"optimeDate" : ISODate("2015-02-27T07:10:28Z"),
"self" : true
},
{
"_id" : 2,
"name" : "192.168.1.129:27001",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 407,
"optime" : Timestamp(1425021028, 1),
"optimeDate" : ISODate("2015-02-27T07:10:28Z"),
"lastHeartbeat" : ISODate("2015-02-27T07:10:41Z"),
"lastHeartbeatRecv" : ISODate("2015-02-27T07:10:41Z"),
"pingMs" : 0,
"syncingTo" : "192.168.1.128:27001"
},
{
"_id" : 3,
"name" : "192.168.1.130:27001",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 405,
"optime" : Timestamp(1425021028, 1),
"optimeDate" : ISODate("2015-02-27T07:10:28Z"),
"lastHeartbeat" : ISODate("2015-02-27T07:10:41Z"),
"lastHeartbeatRecv" : ISODate("2015-02-27T07:10:42Z"),
"pingMs" : 0,
"syncingTo" : "192.168.1.128:27001"
},
{
"_id" : 4,
"name" : "192.168.1.147:27001",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 14,
"lastHeartbeat" : ISODate("2015-02-27T07:10:40Z"),
"lastHeartbeatRecv" : ISODate("2015-02-27T07:10:42Z"),
"pingMs" : 0
}
],
"ok" : 1
}
测试:192.168.1.128 上执行
img_20150226:PRIMARY> db.luya.insert({name:1})
img_20150226:PRIMARY> show dbs
local 523.822265625GB
luya 0.203125GB
img_20150226:PRIMARY> show dbs
local 523.822265625GB
luya 0.203125GB
192.168.1.129 查看: 确认成功
img_20150226:SECONDARY> show dbs;
local 523.822265625GB
luya 0.203125GB
192.168.1.130 查看: 确认成功
img_20150226:SECONDARY> show dbs;
local 523.822265625GB
luya 0.203125GB
local 523.822265625GB
luya 0.203125GB
192.168.1.147 仲裁节点不存储数据 只负责故障转移的群体投票
img_20150226:ARBITER> show dbs;
local 0.078125GB
添加集群节点:primary节点执行
test:PRIMARY> rs.add("10.0.0.113:27018");
{ "down" : [ "10.0.0.113:27018" ], "ok" : 1 }
#查看当前谁是PRIMARY
img_20150226:ARBITER> rs.isMaster()
{
"setName" : "img_20150226",
"ismaster" : false,
"secondary" : false,
"hosts" : [
"192.168.1.130:27001",
"192.168.1.129:27001",
"192.168.1.128:27001"
],
"arbiters" : [
"192.168.1.147:27001"
],
"primary" : "192.168.1.128:27001",
"arbiterOnly" : true,
"me" : "192.168.1.147:27001",
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"localTime" : ISODate("2015-02-27T07:20:26.908Z"),
"ok" : 1
}
读写分离:副本节点默认是不能读的 我们想从副本节点读取数据 需要设置一下
img_20150226:SECONDARY> show tables;
Fri Feb 27 15:21:38.631 error: { "$err" : "not master and slaveOk=false", "code" : 13435 } at src/mongo/shell/query.js:128
img_20150226:SECONDARY> db.getMongo().setSlaveOk();
img_20150226:SECONDARY> show tables;
查看连接数:
img_20150226:SECONDARY> db.serverStatus().connections;
{ "current" : 4, "available" : 9996, "totalCreated" : NumberLong(107) }
mongodb 添加和删除节点
img_20150226:PRIMARY> rs.add("192.168.1.148:27001");
{ "ok" : 1 }
添加之后,mongodb 会自动执行新加节点的恢复操作,所以第一次查询rs.status()时候,新加节点的信息为空,等待恢复完成之后再次查询就有了基本信息了。
删除节点操作
img_20150226:PRIMARY> rs.remove("192.168.1.148:27001");
查看复制情况:
{ "ok" : 1 }
添加之后,mongodb 会自动执行新加节点的恢复操作,所以第一次查询rs.status()时候,新加节点的信息为空,等待恢复完成之后再次查询就有了基本信息了。
删除节点操作
img_20150226:PRIMARY> rs.remove("192.168.1.148:27001");
查看复制情况:
img_20150226:PRIMARY> db.printSlaveReplicationInfo()
source: 192.168.1.129:27001
syncedTo: Fri Feb 27 2015 15:38:43 GMT+0800 (CST)
= 754 secs ago (0.21hrs)
source: 192.168.1.130:27001
syncedTo: Fri Feb 27 2015 15:38:43 GMT+0800 (CST)
= 754 secs ago (0.21hrs)
source: 192.168.1.147:27001
no replication info, yet. State: ARBITER
source: 192.168.1.129:27001
syncedTo: Fri Feb 27 2015 15:38:43 GMT+0800 (CST)
= 754 secs ago (0.21hrs)
source: 192.168.1.130:27001
syncedTo: Fri Feb 27 2015 15:38:43 GMT+0800 (CST)
= 754 secs ago (0.21hrs)
source: 192.168.1.147:27001
no replication info, yet. State: ARBITER
查看配置文件
img_20150226:PRIMARY> rs.conf()
{
"_id" : "img_20150226",
"version" : 6,
"members" : [
{
"_id" : 1,
"host" : "192.168.1.128:27001"
},
{
"_id" : 2,
"host" : "192.168.1.129:27001"
},
{
"_id" : 3,
"host" : "192.168.1.130:27001"
},
{
"_id" : 4,
"host" : "192.168.1.147:27001",
"arbiterOnly" : true
}
]
}
#另外这个连接数还受Linux系统的影响 Linux每个进程的最大连接数
ulimit -n
PS:
{
"_id" : "img_20150226",
"version" : 6,
"members" : [
{
"_id" : 1,
"host" : "192.168.1.128:27001"
},
{
"_id" : 2,
"host" : "192.168.1.129:27001"
},
{
"_id" : 3,
"host" : "192.168.1.130:27001"
},
{
"_id" : 4,
"host" : "192.168.1.147:27001",
"arbiterOnly" : true
}
]
}
#另外这个连接数还受Linux系统的影响 Linux每个进程的最大连接数
ulimit -n
PS:
所有的Secondary都宕机、或则副本集中只剩下一个节点,则该节点只能为Secondary节点,也就意味着整个集群智能进行读操作而不能进行写操作,当其他的恢复时,之前的primary节点仍然是primary节点。
当某个节点宕机后重新启动该节点会有一段的时间(时间长短视集群的数据量和宕机时间而定)导致整个集群中所有节点都成为secondary而无法进行写操作(如果应用程序没有设置相应的ReadReference也可能不能进行读取操作)。
启动参数详解:--dbpath 数据文件路径
--logpath 日志文件路径
--port 端口号 默认是27017
--replSet 复制集的名字,一个replica sets中的每个节点的这个参数都要用一个复制集名字,这里是test.
--replSet test/ 这个后面跟的是其他standard节点的ip和端口
--maxConns 最大连接数
--fork 后台运行
--logappend 日志文件循环使用,如果日志文件已满,那么新日志覆盖最久日志
--keyFile 标识同一集群的认证私钥
--oplogSize 日志操作文件的大
--nojournal 关闭日志 日志选项在64位机器上默认为开启
-h [--help] 显示所有帮助信息
--version 显示版本信息
-f [--config] arg 从配置文件启动MongoDb,配置文件中可以配置启动参数
-v [--verbose]
--quiet 不显示系统信息,如系统版本信息,当前登录信息等
--port 启动服务端口,默认是27017
--bind_ip 配置可连接本机的IP列表,默认是侦听所有IP
--maxConns 配置最大的连接数,默认是20000
--objcheck 是否检查客户端输入数据的有效性
--logpath 配置日志路径,这个路径必须是一个有效的文件,不能是文件夹
--logappend 用追加方式来替代覆盖方式输出日志
--pidfilepath full path to pidfile(if not set, no pidfile is created)
--keyFile 配置集群认证密钥
--auth 开启登录认证模式
--cpu 开启定期显示CPU和IOWait利用状态
--diaglog 0=off 1=W 2=R 3=both 7=W+some reads
--dbpath 配置数据文件的存放路径
--directoryperdb 如果需要为每个目录创建一个独立的文件夹,启动时可以输入此参数
--ipv6 开启对IPv6的支持
--journal 开启日志
--journalCommitInterval how often to group/batch commit(ms)
--journalOptions 日志诊断参数
--jsonp 允许JSONP通过http协议(有安全风险)
--noauth 关闭登录验证
--nohttpinterface 关闭http监控接口
--nojournal 关闭日志,日志选项在64位机器上默认为开启
--noprealloc 禁用数据文件预分配项,此选项往往会影响性能
--noscripting 关闭script引擎
--notablescan 关闭全表扫描
--nssize 新数据库.ns文件的大小,默认是16M
--profile 0=off 1=slow,2=all
--quota 限定每个数据库数据文件的个数,默认是8
--qoutaFiles 制定每个数据库的数据文件个数,需要输入-qouta参数
--repair 开启修复功能
--repairpath repair文件的存放目录,默认是dbpath
--rest 开启简单的rest接口
--slowms value of slow for profile and console log (defalut 100)
--smallfiles 使用较小的默认文件大小
--syncdelay 磁盘的同步时间(0为不同步,不推荐)
--sysinfo 打印系统诊断信息
--upgrade 在需要时更新数据库