下载mongodb:

下载地址:https://www.mongodb.com/download-center#community

        到这个地址中选着linux版本,然后选择 “RHEL 7 Linux 64-bit x64”然后下面就会出现下载按钮,或使用右边的下载地址。

下载安装:

wget 下载:

wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.0.1.tgz

手动安装:

tar xf mongodb-linux-x86_64-rhel70-4.0.1.tgz
mv mongodb-linux-x86_64-rhel70-4.0.1 /usr/local/mongodb
mkdir /usr/local/mongodb/{conf,logs,db} -pv

使用yum安装:

创建yum源:

官网yum源:https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.4/x86_64/

阿里云yum源:https://mirrors.aliyun.com/mongodb/yum/redhat/$releasever/mongodb-org/3.4/x86_64/

vim mongodb-org-3.4.repo
[mongodb-org-3.4]
name=MongoDB 3.4 Repository
baseurl=https://mirrors.aliyun.com/mongodb/yum/redhat/$releasever/mongodb-org/3.4/x86_64/
gpgcheck=0
enabled=1

安装:

yum install mongodb-org

会自动安装如下几个包:

        mongodb-org-mongos 

        mongodb-org-server 

        mongodb-org-shell 

        mongodb-org-tools

配置:

一些常用配置项:

        dbpath:数据目录

        logpath:日志目录

        port:端口

        fork:true 表示后台运行


集群复制的关键两个选项:

Replica set options:

    --replSet arg                        副本集的名称,决定了当前副本集加入的是哪一个集群

    --replIndexPrefetch arg       副本集的索引预取,可以让复制更高效,[ none 不预取 | _id_only 预取id | all 预取所有 ],这个操作只能定义在从节点上,定义在主节点上是没有意义的。加上这一项说明当前节点作为副本集成员启动的。(其实这个不设置也行)。


复制集群搭建


        mongo版本3.4,最好用rpm包安装,因为有写好的配置文件如果没有则使用如下的配置文件。rpm安装的mongo默认配置文件在 /etc/mongod.conf 中,内容如下,3.4版本的配置文件使用的是类json格式。

# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

# Where and how to store data.
storage:
  dbPath: /var/lib/mongo
  journal:
    enabled: true
#  engine:
#  mmapv1:
#  wiredTiger:

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongod.pid  # location of pidfile

# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0  # Listen to local interface only, comment to listen on all interfaces.


#security:

#operationProfiling:

replication:
  replSetName: spock

#sharding:

## Enterprise-Only Options

#auditLog:

#snmp:

    主要设置了两个地方,第一个是复制集的名称,相同复制集名称要相同。也就是说当前配置的复制集都要用同一个名称。

replication:
  replSetName: spock

第二个是bindIp 这个是用来控制访问的。

bindIp: 0.0.0.0

开始搭建:

        准备三台机器,分别安装上mongo,只有主节点可以有数据,其他节点如果有数据的话把数据目录下的内容删除即可,否者会报错。

启动mongo:

        因为当前用的是rpm安装的,所以直接使用systemctl start mongod.service 来启动就可以了,配置文件已经在mongod.service 文件中指定过了。如果是手动安装的mongod命令需要用 mongod -f configFilePath 来指定配置文件。

先在有数据的节点上准备如下配置:

config = {
	"_id":"spock",
	"members":[
		{"_id":0, "host":"192.168.1.113:27017"},
		{"_id":1, "host":"192.168.1.114:27017"},
		{"_id":2, "host":"192.168.1.115:27017"}
	]
}

        上面config中的 "_id": "spock" 这个值就是配置文件中 replSetName: spock 这一项的值。

然后运行初始化命令:

rs.initiate(config)

如果返回中有 ok : 1 则说明集群创建成功。使用下面命令可以查看集群状态:

rs.status()

在输出的信息中 "stateStr" : "PRIMARY" 表示主节点,可以进行写操作,其他的只能执行查询操作。


一些副本集的设置


添加或移除成员:

移除成员:

rs.add("192.168.1.115:27017")

添加成员:

rs.add("192.168.1.115:27017")

添加或移除成员后可以使用 rs.isMaster() 或 rs.status() 或 rs.config() 查看是否被添加或移除了。


修改某成员信息:

var config = rs.config()
config.members[1].host = "mongodb02:27017"
rs.reconfig(config)


设置成员优先级:

        让某个成员成为主节点,只要这个节点的数据足够新就会成为主节点。

rs.add({"_id":1,"host":"192.168.1.114:27017","priority":1.5})


添加仲裁者到副本集:

rs.addArb("mongodb04:27017")

或:

rs.add({"_id":4, "host":"mongodb04:27017","arbiterOnly":true})


隐藏成员:

        如果是隐藏成员是不会通过rs.isMaster() 查看到的,隐藏成员对用户不可见,不可查询。

spock:SECONDARY> rs.isMaster()
{
	"hosts" : [
		"192.168.1.113:27017",
		"192.168.1.114:27017",
		"192.168.1.115:27017"
	],
	...
}

在主节点上操作如下:其中members[2] 这个2表示hosts中按顺序数第三个主机。

spock:PRIMARY> var config = rs.config()
spock:PRIMARY> config.members[2].hidden = 0
0
spock:PRIMARY> config.members[2].priority = 0
0
spock:PRIMARY> rs.reconfig(config)
{ "ok" : 1 }

这样再执行 rs.isMaster() 命令就可以看到第三个节点被隐藏了。

spock:PRIMARY> rs.isMaster()
{
	"hosts" : [
		"192.168.1.113:27017",
		"192.168.1.114:27017"
	],
	"passives" : [
		"192.168.1.115:27017"
	],
	...
}

取消隐藏节点:只要将修改的值改回去就可以了。

spock:PRIMARY> var config = rs.config()
spock:PRIMARY> config.members[2].hidden = false
false
spock:PRIMARY> config.members[2].priority = 1
1
spock:PRIMARY> rs.reconfig(config)
{ "ok" : 1 }

再次使用 rs.isMaster() 就可以看到被隐藏的节点已近恢复了。


复制延迟:

        使用复制延迟优先级必须为0

spock:PRIMARY> var config = rs.config()
spock:PRIMARY> config.members[2].slaveDelay = 10
10
spock:PRIMARY> config.members[2].priority = 0
0
spock:PRIMARY> rs.reconfig(config)

改回来就把 priority 改为1 salveDelay 改为0 即可。

指定不创建索引:

        有些节点不需要创建索引,看可以设置 "buildIndexes" : false ,注意,这是一个不可逆的设置,除非移除集群删除数据再重新加入。同时也要求优先级必须为0。

var config = rs.config()
config.members[2].buildIndexes = false
config.members[2].priority = 0
rs.reconfig(config)

把主节点变为备份节点:

rs.stepDown()
rs.stepDown(600) #单位秒

        这个命令是将主节点退化为备份节点,默认时间60秒,60秒后仍然没有主节点这个节点会重新要求选举,这个时间是可以在括号内设置的。


保持备份节点:

rs.freeze(10000)

        这个命令在备份节点上运行可以让备份节点始终保持备份状态,在主节点上运行 rs.freeze(0) 可让退位的主节点重新变为主节点。


使用维护模式:

function maybeMaintenanceMode(){
    var local=db.getSisterDB("local");
    // 如果成员不是备份节点或处于维护状态就直接返回
    if (!local.isMaster().secondary){
        return;
    )
    // 查找这个成员最后一次操作的时间
    var last=local.oplog.rs.find().sort({"$natural":-1}).next();
    var lasttime=last['ts']['t'];
    // 如果落后30秒以上
    if (lasttime<(new date()).getTime()-30){
        db.adminCommand({"replSetMaintenanceMode":true});
    }
};

将成员从维护模式中恢复:

db.adminCommand({"replSetMaintenanceMode":false});


查看当前成员是从哪个成员进行复制的:

hostname.adminCommand({replSetGetStatus:1})['syncingTo']


指定成员的复制源:

hostname.adminCommand({replSetSyncFrom:"192.168.1.114:27017"})

这个修改过程可能需要几分钟。


禁用复制链:

var config = rs.config()
// 对象不存在就创建一个空的
config.settings = config.settings || {}
config.settings.allowChaining = false
rs.reconfig(config)

        当 allowChaning 设置为 false 时,所有成员都会从主节点复制数据,当主节点不可用时就会到其他备份节点复制数据。


查看复制这条及延迟:

主节点上:

db.printReplicationInfo()

备份节点上:

db.printSlaveReplicationInfo()

输出的时间为落后时间,只是日志中操作的相差时间,并不表示追赶主节点所要的时间。


调整oplog大小:

        如果在oplog记录的时间内备份节点没有恢复,就会导致不得不重新进行完全同步。oplog无法动态修改,可以将备份节点一一下线,修改oplog大小然后上线。

修改oplog的方式为:将当前主机以单机方式启动,把oplog最后一条insert操作保存到其他集合中,然后删除当前的oplog,再创建一个新的oplog,再将最后那条insert操作写回oplog。如果插入没成功就会重新一次完整同步。最后将当前服务器作为副本集启动。

操作方法:

1、如果是主节点,则先将primary 降为 secondary。最后确保没有其他secondary 从该节点复制数据。使用 rs.status() 查看,关闭该mongod服务

 use admin
 db.adminCommand({shutdownServer:1});

2、以单机方式重启该mongod(注释掉 配置文件中的 replSet    shardsvr ,修改端口号)

3、将local.oplog.rs中的最后一条 insert 操作记录保存到临时集合中

mongo> use local
mongo>var cursor=db.oplog.rs.find({"op":"i"});
mongo>var lastinsert=cursor.sort({$natural:-1}).limit(1).next();
mongo>db.templastop.save(lastinsert);
mongo>db.templastop.findOne() #确保写入

4、将oplog.rs 删除:

db.oplog.rs.drop()

5、创建一个新的oplog.rs集合:

 db.createCollection("oplog.rs":{"capped":true,"size":10240})

6、将临时集合中的最后一条insert操作记录写回新创建的oplog.rs:

var temp=db.templastop.findOne();
db.oplog.rs.insert(temp);
db.oplog.rs.findOne()#确保写回,否则 该节点重新加入副本集后会删除该节点上所有数据,然后重新同步所有数据。

7、最后将该节点以副本集成员的身份重新启动即可。


从延迟备份中恢复:

方法一:

        清空非延迟节点上的所有数据,让程序自己从延迟节点去复制数据。

方法二:

        把非延迟节点上的数据都删掉,把延迟节点上的数据拷贝到其他成员。


创建索引:

        创建索引非常消耗时间,可以将成员一个一个以单机方式启动创建完成索引后再加入副本集,在主节点上趁主节点空闲期将读请求发送到其他节点,然后创建索引,这样所有节点都创建索引成功。或将主节点将为备节点然后在主节点上创建索引,再加入副本集。


查看延迟:

db.slave.find()
db.me.findOne() #查看成员标识符

记录着从当前成员同步的成员。


关闭mongo

关闭单机mongo:

方法一:

use admin
db.shutdownServer()

方法二:

mongod --shutdown

方法三:

kill <mongod process ID>
kill -2 <mongod process ID>

注意:千万不要用 kill -9 ,数据会丢失。


关闭副本集:

如果没有备份节点时强制关闭主节点命令:

db.adminCommand({shutdown : 1, force : true})

关闭备用节点命令,5秒后关闭:

db.adminCommand({shutdown : 1, timeoutSecs : 5})

或:

db.shutdownServer({timeoutSecs : 5})

关闭mongo详见:https://docs.mongodb.com/manual/tutorial/manage-mongodb-processes/