MongoDB学习札记第六篇之主从复制

mongo系列文章请看http://www.codefrom.com/p/mongodb


环境准备:

ubuntu12.0.4
mongodb3.0.3

主从复制是MongoDB中最常见的复制方式。这种方式非常灵活,可用于备份,故障恢复,读扩展 等。
本次试验中,我们采用一个主节点,一个从节点。
首先先创建master和slave的目录

lwb@ubuntu:~$ mkdir -p ~/mongoData/master
lwb@ubuntu:~$ mkdir -p ~/mongoData/slave

创建之后,启动master

lwb@ubuntu:~$ mongod --master --dbpath ~/mongoData/master/ --port 10000

然后再启动slave

lwb@ubuntu:~$ mongod --dbpath  ~/mongoData/slave/ --port 10001 --slave --source localhost:10000

接着,连接到master的机器,

lwb@ubuntu:~$ mongo --host localhost --port 10000

往test数据库的users集合里面插入两条数据:

> db.users.find()
{ "_id" : ObjectId("55763d98db85929bb8addedf"), "username" : "lwb" }
{ "_id" : ObjectId("55764a694b24187a7a3c6693"), "username" : "mongodb master-slave" }

在master操作完成之后,在连接slave的mongod

lwb@ubuntu:~$ mongo --host localhost --port 10001
MongoDB shell version: 3.0.3
connecting to: localhost:10001/test
Server has startup warnings:
2015-06-08T19:02:31.866-0700 I CONTROL  [initandlisten]
2015-06-08T19:02:31.866-0700 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/   mm/transparent_hugepage/defrag is 'always'.
2015-06-08T19:02:31.866-0700 I CONTROL  [initandlisten] **        We suggest set   ting it to 'never'
2015-06-08T19:02:31.866-0700 I CONTROL  [initandlisten]
>
> show dbs
2015-06-08T19:09:17.770-0700 E QUERY    Error: listDatabases failed:{ "note" : "   from execCommand", "ok" : 0, "errmsg" : "not master" }
    at Error (<anonymous>)
    at Mongo.getDBs (src/mongo/shell/mongo.js:47:15)
    at shellHelper.show (src/mongo/shell/utils.js:630:33)
    at shellHelper (src/mongo/shell/utils.js:524:36)
    at (shellhelp2):1:1 at src/mongo/shell/mongo.js:47
>
> rs.slaveOk()
> 
> show dbs
local  0.078GB
test   0.078GB
>
> use test
switched to db test
> show collections
system.indexes
users
>
> db.users.find()
{ "_id" : ObjectId("55763d98db85929bb8addedf"), "username" : "lwb" }
{ "_id" : ObjectId("55764a694b24187a7a3c6693"), "username" : "mongodb master-slave" }

我遇到的问题及解决方法
问题一:

我的主从复制实验分为两次进行,刚开始我配置的master的端口是 10000 ,salve的端口是10001 ; 后因为电脑内存使用率暴涨,90+% 。 所以关掉电脑重启。问题就出现在这里,重启之后,我指定master端口的时候指定为 27000 , 指定slave端口为 27001 所以就出现了如下问题:terminating mongod after 30 seconds

2015-06-08T18:11:37.981-0700 I NETWORK  [initandlisten] waiting for connections on port 27001
2015-06-08T18:11:38.975-0700 I REPL     [replslave] repl: --source localhost:27000 != localhost:10000 from local.sources collection
2015-06-08T18:11:38.976-0700 I REPL     [replslave] repl: for instructions on changing this slave's source, see: 2015-06-08T18:11:38.976-0700 I REPL     [replslave] http://dochub.mongodb.org/co re/masterslave
2015-06-08T18:11:38.976-0700 I REPL     [replslave] repl: terminating mongod after 30 seconds
2015-06-08T18:12:08.976-0700 I CONTROL  [replslave] dbexit:  rc: 3

解决方法:
如果仔细观察日志的同学应该会发现:

2015-06-08T18:11:38.975-0700 I REPL     [replslave] repl: --source localhost:27000 != localhost:10000 from local.sources collection

所以,在一开始的时候我们已经为slave指定了master的host和port,这个会插入到local.sources 这个集合的。所以,把master端口改成10000就可以了。

问题二

主从启动之后,连接slave可以成功连上,但是在slave中执行 show dbs 的时候就报错了:

QUERY    Error: listDatabases failed:{ "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" }

解决方法:

在报错的slave机器上执行 rs.slaveOk()方法即可。

> rs.slaveOk()
> show dbs
local  0.078GB
test   0.078GB
> use test
switched to db test
> show collections
system.indexes
users
> db.users.find()
{ "_id" : ObjectId("55763d98db85929bb8addedf"), "username" : "lwb" }
{ "_id" : ObjectId("55764a694b24187a7a3c6693"), "username" : "mongodb master-sla

具体slaveOk方法是什么意思?
rs.slaveOk()

Provides a shorthand for the following operation:

db.getMongo().setSlaveOk()
This allows the current connection to allow read operations to run on secondary members. See the readPref() method for more fine-grained control over read preference in the mongo shell.

Master-Slave安全
这个主从安全在 MongoDB官网说的很清楚。不能和普通的mongod权限验证那样。这里除了需要加入 —auth 还需要加入 —keyFile 的验证。

首先,我们生成我们的keyFile,根据官网提供的说明,这个keyfile是可以任意内容的,只要保证所有集群中的机器都拥有同样的文件即可。在linux环境下,我们通过

openssl rand -base64 741 > /usr/localhsot/mongodb/mongo-keyfile

这条命令来生成我们的keyFile。 生成之后就可以在启动mongod的时候指定了。

首先先启动 master

root@ubuntu:/usr/local/mongodb# mongod --master --dbpath ~/mongoData/master/ --port 10000 --auth --keyFile /usr/local/mongodb/mongo-keyfile

这里在启动的时候可能会遇到一些问题,我是在ubuntu环境下,所以经常操作要sudo,很繁琐。因此,让当前用户获得root权限是很有必要的。

在命令行模式执行 vi etc/passwd
我的用户名是 lwb ,所以将lwb所在的行改成
lwb:x:0:0:Ubuntu12.04,,,:/home/lwb:/bin/bash
原来的值是(将1000 改成 0 即可): lwb:x:1000:1000:Ubuntu12.04,,,:/home/lwb:/bin/bash
修改完成之后重启登录就可以让当前用户获得root权限了。

回到正题,在生成mongo-keyfile后,并指定keyFile参数来启动mongod的时候,可能还会遇到另一个问题:

root@ubuntu:~# mongod --master --dbpath ~/mongoData/master/ --port 10000 --auth --keyFile /usr/local/mongodb/mongo-keyfile
2015-06-08T21:34:43.864-0700 I ACCESS   permissions on /usr/local/mongodb/mongo-keyfile are too open

这个错误的意思是说 mongo-keyfile权限太大了,降低一下这个文件的权限。

root@ubuntu:/usr/local/mongodb# chmod 400 mongo-keyfile
root@ubuntu:/usr/local/mongodb# ll
total 84
drwxr-xr-x  4 root root  4096 Jun  8 21:34 ./
drwxr-xr-x 11 root root  4096 Jun  8 16:49 ../
-rw-r--r--  1 root root 34520 Jun  6 07:24 GNU-AGPL-3.0
-rw-r--r--  1 root root  1359 Jun  6 07:24 README
-rw-r--r--  1 root root 22660 Jun  6 07:24 THIRD-PARTY-NOTICES
drwxr-xr-x  2 root root  4096 Jun  6 07:24 bin/
drwxr-xr-x  3 root root  4096 Jun  7 13:02 data/
-r--------  1 root root  1004 Jun  8 21:34 mongo-keyfile

重启一下mongod即可正常运行。

接着启动slave

mongod --slave --dbpath ~/mongoData/slave/ --port 10001 --source localhost:10000 --auth --keyFile /usr/local/mongodb/mongo-keyfile

一切都顺利的进行着。
使用创建的用户操作master里面的数据库以及集合都是正常的。但是使用同样的用户操作slave的时候就有不正常了。还是提示

QUERY    Error: listDatabases failed:{ "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" }

这个错误上面已经提到了。解决方法也是一样的。 rs.slaveOk() 执行完这条语句之后既可以正常操作了。

可以发现,用keyFile的方式启动mongod服务器其实和平常启动没什么区别,唯一的区别就是在启动参数中指定了 --keyFile keyfile 而已。

具体怎么创建用户参考: MongoDB学习札记第二篇之mongodb安全

Sincerely!
参考

MongoDB权威指南

MongoDB官网Manual手册


码源-专注开源技术分享
码源-专注开源技术分享:[链接]
1.3k 声望
48 粉丝
0 条评论
推荐阅读
xCodeGhost 事件专题总结
最近闹的沸沸扬扬的xCodeGhost事件,一开始是由阿里的蒸米、讯迪在乌云发布了深度的病毒解析,随后腾讯安全研究员也跟进分析。由于此病毒感染了包括网易云音乐、滴滴出行等一批用户量很大的手机APP,在知乎也引起...

已注销1阅读 3.2k评论 1

Mongodb-关联表查询
之前使用SQL语法来查询oracle、sqlserver、mysql表之间的关联,但是到mongodb之后完全无从下手,写法完全不一样,于是到网上查询mongodb关联表查询的写法,于是参考代码自己试着写了下,但是发现有好多问题,比如...

Awbeci2阅读 4.6k评论 1

MongoDB安装、启动、关闭、授权
安装参考[链接]配置文件 {代码...} 启动MongoDB {代码...} MongoDB的关闭方式kill进程模式(不建议使用) {代码...} 自带模式 {代码...} 注意: mongod进程收到SIGINT或SIGTERM信号,会做一些处理 切忌使用kill -9...

YYGP阅读 1.3k

mongoShake基于go实践应用
通过阿里云自研的MongoShake开源工具,您可以实现MongoDB数据库间的数据同步,该功能可用于数据分析、灾备和多活等业务场景。本文以云数据库MongoDB实例间的数据实时同步为例介绍配置流程。

金闽阅读 1k

如何正确地使用 Docker 在云服务器上部署 MongoDB v6 数据库并连接
使用 Docker 部署 MongoDB 时,容器默认不会自动生成 mongod.conf 配置文件,需要开发者手动映射云服务器上的配置文件至容器内部,因此,我们需要先创建一份配置文件,您可以任意选择该文件的存储目录,这里我们...

libinfs阅读 712

封面图
MongoDB的索引事物和高可用分析
collection集合,相当于SQL中的表(table),一个集合可以存放多个文档(行)。不同之处就在于集合的结构(schema)是动态的,不需要预先声明一个严格的表结构。更重要的是,默认情况下 MongoDB并不会对写入的数据做任...

djjk阅读 562

如何使用码匠连接 MongoDB
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。MongoDB 最...

码匠Majiang阅读 507

封面图
1.3k 声望
48 粉丝
宣传栏