Replica Set

## 参考:http://blog.csdn.net/luonanqin/article/details/8497860 ,https://www.cnblogs.com/zhoujinyi/p/3554010.html
## 不同版本 mongodb 下载地址https://www.mongodb.org/dl/linux/x86_64

下面实验使用的是ubuntu1404-3.5.13 版本
在ubuntu1404上安装
Replica Set

   中文翻译叫做副本集,不过我并不喜欢把英文翻译成中文,总是感觉怪怪的。其实简单来说就是集群当中包含了多份数据,保证主节点挂掉了,备节点能继续提供数据服务,提供的前提就是数据需要和主节点一致

    Mongodb(M)表示主节点,Mongodb(S)表示备节点,Mongodb(A)表示仲裁节点。主备节点存储数据,仲裁节点不存储数据。客户端同时连接主节点与备节点,不连接仲裁节点。

   默认设置下,主节点提供所有增删查改服务,备节点不提供任何服务。但是可以通过设置使备节点提供查询服务,这样就可以减少主节点的压力,当客户端进行数据查询时,请求自动转到备节点上。这个设置叫做Read Preference Modes,同时Java客户端提供了简单的配置方式,可以不必直接对数据库进行操作。

   仲裁节点是一种特殊的节点,它本身并不存储数据,主要的作用是决定哪一个备节点在主节点挂掉之后提升为主节点,所以客户端不需要连接此节点。这里虽然只有一个备节点,但是仍然需要一个仲裁节点来提升备节点级别。我开始也不相信必须要有仲裁节点,但是自己也试过没仲裁节点的话,主节点挂了备节点还是备节点,所以咱们还是需要它的。

介绍完了集群方案,那么现在就开始搭建了。

集群节点:

master:172.31.14.255
slave:  172.31.15.180
arbiter:172.31.2.34

master 安装

mkdir -p /work/{source,opt}
cd /work/source
wget http://downloads.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1404-latest.tgz
tar xf mongodb-linux-x86_64-ubuntu1404-3.5.13.tgz
mv mongodb-linux-x86_64-ubuntu1404-3.5.13 ../opt/
cd ../opt/
ln -s mongodb-linux-x86_64-ubuntu1404-3.5.13/ mongodb
export PATH=$PATH:/work/opt/mongodb/bin
echo ###mongodb >> /etc/profile
echo export PATH=$PATH:/work/opt/mongodb/bin >> /etc/profile

mkdir -p /work/opt/mongodb/conf
cd /work/opt/mongodb/conf
cat >>/work/opt/mongodb/conf/mongodb.conf <<EOF
dbpath=/data/mongodb/master  
logpath=/data/logs/mongodb/master.log  
pidfilepath=/data/logs/mongodb/master.pid  
directoryperdb=true  
logappend=true  
replSet=rela-mongodb 
bind_ip=172.31.14.255
port=27017  
oplogSize=10000  
#fork=true  
noprealloc=true
EOF

使用supervisor管理mongodb

apt-get install supervisor -y 
supervisord

cd /etc/supervisor/conf.d
cat >> /etc/supervisor/conf.d/sup_mongodb.conf <<EOF
[program:mongodb]
command=/work/opt/mongodb/bin/mongod -f /work/opt/mongodb/conf/mongodb.conf
;process_name=%(process_num)02d
numprocs=1
#user=rela
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/data/logs/mongodb/sup_mongodb.log
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=5
EOF

mkdir -p /data/logs/mongodb/ /data/logs/mongodb/ /data/mongodb/master
supervisorctl update
supervisorctl status 
netstat -lntup |grep mon

slave 安装

mkdir -p /work/{source,opt}
cd /work/source
wget http://downloads.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1404-latest.tgz
tar xf mongodb-linux-x86_64-ubuntu1404-3.5.13.tgz
mv mongodb-linux-x86_64-ubuntu1404-3.5.13 ../opt/
cd ../opt/
ln -s mongodb-linux-x86_64-ubuntu1404-3.5.13/ mongodb
export PATH=$PATH:/work/opt/mongodb/bin
echo ###mongodb >> /etc/profile
echo export PATH=$PATH:/work/opt/mongodb/bin >> /etc/profile

mkdir -p /work/opt/mongodb/conf
cd /work/opt/mongodb/conf
cat >>/work/opt/mongodb/conf/mongodb.conf <<EOF
dbpath=/data/mongodb/slave
logpath=/data/logs/mongodb/slave.log  
pidfilepath=/data/logs/mongodb/slave.pid  
directoryperdb=true  
logappend=true  
replSet=rela-mongodb 
bind_ip=172.31.15.180
port=27017  
oplogSize=10000  
#fork=true  
noprealloc=true
EOF

使用supervisor管理mongodb

apt-get install supervisor -y 
supervisord

cd /etc/supervisor/conf.d
cat >> /etc/supervisor/conf.d/sup_mongodb.conf <<EOF
[program:mongodb]
command=/work/opt/mongodb/bin/mongod -f /work/opt/mongodb/conf/mongodb.conf
;process_name=%(process_num)02d
numprocs=1
#user=rela
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/data/logs/mongodb/sup_mongodb.log
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=5
EOF

mkdir -p /data/logs/mongodb/ /data/logs/mongodb/ /data/mongodb/slave
supervisorctl update
supervisorctl status 
netstat -lntup |grep mon

arbiter 安装

mkdir -p /work/{source,opt}
cd /work/source
wget http://downloads.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1404-latest.tgz
tar xf mongodb-linux-x86_64-ubuntu1404-3.5.13.tgz
mv mongodb-linux-x86_64-ubuntu1404-3.5.13 ../opt/
cd ../opt/
ln -s mongodb-linux-x86_64-ubuntu1404-3.5.13/ mongodb
export PATH=$PATH:/work/opt/mongodb/bin
echo ###mongodb >> /etc/profile
echo export PATH=$PATH:/work/opt/mongodb/bin >> /etc/profile

mkdir -p /work/opt/mongodb/conf
cd /work/opt/mongodb/conf
cat >>/work/opt/mongodb/conf/mongodb.conf << EOF
dbpath=/data/mongodb/arbiter
logpath=/data/logs/mongodb/arbiter.log  
pidfilepath=/data/logs/mongodb/arbiter.pid  
directoryperdb=true  
logappend=true  
replSet=rela-mongodb 
bind_ip=172.31.2.34
port=27017  
oplogSize=10000  
#fork=true  
noprealloc=true
EOF

使用supervisor管理mongodb

apt-get install supervisor -y 
supervisord

cd /etc/supervisor/conf.d
cat >> /etc/supervisor/conf.d/sup_mongodb.conf <<EOF
[program:mongodb]
command=/work/opt/mongodb/bin/mongod -f /work/opt/mongodb/conf/mongodb.conf
;process_name=%(process_num)02d
numprocs=1
#user=rela
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/data/logs/mongodb/sup_mongodb.log
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=5
EOF

mkdir -p /data/logs/mongodb/ /data/logs/mongodb/ /data/mongodb/arbiter
supervisorctl update
supervisorctl status 
netstat -lntup |grep mon

参数解释:

dbpath:数据存放目录

logpath:日志存放路径

pidfilepath:进程文件,方便停止mongodb

directoryperdb:为每一个数据库按照数据库名建立文件夹存放

logappend:以追加的方式记录日志

replSet:replica set的名字

bind_ip:mongodb所绑定的ip地址

port:mongodb进程所使用的端口号,默认为27017

oplogSize:mongodb操作日志文件的最大大小。单位为Mb,默认为硬盘剩余空间的5%

fork:以后台方式运行进程

noprealloc:不预先分配存储

4.配置主,备,仲裁节点

可以通过客户端连接mongodb,也可以直接在主或被两个节点中选择一个连接mongodb。

mongo 172.31.14.255:27017   #ip和port是某个节点的地址  
>use admin  
>cfg={ _id:"rela-mongodb", members:[ {_id:0,host:'172.31.14.255:27017',priority:2}, {_id:1,host:'172.31.15.180:27017',priority:1},{_id:2,host:'172.31.7.138:27017',arbiterOnly:true}] };  
>rs.initiate(cfg)               #使配置生效  

cfg是可以任意的名字,当然最好不要是mongodb的关键字,conf,config都可以。最外层的_id表示replica set的名字,members里包含的是所有节点的地址以及优先级。优先级最高的即成为主节点,即这里的10.10.148.130:27017。特别注意的是,对于仲裁节点,需要有个特别的配置——arbiterOnly:true。这个千万不能少了,不然主备模式就不能生效。

配置的生效时间根据不同的机器配置会有长有短,配置不错的话基本上十几秒内就能生效,有的配置需要一两分钟。如果生效了,执行rs.status()命令会看到如下信息:

rela-mongodb:SECONDARY> rs.status()     ## 生效会看到下面内容
{
    "set" : "rela-mongodb",
    "date" : ISODate("2017-11-27T07:02:48.848Z"),
    "myState" : 7,
    "term" : NumberLong(2),
    "heartbeatIntervalMillis" : NumberLong(2000),
    "optimes" : {
        "lastCommittedOpTime" : {
            "ts" : Timestamp(1511766165, 1),
            "t" : NumberLong(2)
        },
        "appliedOpTime" : {
            "ts" : Timestamp(1511766165, 1),
            "t" : NumberLong(2)
        },
        "durableOpTime" : {
            "ts" : Timestamp(0, 0),
            "t" : NumberLong(-1)
        }
    },
    "members" : [
        {
            "_id" : 0,
            "name" : "172.31.14.255:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 126,
            "optime" : {
                "ts" : Timestamp(1511766165, 1),
                "t" : NumberLong(2)
            },
            "optimeDurable" : {
                "ts" : Timestamp(1511766165, 1),
                "t" : NumberLong(2)
            },
            "optimeDate" : ISODate("2017-11-27T07:02:45Z"),
            "optimeDurableDate" : ISODate("2017-11-27T07:02:45Z"),
            "lastHeartbeat" : ISODate("2017-11-27T07:02:47.639Z"),
            "lastHeartbeatRecv" : ISODate("2017-11-27T07:02:47.803Z"),
            "pingMs" : NumberLong(0),
            "electionTime" : Timestamp(1511766063, 1),
            "electionDate" : ISODate("2017-11-27T07:01:03Z"),
            "configVersion" : 1
        },
        {
            "_id" : 1,
            "name" : "172.31.15.180:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 126,
            "optime" : {
                "ts" : Timestamp(1511766165, 1),
                "t" : NumberLong(2)
            },
            "optimeDurable" : {
                "ts" : Timestamp(1511766165, 1),
                "t" : NumberLong(2)
            },
            "optimeDate" : ISODate("2017-11-27T07:02:45Z"),
            "optimeDurableDate" : ISODate("2017-11-27T07:02:45Z"),
            "lastHeartbeat" : ISODate("2017-11-27T07:02:47.639Z"),
            "lastHeartbeatRecv" : ISODate("2017-11-27T07:02:48.793Z"),
            "pingMs" : NumberLong(0),
            "syncingTo" : "172.31.14.255:27017",
            "configVersion" : 1
        },
        {
            "_id" : 2,
            "name" : "172.31.2.34:27017",
            "health" : 1,
            "state" : 7,
            "stateStr" : "ARBITER",
            "uptime" : 745,
            "configVersion" : 1,
            "self" : true
        }
    ],
    "ok" : 1
}
rela-mongodb:ARBITER> 

其他相关操作:

  1. 设置slave可读
    mmm:SECONDARY> db.test.find()
    error: { "$err" : "not master and slaveOk=false", "code" : 13435 }
    mmm:SECONDARY> rs.slaveOk()
    mmm:SECONDARY> db.test.find()
    { "_id" : ObjectId("5302edfa8c9151a5013b978e"), "a" : 1 }
  2. 增删节点。
    把25服务加入到副本集中:
    rs.add("172.31.200.25:27017")
  3. 把25服务从副本集中删除:
    rs.remove("172.31.200.25:27017")
  4. 查看复制的情况
    db.printSlaveReplicationInfo()
  5. 查看副本集的状态
    rs.status()
  6. 副本集的配置
    rs.conf()/rs.config()
  7. 当前节点情况

    db.isMaster() 
  8. 添加Arbiter
    连接Primary.

    rs.addArb(“192.168.1.50:10001″)
    rs.addArb(“192.168.1.50:10002″)
    rs.addArb(“192.168.1.50:10003″)

    权限管理

    参考http://blog.csdn.net/kk185800961/article/details/45619863
    mongodb 权限管理

  9. 创建管理员账号

    db.createUser(
    {
     user:"myadmin",
     pwd:"secret",
     roles:[{role:"root",db:"admin"}]
    }
    );

    重启mongodb db,并且在配置文件中加入启用认证功能

    /work/opt/mongodb/bin/mongod -f /work/opt/mongodb/conf/mongodb.conf

    在配置文件 /work/opt/mongodb/conf/mongodb.conf中加入auth=true 参数,重启mongodb

    dbpath=/data/mongodb/arbiter
    logpath=/data/logs/mongodb/arbiter.log  
    pidfilepath=/data/logs/mongodb/arbiter.pid  
    directoryperdb=true  
    logappend=true  
    replSet=rela-mongodb 
    bind_ip=172.31.7.138
    port=27017  
    oplogSize=10000  
    #fork=true  
    noprealloc=true
  10. mongo 常用命令

[root@snails ~]# mongo --host=127.0.0.1 --port=27017
MongoDB shell version: 3.2.7
connecting to: 127.0.0.1:27017/test
> show dbs  #显示数据库列表 
> show collections  #显示当前数据库中的集合(类似关系数据库中的表)
> show users  #显示用户
> use <db name>  #切换当前数据库,如果数据库不存在则创建数据库。 
> db.help()  #显示数据库操作命令,里面有很多的命令 
> db.foo.help()  #显示集合操作命令,同样有很多的命令,foo指的是当前数据库下,一个叫foo的集合,并非真正意义上的命令 
> db.foo.find()  #对于当前数据库中的foo集合进行数据查找(由于没有条件,会列出所有数据) 
> db.foo.find( { a : 1 } )  #对于当前数据库中的foo集合进行查找,条件是数据中有一个属性叫a,且a的值为1

> db.dropDatabase()  #删除当前使用数据库
> db.cloneDatabase("127.0.0.1")   #将指定机器上的数据库的数据克隆到当前数据库
> db.copyDatabase("mydb", "temp", "127.0.0.1")  #将本机的mydb的数据复制到temp数据库中
> db.repairDatabase()  #修复当前数据库
> db.getName()  #查看当前使用的数据库,也可以直接用db
> db.stats()  #显示当前db状态
> db.version()  #当前db版本
> db.getMongo()  #查看当前db的链接机器地址
> db.serverStatus()  #查看数据库服务器的状态
  1. 修改用户密码
db.changeUserPassword('myadmin','8e8f5a4a21438');

4.添加普通库读用户
1.登录到mongo数据库后,切换到admin库,使用管理员账号进行认证,之后切换到目标数据库中,进行创建用户。

use datadb ;
db.createUser(  
  {  
    user: "datadbread",  
    pwd: "8e8f5a4a21438",  
    roles: [ { role: "read", db: "datadb" } ]  
  }  
)  ;

5.添加普通库读写用户
1.登录到mongo数据库后,切换到admin库,使用管理员账号进行认证,之后切换到目标数据库中,进行创建用户。

use datadb ;
db.createUser(  
  {  
    user: "datadb",  
    pwd: "8e8f5a4a21438",  
    roles: [ { role: "readWrite", db: "datadb" } ]  
  }  
)   ;

5.重新授权,已经以及登录


db.grantRolesToUser(  "datadb",  [    { role: "readWrite,dbAdmin",db:"datadb"}  ] )
db.auth('datadb','8e8f5a4a21438')
  1. 内建的角色

数据库用户角色:read、readWrite;
数据库管理角色:dbAdmin、dbOwner、userAdmin;
集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
备份恢复角色:backup、restore;
所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
超级用户角色:root
// 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)
内部角色:__system