前言:
有一个使用 mongodb 做数据库的项目要上生产了,所以在生产环境规划了两台机器用于搭建数据库主从,但是调研搭建的过程中发现主从模式还是有些缺陷,mongodb 提供了另一种复制模式替代主从模式。
一、mongodb 的几种部署模式
mongodb 总共有四种部署模式:
1.单机模式;
2.主从模式;主节点挂了,需要手动把从节点切换成主节点继续提供服务。
3.复制模式;主节点挂了,复制节点会自动选举新的主节点。
4.集群模式;磁盘瓶颈,单节点能力瓶颈推荐使用集群模式进行能力扩展。
二、复制模式
Primary选举
复制集通过 replSetInitiate
命令(或mongoshell的rs.initiate()
)进行初始化,初始化后各个成员间开始发送心跳消息,并发起 Primary 选举操作,获得大多数成员投票支持的节点,会成为 Primary,其余节点成为 Secondary。
“大多数”的定义
假设复制集内投票成员数量为N(Primary+Secondary),则大多数为 N/2 + 1,当复制集内存活成员数量不足大多数时,整个复制集将无法选举出Primary,复制集将无法提供写服务,处于只读状态。
投票成员数 | 大多数 | 容忍失效数 |
---|---|---|
1 | 1 | 0 |
2 | 2 | 0 |
3 | 2 | 1 |
4 | 3 | 1 |
5 | 3 | 2 |
6 | 4 | 2 |
7 | 4 | 3 |
根据上表,N 最少也需要3个。
特殊的Secondary节点
每个复制节点都有优先级,选举时一般会先选优先级最大的。另外还有两类特殊 Secondary 节点,一类是优先级为0的(从Primary复制数据,不会被选为Primary),另一类是Arbiter(不复制数据,只有选举功能,可参与投票,本身不会被选为Primary)。
三、复制模式部署
1.搭建规划:
因为之前是计划主从模式部署,只申请了两台机器,后面调研发现复制模式比较好,所以计划是 Primary + Secondary + Arbiter 部署,Primary 使用一台服务器,Secondary + Arbiter 使用另一台服务器。
搭建之前先找一台机器模拟搭建下,相关版本信息如下:
机器配置和mongodb版本:
服务器:Alibaba Cloud Linux release 3 (Soaring Falcon)【对标的reahat8】
mongodb版本:5.0.5
规划启动三个 mongodb 进程,分别占用27017(Primary )、27018(Secondary )、27019(Arbiter )端口;每个部署相对独立,部署可参考linux 单机部署 mongodb。
目录规划:
# 端口27017的mongodb目录
/apps/program/mongodb-0
# 端口27018的mongodb目录
/apps/program/mongodb-1
# 端口27019的mongodb目录
/apps/program/mongodb-2
每个目录下另创建目录
data 存放数据
logs 存放日志
etc 存放配置文件
2.配置文件
Primary 配置文件如下,另外两个配置文件相应修改目录和端口即可。
systemLog:
# 日志输出目的地,可以指定为“ file”或者“syslog”
destination: file
# 日志存储路径
path: /apps/program/mongodb-0/logs/mongodb.log
logAppend: true
storage:
# 是否开启journal日志持久存储
journal:
enabled: true
dbPath: /apps/program/mongodb-0/data
# 是否将不同DB的数据存储在不同的目录中
directoryPerDB: true
engine: wiredTiger
wiredTiger:
engineConfig:
# 数据占用内存的大小
cacheSizeGB: 0.5
processManagement:
# 是否后台启动
fork: true
# 进程文件
pidFilePath: /apps/program/mongodb-0/mongod.pid
net:
# 可访问的地址
bindIp: 0.0.0.0
# 进程端口
port: 27017
security:
# 是否开启用户访问控制
authorization: enabled
# 集群之间的认证模式
clusterAuthMode: keyFile
# 当认证模式为keyFile时,该文件的路径
keyFile: /apps/program/mongodb-0/keyFile
replication:
# oplog的大小,类似mysql的binlog
oplogSizeMB: 512
# 复制集的名称
replSetName: fuzhiji
keyFile 的内容其实没有太多约束,例如可以使用 openssl 随机生成100字符的base64编码:
openssl rand -base64 100 > ./keyFile
keyFile 权限是 400,复制集的每个keyFile要完全一致。
3.启动 mongodb
切换到mongodb的bin目录下,分别使用对应的配置文件启动三个进程:
./mongod -f /apps/program/mongodb-*/etc/mongodb.conf
4.配置复制集
登录任意一个可用mongodb数据库:
# 登入任意一台数据库
./mongo --host localhost --port 27017
# 声明复制集的配置
config={_id:'fuzhiji',
members:[
{_id: 0, host: 'localhost:27017',priority:2},
{_id: 1, host: 'localhost:27018',priority:1},
{_id: 2, host: 'localhost:27019',arbiterOnly:true}
]
}
#复制集配置生效
rs.initiate(config)
命令执行后,该连接命令窗口就会出现该连接的节点属性:
5.其他命令
# 查看当前复制集集群中成员的配置
rs.config()
# 查看主节点
db.isMaster()
# 查看复制集集群成员状态
rs.status()
# 新增节点到复制集
rs.add('ip:port')
# 从复制集删除节点
rs.remove('ip:port')
# 新增仲裁节点
rs.addArb('ip:port')
# 允许在Secondary节点可以进行查询,需要在副本节点上操作
rs.secondaryOk()
# 查看当前连接
db.getMongo()
# 修改节点优先级,需要在Primary节点操作,操作前需要切到 admin 进行认证
config=rs.config()
config.members[1].priority=5
rs.reconfig(config)
四、参考文档
1.官方配置文件说明:5.0版本配置文件配置项