复制集的选举简介
MongoDB 复制集的节点是通过选举产生主节点
复制的原理
复制是基于操作日志 oplog, 相当于 MySQL 中的二进制日志, 只记录发生改变的记录. 复制是将主节点的 oplog 日志同步并应用到其他从节点过程
选举的原理
节点类型分为标准 (host) 节点, 被动 (passive) 节点和仲裁 (arbiter) 节点
1. 只有标准节点可能被选举为主 (primary) 节点, 有选举权; 被动节点有完整副本, 只能作为复制集保存, 不可能成为主节点, 没有选举权; 仲裁节点不存放数据, 只负责投票选举, 不可能成为主节点, 不存放数据, 依然没有选举权
2. 标准节点与被动节点的区别: priority 值高者是标准节点, 低者则为被动节点
3. 选举规则是票数高者获胜, priority 是优先权为 0~1000 的值, 相当于额外增加 0~1000 的票数. 选举结果: 票数高者获胜; 若票数相同, 数据新者获胜
一, 安装 MongoDB
1, 自定义 yum 源文件
- [root@RedHat7_6 ~]# cd /etc/yum.repos.d/
- [root@redhat7_6 yum.repos.d]# mkdir bak
- [root@redhat7_6 yum.repos.d]# mv CentOS-* bak/
- [root@redhat7_6 yum.repos.d]# vim local.repo
- [mongodb-org]
- name=MongoDB Repository
- baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.6/x86_64/
- gpgcheck=1
- enabled=1
- gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc
2, 安装 MongoDB
- [root@redhat7_6 ~]# yum -y install mongodb-org
- [root@redhat7_6 ~]# yum clean all #清除 yum 缓存
- [root@redhat7_6 ~]# yum list #重新加载源
二, 配置复制集
1, 创建实例相关文件
- [root@redhat7_6 ~]# mkdir -p /data/mongodb/mongodb{1,2,3,4} #创建数据目录
- [root@redhat7_6 ~]# mkdir -p /data/logs/mongodb #创建日志目录
- [root@redhat7_6 ~]# cd /data/logs/mongodb/
- [root@redhat7_6 mongodb]# touch mongodb{1,2,3,4}.log #创建日志文件
- [root@redhat7_6 mongodb]# chmod 777 *.log #修改目录权限
2, 编辑实例 1 配置文件
- [root@redhat7_6 ~]# cp -p /etc/mongod.conf /etc/mongod1.conf
- [root@redhat7_6 ~]# vim /etc/mongod1.conf #修改配置文件
- path: /data/logs/mongodb/mongodb1.log #约第 10 行, 编辑日志文件路径, 对应其他的实例依次往下......
- dbPath: /data/mongodb/mongodb1/ #编辑数据目录文件路径, 也是一样对应其他的实例依次往下......
- net: #约 28 行, 指定网络接口
- port: 27017 #编辑端口号, 实例 1 为 27017, 实例 2 为 27018, 依次往下排......
- bindIp: 0.0.0.0
- replication: #约 37 行, 打开复制选项注释, 四台实例都要添加
- replSetName: kgcrs #指定复制集名称
3, 编辑其他实例配置文件
- [root@redhat7_6 ~]# cp -p /etc/mongod1.conf /etc/mongod2.conf #创建其他三个 MongoDB 实例配置文件
- [root@redhat7_6 ~]# cp -p /etc/mongod1.conf /etc/mongod3.conf
- [root@redhat7_6 ~]# cp -p /etc/mongod1.conf /etc/mongod4.conf
- [root@redhat7_6 ~]# rm -rf /etc/mongod.conf
4, 编写启动脚本
- [root@redhat7_6 ~]# vim /etc/init.d/mongodb
- #!/bin/bash
- # descript:Mongodb Server Control Script
- # Author: GuiHaiYiDao TEL:139741741741
- # date:long long ago
- instance=$1
- action=$2
- case "$action" in
- 'start')
- /usr/bin/mongod -f /etc/"$instance".conf
- ;;
- 'stop')
- /usr/bin/mongod -f /etc/"$instance".conf --shutdown
- ;;
- 'restart')
- /usr/bin/mongod -f /etc/"$instance".conf --shutdown
- /usr/bin/mongod -f /etc/"$instance".conf
- ;;
- esac
- [root@redhat7_6 ~]# chmod +x /etc/init.d/mongodb
- [root@redhat7_6 ~]# /etc/init.d/mongodb mongod1 start
- [root@redhat7_6 ~]# /etc/init.d/mongodb mongod2 start
- [root@redhat7_6 ~]# /etc/init.d/mongodb mongod3 start
- [root@redhat7_6 ~]# /etc/init.d/mongodb mongod4 start
- [root@redhat7_6 ~]# netstat -anpt | grep 'mongod'
5, 初始化配置复制集
- [root@redhat7_6 ~]# mongo --port 27017
- > cfg={"_id":"kgcrs","members":[{"_id":0,"host":"192.168.100.76:27017","priority":100},{"_id":1,"host":"192.168.100.76:27018","priority":100},{"_id":2,"host":"192.168.100.76:27019","priority":0},{"_id":3,"host":"192.168.100.76:27020","arbiterOnly":true}]} #定义两个主节点, 一个被动节点, 一个仲裁节点> rs.initiate(cfg) #初始化复制集> kgcrs:PRIMARY> rs.isMaster() #查看群集状态
- {
- "hosts" : [ #标准节点
- "192.168.100.76:27017",
- "192.168.100.76:27018"
- ],
- "passives" : [ #被动节点
- "192.168.100.76:27019"
- ],
- "arbiters" : [ #仲裁节点
- "192.168.100.76:27020"
- ],
- "setName" : "kgcrs",
- "setVersion" : 1,
- "ismaster" : true,
- "secondary" : false,
- "primary" : "192.168.100.76:27017",
- "me" : "192.168.100.76:27017",
- "electionId" : ObjectId("7fffffff0000000000000001"),
- }
- ......
三, 验证复制集选举原理
1, 查看 oplog 日志
- kgcrs:PRIMARY> use testDB #进入或创建库
- kgcrs:PRIMARY> db.t1.insert({"id":1,"name":"Tom"}) #插入数据
- kgcrs:PRIMARY> db.t1.insert({"id":2,"name":"Jack"})
- kgcrs:PRIMARY> db.t1.find() #查看集合
- { "_id" : ObjectId("5b95c4c915740fa3d0077e8d"), "id" : 1, "name" : "Tom" }
- { "_id" : ObjectId("5b95c4d715740fa3d0077e8e"), "id" : 2, "name" : "Jack" }
- kgcrs:PRIMARY> db.t1.update({"id":2},{"$set":{"name":"Bob"}}) #修改数据
- kgcrs:PRIMARY> db.t1.remove({"id":2}) #移除数据
- kgcrs:PRIMARY> show dbs
- kgcrs:PRIMARY> use local #进入 local 库
- kgcrs:PRIMARY> show collections
- kgcrs:PRIMARY> db.oplog.rs.find() #注意查看每个文档都代表主节点上执行的一个操作, oplog 会包含所有对数据有修改的操作(查询操作不会记录)
2, 模拟主节点 01 故障(端口 27017)
- [root@redhat7_6 ~]# /etc/init.d/mongodb mongod1 stop #关闭 01 节点服务器
- [root@redhat7_6 ~]# mongo --port 27018
- kgcrs:PRIMARY> rs.status() #查看复制状态
3, 模拟主节点 02 故障(端口 27018)
- [root@redhat7_6 ~]# /etc/init.d/mongodb mongod2 stop
- [root@redhat7_6 ~]# mongo --port 27019 #进入第三个实例
4, 启动标准节点
- [root@redhat7_6 ~]# /etc/init.d/mongodb mongod1 start #第一个先启动实例 1, 成为主节点. 可以进行人为控制
- [root@redhat7_6 ~]# /etc/init.d/mongodb mongod2 start
- kgcrs:PRIMARY> rs.status()
四, MongoDB 复制集管理
1, 配置允许在从节点读取数据
1). 查看实例 1 服务
- [root@redhat7_6 ~]# mongo --port 27017
- kgcrs:PRIMARY> show dbs
- kgcrs:PRIMARY> use testDB
- kgcrs:PRIMARY> db.t1.find() #查询集合数据
- { "_id" : ObjectId("5b98d55d06a599fff182be6d"), "id" : 1, "name" : "Tom" }
2). 设置允许读取数据
- [root@redhat7_6 ~]# mongo --port 27018
- kgcrs:SECONDARY> rs.slaveOk() #允许默认从节点读取数据
- kgcrs:SECONDARY> show dbs
- ......
- testDB 0.000GB #读取成功
- kgcrs:SECONDARY> use testDB
- kgcrs:SECONDARY> db.t1.find()
2, 查看复制状态信息
- kgcrs:SECONDARY> rs.help() #查看命令帮助 kgcrs:SECONDARY> rs.printReplicationInfo()
- configured oplog size: 990MB #oplog 文件大小
- log length start to end: 7688secs (2.14hrs) #日志启用的时间段. 单位: 秒
- oplog first event time: Wed Sep 12 2018 16:50:59 GMT+0800 (CST) #第一个事务日志的产生时间
- oplog last event time: Wed Sep 12 2018 18:59:07 GMT+0800 (CST) #第一个事务日志的结束时间
- now: Wed Sep 12 2018 18:59:16 GMT+0800 (CST) #当前时间 kgcrs:SECONDARY> rs.printSlaveReplicationInfo() #可以通过下面 IP, 端口发现, 仲裁节点不具备数据复制
- source: 192.168.100.76:27018 #从库的 IP 及端口
- syncedTo: Wed Sep 12 2018 18:59:27 GMT+0800 (CST) #目前的同步情况, 延迟了多久等信息
- 0 secs (0 hrs) behind the primary
- source: 192.168.100.76:27019
- syncedTo: Wed Sep 12 2018 18:59:27 GMT+0800 (CST)
- 0 secs (0 hrs) behind the primary
3, 更改 oplog 大小
简介: oplog 即 operations log 简写, 存储在 local 数据库中. oplog 中新操作会自动替换旧的操作, 以保证 oplog 不会超过预设的大小. 默认情况下, oplog 大小会占用 64 位的实例 5% 的可用磁盘
原理: 主节点应用业务操作修改到数据库中, 然后记录这些操作到 oplog 中, 从节点复制这些 oplog, 然后应用这些修改. 这些操作是异步的. 如果从节点的操作已经被主节点落下很远, oplog 日志在从节点还没执行完, oplog 可能已经轮滚一圈了, 从节点跟不上同步, 复制就会停下, 从节点需要重新做完整的同步, 为了避免此种情况, 尽量保证主节点的 oplog 足够大, 能够存放相当长时间的操作记录
1). 关闭从节点服务器
- [root@redhat7_6 ~]# mongo --port 27018
- kgcrs:SECONDARY> use admin
- kgcrs:SECONDARY> db.shutdownServer() #关闭服务, 从复制集成员退出来
2). 修改从节点主配置文件
[root@redhat7_6 ~]# vim /etc/mongod2.conf
3). 启动单实例
[root@redhat7_6 ~]# /etc/init.d/mongodb mongod2 start
4). 备份当前节点所有 oplog 记录
- [root@redhat7_6 ~]# mongodump --port 27028 --db local --collection 'oplog.rs'
- port #指定端口
- db #指定数据库
- collection #指定集合
5). 更改 oplog 文件大小
- [root@redhat7_6 ~]# mongo --port 27028
- > use local
- > db.oplog.rs.drop() #删除 oplog 文件
- > db.runCommand({ create: "oplog.rs", capped: true, size: (2 * 1024 * 1024 * 1024)}) #重建文件, 指定 2048M 的空间
6). 暂时关闭服务
- > use admin
- > db.shutdownServer()
7). 修改从节点主配置文件
- [root@redhat7_6 ~]# vim /etc/mongod2.conf
- net:
- port: 27018 #约 29 行, 把端口改成 27018
- replication: #约 37 行, 打开复制选项
- replSetName: kgcrs #解开注释
- oplogSizeMB: 2048 #添加 oplog 日志文件大小 2048MB
8). 登录服务
- [root@redhat7_6 ~]# /etc/init.d/mongodb mongod2 start
- [root@redhat7_6 ~]# mongo --port 27018
- kgcrs:SECONDARY> rs.printReplicationInfo()
9). 进行主从切换
- [root@redhat7_6 ~]# mongo --port 27017
- kgcrs:PRIMARY> rs.freeze(30) #暂停 30 秒不参加选举
- kgcrs:PRIMARY> rs.stepDown(60,30) #告知主节点交出主节点位置, 然后维持从节点状态不少于 60 秒, 同时等待 30 秒以使主节点和从节点日志同步
- [root@redhat7_6 ~]# mongo --port 27018
五, 部署认证复制
[root@redhat7_6 ~]# mongo --port 27018
1, 创建用户
- kgcrs:PRIMARY> use admin
- kgcrs:PRIMARY> db.createUser({"user":"root","pwd":"123","roles":["root"]})
2, 修改主配置文件
- [root@redhat7_6 ~]# vim /etc/mongod1.conf
- security: #约 33 行, 开启认证功能
- keyFile: /usr/bin/kgcrskey1 #指定验证文件路径.!!! 注意实例 1 是 kgcrskey1 ; 实例 2 是 kgcrskey2; 实例 3 是 kgcrskey3
- clusterAuthMode: keyFile #指定验证模式, 秘钥文件验证
- [root@redhat7_6 ~]# vim /etc/mongod2.conf #依次第 2,3,4 实例都要添加上面句.!!! 注意验证文件路径要修改
- [root@redhat7_6 ~]# vim /etc/mongod3.conf
- [root@redhat7_6 ~]# vim /etc/mongod4.conf
3, 生成秘钥文件
- [root@redhat7_6 ~]# cd /usr/bin/
- [root@redhat7_6 bin]# echo "kgcrs key"> kgcrskey1
- [root@redhat7_6 bin]# echo "kgcrs key"> kgcrskey2
- [root@redhat7_6 bin]# echo "kgcrs key"> kgcrskey3
- [root@redhat7_6 bin]# echo "kgcrs key"> kgcrskey4
4, 更改目录权限
[root@redhat7_6 bin]# chmod 600 kgcrskey{1..4} #复制集对 keyFile 的权限有要求, 最多到 600
5, 重启实例
- [root@redhat7_6 ~]# /etc/init.d/mongodb mongod1 restart
- [root@redhat7_6 ~]# /etc/init.d/mongodb mongod2 restart
- [root@redhat7_6 ~]# /etc/init.d/mongodb mongod3 restart
- [root@redhat7_6 ~]# /etc/init.d/mongodb mongod4 restart
6, 访问主节点
[root@redhat7_6 ~]# mongo --port 27017
7, 验证访问
- kgcrs:PRIMARY> use admin
- kgcrs:PRIMARY> db.auth("root","123")
来源: http://www.linuxidc.com/Linux/2018-09/154125.htm