MongoDB集群架构

一、MongoDB 复制集特性

  1. 复制集群的架构
  2. 复制集群搭建
  3. 复制集群的选举配置

1.复制集群的架构

2.复制集群搭建基础示例

2.复制集群搭建基础示例

主节点配置

dbpath=/data/mongo/master

port=27017

fork=true

logpath=master.log

replSet=MyCluster

从节点配置

dbpath=/data/mongo/slave

port=27018

fork=true

logpath=slave.log

replSet=MyCluster

#子节点配置2

dbpath=/data/mongo/slave2

port=27019

fork=true

logpath=slave2.log

replSet=MyCluster

  • 分别启动三个节点
  • 进入其中一个节点

集群复制配置管理

#查看复制集群的帮助方法

rs.help()

添加配置

// 声明配置变量

var cfg ={"_id":"tuling",

"members":[

{"_id":1,"host":"127.0.0.1:27017"},

{"_id":2,"host":"127.0.0.1:27018"}

]

}

// 初始化配置

rs.initiate(cfg)

// 查看集群状态

rs.status()

变更节点示例:

// 插入新的复制节点

rs.add("127.0.0.1:27019")

// 删除slave 节点

rs.remove("127.0.0.1:27019")

注:默认节点下从节点不能读取数据。调用 rs.slaveOk() 解决。

 

3.复制集群选举操作

为了保证高可用,在集群当中如果主节点挂掉后,会自动 在从节点中选举一个 重新做为主节点。

  1. 演示节点的切换操作
  1. kill 主节点
  1. 进入从节点查看集群状态 。rs.status()

选举的原理:

选举协议

pv0: 基于priority 和 optime 选举新主,依赖clock synchronization。

有选举权的节点,每一轮选举最多投一票,在30s内,不能重复投票。

pv1:基于Raft协议,每个成员都有 对候选主列表成员投赞成或者反对票,不是单方面否决选举,没有节点投反对票,且获得赞成票数超过有权投票节点总数的1/2,则能成为Primary。否则进入下一轮选举。

因使用了Raft协议,加快  back-to-back选主,减少整个选举新主所需花费的总时间,相应的会增加WriteConcern(w:1)rollback的可能性。

Raft将时间分为多个term,term以连续的整数来标识,每个term以一次election开始,如果有server被选为leader,则该term的剩余时间该server都是leader。

有些term里,可能并没有选出leader,这时候会开启一个新term来继续选主

2.怎么选举?

选举:

假设X是一个Secondary,那么X会定时检测是否需要选举自己成为Primary。其检测内容包括:
1) 是否集群中有其它节点认为自己是Primary?
2) X节点自己是否已经是Primary?
3) X节点自己是否有资格成为Primary?
如果这三个问题中的任何一个回答是否定的,那么X节点就不会试图把自己变成Primary。(也就是说,只有当X节点是一个能够当Primary 的secondary,并且其它节点都不是Primary时,X才会发起选举并选自己为Primary)。

投票规则:如果没有节点投反对票,且获得赞成票数超过有权投票节点总数的1/2,则能成为Primary。否则进入下一轮选举。

3.2之前(只支持pv0 协议):

replica set最多可以50个节点,但最多有7个节点参与选举,每个节点最多投一票,得到票数最多的为主。

Because a replica set can have up to 50 members, but only 7 voting members, non-voting members allow a replica set to have more than seven members.

影响选举的因素

1)优先级(先看优先级,级别越高,优先为主,priority=0:表示不参与选举、不能成为主

2)optime (如果优先级都相同,则有最新的 optime 的成为主) 注意:集群中 prority 最大,但是optime 不是最新的,落后集群其他最新optime超过10s的prority 最大也不能选为主。

3)心跳 (副本级中的每个member默认都是每2秒ping 其他节点,如果超过{"heartbeatTimeoutSecs" : 10} 默认是10秒没有回应,则标记节点不可达s_down)

网络分裂(Network Partition):

如果Primary在少数的那一组,那么次Primary会变成Secondary,多数节点(互相能通信)的那组选举新的主(Primary)。

例外情况:如发生网络分裂,被分裂的一组选举出一个新的Primary,老的Primary还没降级,这就出现了2个Primary,这就是脑裂现象。此时2个Primary都有写入,直到网络恢复后,若老主再次成为Primary,则脑裂过程中选举出的新Primary会回滚脑裂过程新写入的数据;若老主成为Secondary,则回滚老主脑裂过程新写入的数据。

>= 3.2开始:

支持pv0 协议、pv1协议,默认是pv1协议。

影响选举的因素

1)Replication Election Protocol(从3.2开始支持protocolVersion: 1)

2)优先级(先看优先级,级别越高,优先为主,priority=0:表示不参与选举、不能成为主

3)optime (如果优先级都相同,则有最新的 optime 的成为主)

4)心跳 (副本级中的每个member默认都是每2秒ping 其他节点,protocolVersion:0如果超过{"heartbeatTimeoutSecs" : 10} 默认是10秒 或者 protocolVersion:1时 electionTimeoutMillis 默认是10秒没有回应,则标记节点不可达s_down,类似Redis sentinel主观下线)

下面status的节点有资格成为选举者:
PRIMARY
SECONDARY
RECOVERING
ARBITER
ROLLBACK

什么时候发生选举主?

1)初始化副本集

2)修改了节点的priority  (config.members[0].priority = 3)

3)网络分裂(当前的Primary和多数的节点不通,当前Primary变成Secondary多数节点的组重新选Primary)

4)当前主上执行rs.stepDown()

5)Secondary ping超过heartbeatTimeoutSecs 后不可达,则标记Primary s_down,发生选主

示例:

重新配置节点

var cfg ={"_id":"tuling",

  "protocolVersion" : 1,

  "members":[

{"_id":1,"host":"127.0.0.1:27017","priority":10},

{"_id":2,"host":"127.0.0.1:27018","priority":0},

{"_id":3,"host":"127.0.0.1:27019","priority":5},

                {"_id":4,"host":"127.0.0.1:27020","arbiterOnly":true}

]

}

// 重新装载配置,并重新生成集群节点。

rs.reconfig(cfg)

//重新查看集群状态

rs.status()

节点说明:

 PRIMARY 节点: 可以查询和新增数据

 SECONDARY 节点:只能查询 不能新增  基于priority 权重可以被选为主节点

 RBITER 节点: 不能查询数据 和新增数据 ,不能变成主节点

二、MongoDB 分片操作

知识点:

  1. 分片的概念
  2. mongodb 中的分片架构
  3. 分片示例

1.为什么需要分片?

随着数据的增长,单机实例的瓶颈是很明显的。可以通过复制的机制应对压力,但mongodb中单个集群的 节点数量限制到了12个以内,所以需要通过分片进一步横向扩展。此外分片也可节约磁盘的存储。

1.mongodb 中的分片架构

分片中的节点说明:

  • 路由节点(mongos):用于分发用户的请求,起到反向代理的作用。
  • 配置节点(config):用于存储分片的元数据信息,路由节点基于元数据信息 决定把请求发给哪个分片。(3.4版本之后,该节点,必须使用复制集。)
  • 分片节点(shard):用于实际存储的节点,其每个数据块默认为64M,满了之后就会产生新的数据库。

2.分片示例流程:

  1. 配置 并启动config 节点集群
    1. 配置集群信息
  2. 配置并启动2个shard 节点
  3. 配置并启动路由节点
    1. 添加shard 节点
    2. 添加shard  数据库
    3. 添加shard 集合
  4. 插入测试数据
    1. 检查数据的分布
  5. 插入大批量数据查看shard 分布
    1. 设置shard 数据块为一M
    2. 插入10万条数据

配置 并启动config 节点集群

# 节点1 config1-37017.conf

dbpath=/data/mongo/config1

port=37017

fork=true

logpath=logs/config1.log

replSet=configCluster

configsvr=true

# 节点2 config2-37018.conf

dbpath=/data/mongo/config2

port=37018

fork=true

logpath=logs/config2.log

replSet=configCluster

configsvr=true

进入shell 并添加 config 集群配置:

var cfg ={"_id":"configCluster",

  "protocolVersion" : 1,

  "members":[

{"_id":0,"host":"127.0.0.1:37017"},

{"_id":1,"host":"127.0.0.1:37018"}

]

}

// 重新装载配置,并重新生成集群。

rs.initiate(cfg)

# 配置 shard 节点集群==============

# 节点1 shard1-47017.conf

dbpath=/data/mongo/shard1

port=47017

fork=true

logpath=logs/shard1.log

shardsvr=true

# 节点2 shard2-47018.conf

dbpath=/data/mongo/shard2

port=47018

fork=true

logpath=logs/shard2.log

shardsvr=true

配置 路由节点 mongos ==============

# 节点 route-27017.conf

port=27017

bind_ip=0.0.0.0

fork=true

logpath=logs/route.log

configdb=conf/127.0.0.1:37017,127.0.0.1:37018

// 添加分片节点

sh.status()

sh.addShard("127.0.0.1:47017");

sh.addShard("127.0.0.1:47018");

为数据库开启分片功能

sh.enableSharding("tuling")

 为指定集合开启分片功能

 sh.shardCollection("tuling.emp",{"_id":1})

修改分片大小

 use config

 db.settings.find()

db.settings.save({_id:"chunksize",value:1})

 尝试插入1万条数据:

 for(var i=1;i<=100000;i++){

     db.emp.insert({"_id":i,"name":"copy"+i});

}

db.emp.createIndex({_id: 'hashed'})

三、MongoDB用户权限管理

// 创建管理员用户

use admin;

db.createUser({"user":"admin","pwd":"123456","roles":["root"]})

#验证用户信息

db.auth("admin","123456")

#查看用户信息

db.getUsers()

# 修改密码

db.changeUserPassword("admin","123456")

 以auth 方式启动mongod,需要添加auth=true 参数 ,mongdb 的权限体系才会起作用:

#以auth 方向启动mongod (也可以在mongo.conf 中添加auth=true 参数)

./bin/mongod -f conf/mongo.conf --auth

# 验证用户

use admin;

db.auth("admin","123456")

 创建只读用户

db.createUser({"user":"dev","pwd":"123456","roles":["read"]})

重新登陆 验证用户权限

use demo;

db.auth("dev","123456")

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小强同志

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值