设为首页 收藏本站
查看: 1008|回复: 0

[经验分享] mongo副本集原理,搭建

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-10-28 08:43:40 | 显示全部楼层 |阅读模式
#进入mongo
mongo   默认端口27017启动的mongo服务,直接进入
mongo --port=27027   指定端口27027启动mongo服务,需加端口号启动
mongo 103.56.195.5:27017   登录指定主机的mongo服务,可以以此测试对端防火墙是否放通,mongo服务器端口

#mongo副本集启动参数:
[iyunv@mongo01-new db]# ps aux |grep mongo
root     112542  0.7  0.1 105841748 90120 ?     Sl   04:39   1:06 /usr/local/mongodb/bin/mongod --dbpath=/data/mongodb2/db
--logpath=/data/mongodb2/log/mongo.log --fork --port 27017 --logappend --replSet repl
--rest --httpinterface --maxConns=8000 --keyFile=/datamongodb2/keyfile/security

#创建帐号
use admin
db.createrUser({user:"mongo_admin",pwd:"xxx",roles:[{role:"root",db:"admin"}]})
db.auth('mongo_admin','xxx')才能使用admin数据库

(例)现在需要创建一个帐号,该账号需要有grant权限,即:账号管理的授权权限。注意一点,帐号是跟着库走的,所以在指定库里授权,必须也在指定库里验证(auth)。
> 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"
        }
    ]
}

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副本集之间建立的网络连接
[iyunv@mongo04-new mongoarb]# 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节点。因为仲裁节点不复制数据,因此利用仲裁节点可以实现最少的机器开 销达到两个节点热备的效果。

#仲裁节点启动参数
[iyunv@mongo04-new 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仲裁节点进程
[iyunv@mongo04-new 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开机自启动服务
[iyunv@mongo04-new 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,不能提供服务。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-131631-1-1.html 上篇帖子: mongo数据库安装 下篇帖子: 【mongdb报错】Failed global initialization: BadValue Invalid or no user locale set.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表