天天看点

mongodb服务安装,搭建副本集及原理概述

##初始化系统环境,参考文档:服务器系统环境初始化,Centos7系统

#mongodb下载安装

mkdir -p /server/src /server/logs
groupadd mongod
useradd -s /sbin/nologin -g mongod mongod  
cat /etc/passwd |grep mongo
cd /root
   ##安装mongodb 3.0.7版本,若需要其他版本,官网获取下载https://fastdl.mongodb.org/linux/
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.0.7.tgz   
tar zxvf mongodb-linux-x86_64-rhel70-3.0.7.tgz 
mv mongodb-linux-x86_64-rhel70-3.0.7 /usr/local/mongodb
mkdir -p /data/mongodb2/db
mkdir /data/mongodb2/log
mkdir /data/mongodb2/keyfile
chmod 755 !$
touch /data/mongodb2/keyfile/security
chmod 600 !$
echo "xxxxy" > !$
cat !$
touch /data/mongodb2/log/mongo.log
chmod 644 !$
chown -R mongod.mongod /data/mongodb2
ll /data
ll /data/mongodb2/
ll /data/mongodb2/log/
ll /data/mongodb2/keyfile/
vim /lib/systemd/system/mongod.service      
[Unit]
    Description=mongodb
    After=network.target remote-fs.target nss-lookup.target
 
[Service]
    Type=forking
    PIDFile=/data/mongodb2/db/mongod.lock
    ExecStart=/usr/local/mongodb/bin/mongod --dbpath=/data/mongodb2/db --logpath=/data/mongodb2/log/mongo.log --fork --port 27017 --logappend --replSet rep1 --rest --httpinterface --maxConns=8000 --keyFile=/data/mongodb2/keyfile/security
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/bin/kill -s QUIT $MAINPID
    PrivateTmp=true
    LimitFSIZE=infinity
    LimitCPU=infinity
    LimitAS=infinity
    LimitNOFILE=64000
    LimitNPROC=64000
 
[Install]
    WantedBy=multi-user.target      
systemctl enable mongod.service
systemctl start mongod.service
ps aux |grep mongo |grep -v 'grep'
systemctl status mongod.service 
    #将mongo程序添加到环境变量
echo "export PATH=/usr/local/mongodb/bin:$PATH" >>/etc/profile
source !$
echo $PATH      

#创建帐号

##创建帐号方式一(创建admin管理员)
use admin
db.createUser({user:"mongo_admin",pwd:"xxx",roles:[{role:"root",db:"admin"}]})      
    #下次登录需要验证才能对数据库进行操作
mongo
use admin
db.auth('mongo_admin','xxx')      

##创建管理员方式二(创建dba用户)

> use admin
switched to db admin
> db.createUser(
...   {
...     user: "dba",
...     pwd: "dba",
...     roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
...   }
... )
Successfully added user: {
    "user" : "dba",
    "roles" : [
        {
            "role" : "userAdminAnyDatabase",
            "db" : "admin"
        }
    ]
}
##现在需要创建一个帐号,该账号需要有grant权限,即:账号管理的授权权限。注意一点,帐号是跟着库走的,所以在指定库里授权,使用指定库也必须在指定库里验证(auth)。      

##创建用户解析

roles:指定用户的角色,可以用一个空数组给新用户设定空角色;在roles字段,可以指定内置角色和用户定义的角色。role里的角色可以选:

  Built-In Roles(内置角色):

    1. 数据库用户角色:read、readWrite;

    2. 数据库管理角色:dbAdmin、dbOwner、userAdmin;

    3. 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;

    4. 备份恢复角色:backup、restore;

    5. 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase

    6. 超级用户角色:root  

    // 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)

    7. 内部角色:__system

具体角色: 

Read:允许用户读取指定数据库

readWrite:允许用户读写指定数据库

dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile

userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户

clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。

readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限

readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限

userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限

dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。

root:只在admin数据库中可用。超级账号,超级权限

#副本集配置文件

conf=({_id:"repl",members:[{_id:0,host:"103.56.195.2"},{_id:1,host:"103.56.195.3"},{_id:2,host:"103.56.195.4"}]})
rs.initiate(conf)
rs.status()
rs.conf()                        #查看副本集配置文件
{
	"_id" : "repl",
	"version" : 8,
	"members" : [
		{
			"_id" : 0,
			"host" : "103.56.195.2:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : 0,
			"votes" : 1
		},
		{
			"_id" : 1,
			"host" : "103.56.195.3:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : 0,
			"votes" : 1
		},
		{
			"_id" : 3,
			"host" : "103.56.195.5:27027",
			"arbiterOnly" : true,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : 0,
			"votes" : 1
		},
		{
			"_id" : 2,
			"host" : "103.56.195.4:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : 0,
			"votes" : 1
		}
	],
	"settings" : {
		"chainingAllowed" : true,
		"heartbeatTimeoutSecs" : 10,
		"getLastErrorModes" : {
			
		},
		"getLastErrorDefaults" : {
			"w" : 1,
			"wtimeout" : 0
		}
	}
}      

#设置副本集中每台服务器的优先级

mongo 10.10.148.130:27017       #ip和port是某个节点的地址   
use admin 
cfg={_id:"testrs",members:[{_id:0,host:'10.10.148.130:27017',priority:2},{_id:1,host:'10.10.148.131:27017',priority:1},{_id:2,host:'10.10.148.132:27017',arbiterOnly:true}]};   
rs.initiate(cfg)      

#测试副本集数据同步,在primary主节点上写数据

[primary]
for(var i=0;i<10002;i++){db.test.insert({"name":"test"+i,"age":123})}
db.test.count()

[slave]
rs.slaveOk()
db.test.count()      

#查看mongo副本集服务器之间之间建立的网络连接

netstat -atnp |grep mongo
tcp        0      0 0.0.0.0:27017           0.0.0.0:*               LISTEN      60566/mongod        
tcp        0      0 0.0.0.0:27027           0.0.0.0:*               LISTEN      60518/mongod        
tcp        0      0 0.0.0.0:28027           0.0.0.0:*               LISTEN      60518/mongod        
tcp        0      0 103.56.195.5:27027      103.56.195.3:48225      ESTABLISHED 60518/mongod        
tcp        0      0 103.56.195.5:32798      103.56.195.2:27017      ESTABLISHED 60518/mongod        
tcp        0      0 103.56.195.5:27027      103.56.195.4:56920      ESTABLISHED 60518/mongod        
tcp        0      0 103.56.195.5:37736      103.56.195.4:27017      ESTABLISHED 60518/mongod        
tcp        0      0 103.56.195.5:27027      103.56.195.2:56702      ESTABLISHED 60518/mongod        
tcp        0      0 103.56.195.5:59560      103.56.195.3:27017      ESTABLISHED 60518/mongod      

#增删节点

#插入副本节点
rs.add({"_id":2,"host":"103.56.195.4:27017"})      
#插入仲裁节点
rs.addArb("103.56.195.5:27027")      
#删除节点
rs.remove("103.56.195.4:27017")      

#仲裁节点

上面说明已经让25服务器成为仲裁节点。副本集要求参与选举投票(vote)的节点数为奇数,当我们实际环境中因为机器等原因限制只有两个(或偶数)的节点,这时为了实现 Automatic Failover引入另一类节点:仲裁者(arbiter),仲裁者只参与投票不拥有实际的数据,并且不提供任何服务,因此它对物理资源要求不严格。

通过实际测试发现,当整个副本集集群中达到50%的节点(包括仲裁节点)不可用的时候,剩下的节点只能成为secondary节点,整个集群只能读不能写。比如集群中有1个primary节点,2个secondary节点,加1个arbit节点时:当两个secondary节点挂掉了,那么剩下的原来的 primary节点也只能降级为secondary节点;当集群中有1个primary节点,1个secondary节点和1个arbit节点,这时即使 primary节点挂了,剩下的secondary节点也会自动成为primary节点。因为仲裁节点不复制数据,因此利用仲裁节点可以实现最少的机器开 销达到两个节点热备的效果。

#仲裁节点启动参数

[[email protected] mongoarb]# cat /usr/local/mongodb/mongoarb.conf 
    dbpath=/data/mongoarb/arbiter
    logpath=/data/mongoarb/log/arbiter.log 
    fork=true
    port=27027 
    logappend=true
    replSet=repl 
    keyFile=/data/mongoarb/keyfile/security      

#mongo仲裁节点进程

[[email protected] mongoarb]# ps aux |grep mongo
root  60518  1.0  0.1 105572288 66668 ?  Sl  18:30  0:00 /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/mongoarb.conf --rest
root  60566  0.3  0.0 491396 47140 ? Sl 18:31  0:00 /usr/local/mongodb/bin/mongod --dbpath=/data/mongodb2/db --logpath=/data/mongodb2/log/mongo.log --fork --port 27017 --logappend      

#仲裁节点mongo服务添加到systemctl开机自启动服务

[[email protected] mongoarb]# cat /lib/systemd/system/mongoarb.service 
[Unit]
    Description=mongoarb
    After=network.target remote-fs.target nss-lookup.target 
[Service]
    Type=forking
    PIDFile=/data/mongoarb/arbiter/mongod.lock
    ExecStart=/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/mongoarb.conf --rest 
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/bin/kill -s QUIT $MAINPID
    PrivateTmp=true
    LimitFSIZE=infinity
    LimitCPU=infinity
    LimitAS=infinity
    LimitNOFILE=64000
    LimitNPROC=64000
[Install]
    WantedBy=multi-user.target      

#读写分离

MongoDB副本集对读写分离的支持是通过Read Preferences特性进行支持的,这个特性非常复杂和灵活。

应用程序驱动通过read reference来设定如何对副本集进行读取操作,默认的,客户端驱动所有的读操作都是直接访问primary节点的,从而保证了数据的严格一致性。

支持五种的read preference模式:官网说明

primary主节点,默认模式,读操作只在主节点,如果主节点不可用,报错或者抛出异常。

primaryPreferred 首选主节点,大多情况下读操作在主节点,如果主节点不可用,如故障转移,读操作在从节点。

secondary从节点,读操作只在从节点, 如果从节点不可用,报错或者抛出异常。

secondaryPreferred首选从节点,大多情况下读操作在从节点,特殊情况(如单主节点架构)读操作在主节点。

nearest最邻近节点,读操作在最邻近的成员,可能是主节点或者从节点,关于最邻近的成员请参考

注意:2.2版本之前的MongoDB对Read Preference支持的还不完全,如果客户端驱动采用primaryPreferred实际上读取操作都会被路由到secondary节点。

副本集中数据同步过程:Primary节点写入数据,Secondary通过读取Primary的oplog得到复制信息,开始复制数据并且将复制信息写入到自己的oplog。如果某个操作失败,则备份节点停止从当前数据源复制数据。如果某个备份节点由于某些原因挂掉了,当重新启动后,就会自动从oplog的最后一个操作开始同步,同步完成后,将信息写入自己的oplog,由于复制操作是先复制数据,复制完成后再写入oplog,有可能相同的操作会同步两份,不过MongoDB在设计之初就考虑到这个问题,将oplog的同一个操作执行多次,与执行一次的效果是一样的。简单的说就是:

当Primary节点完成数据操作后,Secondary会做出一系列的动作保证数据的同步:

1:检查自己local库的oplog.rs集合找出最近的时间戳。

2:检查Primary节点local库oplog.rs集合,找出大于此时间戳的记录。

3:将找到的记录插入到自己的oplog.rs集合中,并执行这些操作。

副本集的同步和主从同步一样,都是异步同步的过程,不同的是副本集有个自动故障转移的功能。其原理是:slave端从primary端获取日志,然后在自己身上完全顺序的执行日志所记录的各种操作(该日志是不记录查询操作的),这个日志就是local数据 库中的oplog.rs表,默认在64位机器上这个表是比较大的,占磁盘大小的5%,oplog.rs的大小可以在启动参数中设 定:--oplogSize 1000,单位是M。

注意:在副本集的环境中,要是所有的Secondary都宕机了,只剩下Primary。最后Primary会变成Secondary,不能提供服务。

参考文档:MongoDB 副本集的原理、搭建、应用

http://www.cnblogs.com/zhoujinyi/p/3554010.html

2-Mongodb集群搭建的三种方式

http://wenku.baidu.com/link?url=Th6OyRUeoUE_-Kxq09vWrUEHT1_k9JgXV-0F6sWdmRO6MyJbNPKa8B6FfGd26fZBIT8DjCTkj25AOLDFOROg5L1tSn_kzzzu80ejf35PlL_

转载于:https://blog.51cto.com/jschu/1706918