一:概念
相关概念及图片引用自这里
mongodb副本集: 副本集是一组服务器,其中一个是主服务器,用于处理客户请求;还有多个备份服务器,用于保存主服务器的数据副本。如果主服务器崩溃了,备份服务器自动将其中一个成员升级为新的主服务器。 由此可见副本集对于应对灾难性事件是多么的合适。以前的mongo主从模式其实就是一个单副本的应用,没有很好的扩展性和容错性。而mongodb副本集具有多个副本保证了高性能,数据的一致性,容错性,就算一个副本挂掉了还有很多副本存在,并且解决了上面第一个问题“主节点挂掉了,整个集群内会自动切换”。
由图可以看到客户端连接到整个副本集,不关心具体哪一台机器是否挂掉。主服务器负责整个副本集的读写,副本集定期同步数据备份,一但主节点挂掉,副本节点就会选举一个新的主服务器,这一切对于应用服务器不需要关心。我们看一下主服务器挂掉后的架构:
副本集中的副本节点在主节点挂掉后通过心跳机制检测到后,就会在集群内发起主节点的选举机制,自动选举一位新的主服务器。
其他关于选举等详细概念可以看这里。
官方推荐的副本集机器数量为至少3个,那我们也按照这个数量配置测试。
因此先准备3台虚拟机用于测试:
系统均为:Linux Debian ,分别为:
已分配好的可登录用户分别是:root,user1
二:安装mongodb
以下记录在安装mongodb过程中遇到的问题:
1.在ip为84的虚拟机上,root用户没有开放远程登录权限,用root账号登录时报错:Access denied (网上查到是因为sshd的设置不允许root用户用密码远程登录的原因)
解决办法:user1用户登录后
su // 切换到管理员账号
输入 nano /etc/ssh/sshd_config 回车 //nano是用记事本打开,也可以使用 vi 打开
找到 # Authentication: LoginGraceTime 120 PermitRootLogin without passwd StrictModes yes
把“PermitRootLogin without passwd”改成“PermitRootLogin yes”
按“ctrl+o”保存再退出,退出后记得要重启一下才生效!
reboot //重启
2. root用户目录下安装mongodb
root 登录
cd /root //在root目录下安装
mkdir mongodb
拖动 mongodb-linux-x86_64-3.0.1.tgz 到mongodb目录
解压缩到当前目录:tar zxvf mongodb-linux-x86_64-3.0.1.tgz
3. 配置mongodb启动的配置文件 mongodb.conf
解释一下参数名称:
- dbpath: db数据文件存放位置
- logpath:db的日志文件存放位置
- logappend: 日志是否以追加方式写入
- fork: 后台运行
- port: 访问端口 //默认27017
- noauth: 无认证访问(此处是为测试方便,请勿效仿)
- replSet:副本集核心参数,副本集的名称,这个参数是必须的,而且必须三台机器完全一样
- 更多参数可以根据需要添加
4. 设置环境变量
vi ~/.bashrc // ~/ 表示打开当前用户目录下面的.bashrc文件
拷贝以下设置到文件保存即可
export MONGOHOME=/root/mongodb/mongodb-linux-x86_64-3.0.1
export PATH=$MONGOHOME/bin:$PATH
5. 设置服务开机自启动:
cd /etc/init.d //进入启动项目文件夹下
touch mongodb 创建mongodb文件,将以下内容拷贝到文件并保存
#!/bin/sh
### BEGIN INIT INFO
# Provides: mongod
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start/stop
### END INIT INFO
# Source function library.
. /lib/lsb/init-functions
retval=0
pidfile=`ps -ef | grep 'mongod' | grep -v grep | awk '{print $2}'`
CONFIG="/root/mongodb/mongodb.conf"
PROGRAM="/root/mongodb/mongodb-linux-x86_64-3.0.1/bin/mongod"
MONGOPID=`ps -ef | grep 'mongod' | grep -v grep | awk '{print $2}'`
test -x $PROGRAM || exit 0
case "$1" in
start)
ulimit -n 3000
log_begin_msg "Starting MongoDB server"
$PROGRAM -f $CONFIG &
log_end_msg 0
;;
stop)
log_begin_msg "Stopping MongoDB server"
if [ ! -z "$MONGOPID" ]; then
kill -15 $MONGOPID
fi
log_end_msg 0
;;
status)
;;
*)
log_success_msg "Usage: /etc/init.d/mongodb {start|stop|status}"
exit 1
esac
exit 0
(在mongodb文件存在的情况下,可将mongodb的启动文件拖动到 /etc/init.d文件夹下)
核对:启动项目位置及配置文件位置
CONFIG="/root/mongodb/mongodb.conf"
PROGRAM="/root/mongodb/mongodb-linux-x86_64-3.0.1/bin/mongod"
MONGOPID=`ps -ef | grep 'mongod' | grep -v grep | awk '{print $2}'`
6. 配置好后reboot 重启系统
检测是否能进入mongo:
mongo -v 或者 mongo 命令。
注意项:
因为mongodb是安装在root用户下(Linux系统默认所安装的软件只能在当前用户下有使用权限,换一个用户就没有权限访问),当user用户登录后使用mongo命令时,会报错没有权限访问,这是我们需要设置user用户的访问mongodb的权限。
1:user用户登录
在user用户目录下 加入环境变量,指向mongo安装的文件夹:
vi ~/.bashrc 进入当前用户下面的.bashrc文件
拷贝以下设置保存即可
export MONGOHOME=/root/mongodb/mongodb-linux-x86_64-3.0.1
export PATH=$MONGOHOME/bin:$PATH
2:mongodb的安装目录(root目录)访问权限
给mongodb的安装目录 :root目录设置访问权限(需要在root管理员用户下设置) 在root当存目录
cd /root
chmod 777 root (读写执行权限都有了)
chmod -R 777 root(文件的读写,创建文件夹等)
chmod a+x root 执行权限
设置完这两部,在user账号下,就能启动mongodb了。
如果在启动mongodb时报以下连接不上的mask错误,试试以下命令:
systemctl unmask mongodb
systemctl enable mongodb
systemctl start mongodb
3:在user用户下,判断开机启动项下面的mongodb文件是否有执行权限
cd /etc/init.d/ 进入这个启动项目录
ls -al mongodb 查看mongodb启动文件的权限 (./mongo) 按tab键不全 则是没有执行权限
chmod a+x mongodb 给mongodb文件赋予执行权限 (需要在管理员权限下设置)
systemctl enable mongodb 对mongodb文件设置可用
systemctl start mongodb.service 启动服务
4: 其他可能涉及的命令:
如果系统开放了防火墙,还需要开放防火墙的端口,可以使得3台机器相互之间能访问,不会被墙掉。
列出INPUT 链所有的规则
iptables -L INPUT --line-numbers
#当然,自己不能被挡在外面,给自己开个后门
iptables -I INPUT -s 127.0.0.1 -p tcp --dport 27017 -j ACCEPT(出于业务逻辑的需要,有时还需要对服务器的公网IP授权)
iptables -I INPUT -s 172.16.9.241 -p tcp --dport 27017 -j ACCEPT
iptables -I INPUT -s 172.16.9.240 -p tcp --dport 27017 -j ACCEPT
iptables -I INPUT -s 172.16.9.85 -p tcp --dport 27017 -j ACCEPT
列出所有的服务,查看所有服务
systemctl list-units --type=service
df -h 查看磁盘空间
手动从配置文件启动服务 :mongod -config ./mongodb-3.2.18/mongodb.conf(配置文件路径)
三:设置副本集
在3个虚拟机上启动mongo服务都没有问题时,开始配置副本集。
随便选择某一台服务器做副本集初始化配置即可。
输入mongo命令,启动mongo
config={
_id:"testrepl",
members:[
{_id:,host:"172.16.9.241:27017"},
{_id:,host:"172.16.9.240:27017"},
{_id:,host:"172.16.9.84:27017"}]
} rs.initiate(config) ##########################
"_id": 副本集的名称
"members": 副本集的服务器列表
"_id": 服务器的唯一ID
"host": 服务器主机
"priority": 是优先级,默认为1,优先级0为被动节点,不能成为活跃节点。优先级不位0则按照有大到小选出活跃节点。
"arbiterOnly": 仲裁节点,只参与投票,不接收数据,也不能成为活跃节点。
第一次初始化时报以下错误:
replSetInitiate quorum check failed because not all proposed set members responded affirmatively: 172.16.9.85:27017 failed with Failed attempt to connect to 172.16.9.85:27017; couldn't connect to server 172.16.9.85:27017 (172.16.9.85), connection attempt failed code:74
经查证发现root磁盘空间小了,副本集至少要求好几G空间,以用来交互数据使用。重新分配虚拟机空间后解决问题。
若初始化成功,会返回以下代码:
{
"ok" : 1
}
查看副本集状态: rs.status() 命令
注意事项:
1.只需要选择其中某一节点做初始化配置
2. 在副本集初始化的时候,一般都是copy不同的数据至各个结点,之后启动结点,添加至集群,之后查询状态会发现是 STARTUP2,这是因为集群初始化在同步数据,同步完数据之后,状态就变正常了
3. 在副本节点读取数据报错:
Error: error: { "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435 }
因为241为主副本集,mongodb默认是从主节点读写数据的,而副本节点上不允许读数据,因此在从服务器上需要做以下设置,需要设置副本节点可以读。
repset:SECONDARY>db.getMongo().setSlaveOk(); 执行这句让副本集可以读
其实:有两种方法实现从机的查询:
第一种方法:db.getMongo().setSlaveOk();
第二种方法:rs.slaveOk();
上面两行命令即允许此连接从副本读取.
但是这种方式有一个缺点就是,下次再通过mongo进入实例的时候,查询仍然会报错,为此可以通过下列方式
vi ~/.mongorc.js
增加一行rs.slaveOk();
以后每次通过mongo命令进入都可以查询了。
可以测试当主节点挂掉,副本节点就会选举一个新的主服务器
当再次启动241服务器的mongo时,会恢复其primary身份。
到这里,副本集就已经配置完成。
对于切换日志的操作,
>use admin
> db.runCommand({logRotate:1})