mongodb主从配置

复制概述

复制就是在多台服务器上分布并管理数据库服务器。MongoDB提供了两种复制风格:主从复制和副本集。两种方式都是在一个主节点进行写操作(写入的数据被异步地同步到所有的从节点上),并从节点上读取数据。

所有数据库都对其运行环境中的故障很敏感,而复制提供了一种抵御故障的机制。

主从配置

配置主从复制注意点

  1. 在数据库集群中要明确的知道谁是主服务器,主服务器只有一台;
  2. 从服务器要知道自己的数据源也就是对应的主服务器是谁;
  3. master用来确定主服务器,slave和source来控制从服务器。

机器环境

192.168.160.145 master node
192.168.160.146 slave node

主节点配置

master.conf

#data file directory
dbpath=/home/soft/mongodb/data
# log file directory
logpath=/home/soft/mongodb/logs/mongodb.log
#port
port=26016
#daemon process
fork=true
#log type of output
logappend=true
#pid file
pidfilepath=/home/soft/mongodb/bin/mongo.pid

软链接使命令全局可用

ln -s /home/soft/mongodb/bin/mongod /usr/bin/mongod
ln -s /home/soft/mongodb/bin/mongo /usr/bin/mongo

启动mongodb master

mongod -f master.conf

启动报错

about to fork child process, waiting until server is ready for connections.
forked process: 31619
ERROR: child process failed, exited with error number 1

怀疑是配置文件中数据和日志目录未创建

mkdir /home/soft/mongodb/data
mkdir /home/soft/mongodb/logs
touch /home/soft/mongodb/logs/mongodb.log

创建目录后,再次执行启动命令,启动结果如下:

about to fork child process, waiting until server is ready for connections.
forked process: 31678
child process started successfully, parent exiting

说明启动成功

启动mongo并创建用户

mongo --port=26016

use admin;
db.createUser({user: 'root', pwd:'root', roles:[{role: '__system', db: 'admin'}]});

结果:

Successfully added user: {
    "user" : "root",
    "roles" : [
        {
            "role" : "__system",
            "db" : "admin"
        }
    ]
}

查看新建用户:

show users;

结果:

{
    "_id" : "admin.root",
    "user" : "root",
    "db" : "admin",
    "roles" : [
        {
            "role" : "__system",
            "db" : "admin"
        }
    ]
}

或使用db.system.users.find()查看用户。

slave节点配置步骤同上。

认证配置

生成密钥文件mongo_key

openssl rand -base64 1024 >> mongo_key

chmod 700 mongo_key

修改master.conf并重新启动

#data file directory
dbpath=/home/soft/mongodb/data
# log file directory
logpath=/home/soft/mongodb/logs/mongodb.log
#port
port=26016
#daemon process
fork=true
#log type of output
logappend=true
#pid file
pidfilepath=/home/soft/mongodb/mongodb/bin/mongo.pid
journal=true
# authentication
auth=true
#key file
keyFile=/home/soft/mongodb/mongodb/mongo_key
#master node
master=true
#set oplog size(MB)
oplogSize=1024

关掉mongodb进程时不要使用kill -9 pid,这种方式杀掉进程会导致错误,即使mongod --repair也无法恢复。应使用killall mongod关闭mongodb进程。

启动过程报错

Unable to lock file mongod.lock

2018-11-08T22:46:54.594-0800 I STORAGE  [initandlisten] exception in initAndListen: 98 Unable to lock file: /home/soft/mongodb/data/mongod.lock Resource temporarily unavailable. Is a mongod instance already running?, terminating
2018-11-08T22:46:54.594-0800 I NETWORK  [initandlisten] shutdown: going to close listening sockets...
2018-11-08T22:46:54.594-0800 I NETWORK  [initandlisten] shutdown: going to flush diaglog...
2018-11-08T22:46:54.594-0800 I CONTROL  [initandlisten] now exiting
2018-11-08T22:46:54.594-0800 I CONTROL  [initandlisten] shutting down with code:100

解决方法:

删除data目录下的mongod.lock

addr already in use

2018-11-08T22:53:30.757-0800 E NETWORK  [initandlisten] listen(): bind() failed Address already in use for socket: 0.0.0.0:26016
2018-11-08T22:53:30.757-0800 E NETWORK  [initandlisten]   addr already in use

解决方法

杀掉mongodb进程,重新启动

若执行上述方法仍报错,可查询占用端口的进程,杀掉即可。

lsof -i:26016

占用端口的进程如下:

COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mongod  31678 root    7u  IPv4  62742      0t0  TCP *:26016 (LISTEN)

杀掉进程:

kill -9 31678

再次启动,无错误。

修改slave.conf并重新启动

#data file directory
dbpath=/home/soft/mongodb/data
# log file directory
logpath=/home/soft/mongodb/logs/mongodb.log
#port
port=26016
#daemon process
fork=true
#log type of output
logappend=true
#pid file
pidfilepath=/home/soft/mongodb/bin/mongo.pid
# authentication
auth=true
#key file
keyFile=/home/soft/mongodb/mongo_key
#slave node
slave=true
#replication source
source=192.168.160.145:26016
#add global lock when slave have much to replicate
autoresync=true
oplogSize=1024

需配置source指定复制源,slave=true设置为从节点

查看数据库时出错 not master and slaveOk=false

2018-11-08T23:12:26.598-0800 E QUERY    [thread1] Error: listDatabases failed:{
    "ok" : 0,
    "errmsg" : "not master and slaveOk=false",
    "code" : 13435,
    "codeName" : "NotMasterNoSlaveOk"
}

输入如下命令,重新执行即可:

rs.slaveOk();

测试

在主节点新建数据库,从节点查看是否复制

> show dbs;
admin       0.000GB
datavisual  0.197GB
local       0.000GB

多了datavisual,数据库复制成功.

admin和local中数据不会被复制。

查看日志有如下输出,说明一直在请求主节点进行数据复制。

2018-11-08T23:07:17.297-0800 I REPL     [replslave] syncing from host:192.168.160.145:26016
2018-11-08T23:07:18.299-0800 I REPL     [replslave] syncing from host:192.168.160.145:26016
2018-11-08T23:07:19.302-0800 I REPL     [replslave] syncing from host:192.168.160.145:26016
2018-11-08T23:07:20.303-0800 I REPL     [replslave] syncing from host:192.168.160.145:26016
2018-11-08T23:07:22.292-0800 I REPL     [replslave] syncing from host:192.168.160.145:26016
2018-11-08T23:07:23.295-0800 I REPL     [replslave] syncing from host:192.168.160.145:26016

日志文件一直在写入。

主从架构面临的问题

a. 如果读写都是对主节点的操作,会导致主节点压力过大;
b. 如果主节点挂掉,架构失效;
c. 如果多个从节点从主节点复制数据,主节点压力过大。

主从复制,主节点挂掉后从节点不会自动提升为主节点,需手动配置;可设置从节点读取数据,减轻主节点压力。

其他

关于oplog

oplog是MongoDB复制的关键。oplog是一个固定集合,位于每个复制节点的local数据库里,记录了所有对数据的变更。每次客户端向主节点写入数据,就会自动向主节点的oplog里添加一个条目,其中包含了足够的信息来再现数据。一旦写操作被复制到某个从节点上,从节点的oplog也会保存一条关于写入的记录。每个oplog条目都由一个BSON时间戳进行标识,所有从节点都使用这个时间戳来追踪它们最后应用的条目。

调整复制OPLOG大小

因为oplog是一个固定集合,所以一旦创建就无法重新设置大小,为此要慎重选择初始oplog大小。

默认的oplog大小会随着环境发生变化。在32位系统上,oplog默认是50MB,而在64位系统上,oplog会增大到1GB或空余磁盘空间的5%。对于多数部署环境,空余磁盘空间的5%绰绰有余。对于这种尺寸的oplog,要意识到一旦重写20次,磁盘可能就满了。

因此默认大小并非适用于所有应用程序。如果知道应用程序写入量会很大,在部署之前应该做些测试。配置好复制,然后以生产环境的写入量向主节点发起写操作,像这样对服务器施压起码一小时。完成之后,连接到任意副本集成员上,获取当前复制信息:

db.getReplicationInfo();

一旦了解了每小时会生成多少oplog,就能决定分配多少oplog空间了。你应该为从节点下线八小时做好准备。发生网络故障或类似事件时,要避免任意节点重新同步完整数据,增加oplog大小能为你争取更多事件。

如果要改变默认oplog大小,必须在每个成员节点首次启动时使用mongod的--oplogSize选项,其值的单位是兆。

读扩展

经复制的数据库能很好地适用于读扩展。如果单台服务器无法承担应用程序的读负载,那么可以将查询路由到更多的副本上。大多数驱动都内置了将查询发送到从节点的功能。

你可能感兴趣的:(mongodb主从配置)