写在前面的话
对于生产环境而言,除非是非常不重要的业务,且该业务允许我们出现一定时间的停机,我们一般才会使用单节点,且该单节点必须要有完善的备份手段。
RS 复制集
我们这里采取一主两从的方式搭建复制集,在 mongodb 中,其采用 Raft 监控投票机制。如果主库发生宕机,复制集内部会重新选举主库,并通知到客户端,应用就会连接到新的主库。当然,对于应用端应该如何连接,这不是我们该思考的问题,代码里面会有专门针对这种方式的连接方法。
1. 本次准备了 3 台虚拟机搭建该集群,初始配置方法都一样:
# 关闭大页内存机制 if test -f /sys/kernel/mm/transparent_hugepage/enabled; then echo never > /sys/kernel/mm/transparent_hugepage/enabled fi if test -f /sys/kernel/mm/transparent_hugepage/defrag; then echo never > /sys/kernel/mm/transparent_hugepage/defrag fi # 查看设置结果 cat /sys/kernel/mm/transparent_hugepage/enabled cat /sys/kernel/mm/transparent_hugepage/defrag # 初始化目录 mkdir -p /data/{backup,data,logs,packages,services} mkdir -p /data/packages/mongodb # 将安装包上传到:/data/packages/mongodb 下 # 解压 cd /data/packages/mongodb tar -zxf mongodb-linux-x86_64-rhel70-4.2.1.tgz mv mongodb-linux-x86_64-rhel70-4.2.1 /data/services/mongodb # 配置基础目录 cd /data/services/mongodb rm -f LICENSE-Community.txt MPL-2 README THIRD-PARTY-NOTICES THIRD-PARTY-NOTICES.gotools mkdir data logs conf
2. 都添加配置文件:
cat > /data/services/mongodb/conf/mongo.conf << EOF # 系统日志相关 systemLog: destination: file path: "/data/services/mongodb/logs/mongodb.log" logAppend: true # 数据存储相关 storage: journal: enabled: true dbPath: "/data/services/mongodb/data" directoryPerDB: true wiredTiger: engineConfig: cacheSizeGB: 1 directoryForIndexes: true collectionConfig: blockCompressor: zlib indexConfig: prefixCompression: true # 进程相关 processManagement: fork: true pidFilePath: "/data/services/mongodb/logs/mongodb.pid" # 网络配置相关 net: bindIp: 192.168.200.101,127.0.0.1 port: 27000 # 复制集配置相关 replication: oplogSizeMB: 2048 replSetName: my_mongo_repl EOF
注意红色配置!
3. 配置 systemd:
cat > /etc/systemd/system/mongod-27000.service <<EOF [Unit] Description=mongodb-27000 After=network.target remote-fs.target nss-lookup.target [Service] User=root Type=forking ExecStart=/data/services/mongodb/bin/mongod --config /data/services/mongodb/conf/mongo.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/data/services/mongodb/bin/mongod --config /data/services/mongodb/conf/mongo.conf --shutdown PrivateTmp=true [Install] WantedBy=multi-user.target EOF
启动所有节点:
systemctl start mongod-27000.service
4. 登录任意节点配置:
/data/services/mongodb/bin/mongo --port 27000 admin
配置:
# 添加集合 config = {_id: "my_mongo_repl", members:[ {_id: 0, host: '192.168.200.101:27000'}, {_id: 1, host: '192.168.200.102:27000'}, {_id: 2, host: '192.168.200.103:27000'} ]} # 初始化集群 rs.initiate(config)
执行效果:
成功以后提示符会变!
5. 查看复制集状态:
rs.status()
主要结果如下:
红色部分为主要我们需要了解的,一个是节点的身份,是主还是从,另外一个就是当前的复制状态,在 MySQL 中我们使用指针或者 GTID 表示当前复制到哪里了。而在 mongodb 中则使用时间戳加第几个操作表示当前执行到哪里了。
此外还可以使用:
# 查看当前是否主节点 rs.isMaster() # 查看配置 rs.conf()
当前这是最基础的 RS 复制集架构,还有其它的设计方案!
特殊节点
在 mongodb 中,从节点还存在三种特殊的节点:
arbiter:主要用于监控,这意味着我们只需要一主一从一arbiter,由于该节点不用同步数据,所以可以使用性能差点的机器。
hidden:隐藏节点,不参与选主,不对外服务。
delay:延时节点,由于延时,也不参与选主和提供服务,一般和 hidden 联合使用。
配置 arbiter 节点:
两种情况,一种是集群搭建的时候就初始化为 arbiter 节点,只需要把定义的 config 增加配置即可:
config = {_id: "my_mongo_repl", members:[ {_id: 0, host: '192.168.200.101:27000'}, {_id: 1, host: '192.168.200.102:27000'}, {_id: 2, host: '192.168.200.103:27000', "arbiterOnly": true} ]}
然后再初始化即可!
另外一种情况就是集群已经存在了,但是就是普通的主从环境,就需要修改其中一个节点为 arbiter 节点:
1. 先删除该节点:
# 删除从节点 rs.remove("192.168.200.103:27000") # 增加 arbiter 节点 rs.addArb("192.168.200.103:27000")
如果只是增加普通从节点只需要使用 rs.add() 即可!
2. 查看集群情况:
rs.status()
结果如图:
记得检查该节点是否启动,如果没用启动会报错:Error connecting to 192.168.200.103:27000 :: caused by :: Connection refused
配置 hidden delay 节点:
首先我们还是一主两从节点,选取一个从节点作为 hidden delay 节点:
# 拷贝原有配置 cfg = rs.conf() # 修改member中角标为2的参数,注意不是id为2 # 设置权重,让它不参与选主 cfg.members[2].priority=0 # 是否隐藏 cfg.members[2].hidden=true # 延时时间 cfg.members[2].slaveDelay=120 # 重载新配置 rs.reconfig(cfg) # 查看新配置结果 rs.conf()
结果如下:
当然取消只需要反过来将配置改回默认即可!