mongodb的高可用部署
一.什么是 MongoDB ?
1.1介绍
MongoDB 是一个文档型数据库,数据以类似 JSON 的文档形式存储。
MongoDB 的设计理念是为了应对大数据量、高性能和灵活性需求。
MongoDB使用集合(Collections)来组织文档(Documents),每个文档都是由键值对组成的。
数据库(Database):存储数据的容器,类似于关系型数据库中的数据库。
集合(Collection):数据库中的一个集合,类似于关系型数据库中的表。
文档(Document):集合中的一个数据记录,类似于关系型数据库中的行(row),以 BSON 格式存储。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成,文档类似于 JSON 对象,字段值可以包含其他文档,数组及文档数组:
1.2主要特点
文档导向的存储:MongoDB 是一个面向文档的数据库,它以 JSON-like 的格式存储数据,使得数据结构更加灵活和丰富。
索引优化查询:MongoDB 允许用户为文档中的任意属性创建索引,例如 FirstName 和 Address,从而提高查询效率和排序性能。
数据镜像与扩展性:通过本地或网络创建数据的副本,MongoDB 实现了强大的数据冗余和扩展能力。
水平扩展与分片:面对增加的负载,MongoDB 可以通过分片技术将数据分布到计算机网络中的其他节点上,实现水平扩展。
强大的查询语言:MongoDB 使用 JSON 格式的查询语法,支持复杂的查询表达式,包括对内嵌对象和数组的查询。
数据更新:利用 update() 命令,MongoDB 能够替换整个文档或更新指定的数据字段,提供了灵活的数据更新方式。
MapReduce 批量处理:MongoDB 的 MapReduce 功能专为大规模数据处理和聚合操作设计,通过 Map 函数的 emit(key, value)调用和 Reduce 函数的逻辑处理,实现高效的数据汇总。
MapReduce 脚本编写:Map 和 Reduce 函数使用 JavaScript 编写,可以通过 db.runCommand 或 mapreduce 命令在 MongoDB 中执行。
GridFS 大文件存储:GridFS 是 MongoDB 内置的功能,用于存储和检索大于 BSON 文档大小限制的文件,如图片和视频。
服务端脚本执行:MongoDB 允许在服务端执行 JavaScript 脚本,提供了直接在服务端执行或存储函数定义以供后续调用的能力。
多语言支持:MongoDB 提供了对多种编程语言的支持,包括但不限于 RUBY、PYTHON、JAVA、C++、PHP 和 C#。
安装简单:MongoDB 的安装过程简单直观,便于用户快速部署和使用。
二.项目目的
2.1 完成mongoDB 高可用部署;
2.2 验证数据同步;
2.3 验证故障转移;
三.项目内容
3.1 拓扑图
节点角色规划(最小化生产部署)
节点IP | 角色 | 推荐配置 | 关键要求 |
10.1.1.151 | Primary | 4核CPU+16GB内存+SSD | 稳定低延迟网络 |
10.1.1.152 | Secondary | 4核CPU+8GB内存+SSD | 与主节点同机房 |
10.1.1.153 | Arbiter | 1核CPU+1GB内存 | 仅参与选举 |
注意:如果没有arbiter ,故障转移需要手动干预。
3.2 配置步骤
1)mongodb 的部署过程
#安装依赖yum -y install libcurl openssl#上传安装包#安装mongodbyum -y install https://repo.mongodb.org/yum/redhat/9/mongodb-org/8.0/x86_64/RPMS/mongodb-org-server-8.0.9-1.el9.x86_64.rpm#若上传了安装包,安装mongodbyum -y install /root/mongodb-org-server-8.0.9-1.el9.x86_64.rpm #启动服务systemctl start mongod.service && systemctl enable mongod#下载工具yum -y install net-tools#查看进程netstat -naptlu |grep mongod#查看当前mongodb 的版本mongod --version
2)部署mongodb的后台管理工具mongosh
#上传安装包#安装mongoshyum -y install https://downloads.mongodb.com/compass/mongodb-mongosh-2.5.1.x86_64.rpm#若上传了安装包,安装mongodbyum -y install /root/mongodb-mongosh-2.5.1.x86_64.rpm #安装内容rpm -ql mongodb-mongosh#查看当前版本mongosh 版本mongosh --version
3)实例操作:定义用户,启动身份验证配置;验证用户登录;
以下是一个完整的示例操作流程:第一步:创建管理员用户(无认证状态下)#启动 MongoDB Shell 并连接到服务器:mongosh#查看数据库show dbs# 在MongoDB shell中执行use admindb.createUser({user: "admin",pwd: "YourStrongPassword123!", # 请修改为强密码roles: ["root"]})第二步:验证管理员权限# 使用管理员登录mongosh -u admin -p YourStrongPassword123! --authenticationDatabase admin# 在shell中验证use adminshow users # 应能看到admin用户第三步:启用身份验证并重启 MongoDB 实例#编辑 mongod.conf 文件,添加以下内容:vi /etc/mongod.confsecurity:authorization: "enabled"#重启 MongoDB 服务:systemctl restart mongod# 使用管理员登录mongosh -u admin -p YourStrongPassword123! --authenticationDatabase admin
配置完后,克隆两台虚拟机,修改IP地址,一共三台虚拟机,一个主节点,一个从节点,一个仲裁节点
4)系统基础配置(所有节点)
# 1. 关闭SELinux(需重启) sudo sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config sudo setenforce 0# 2. 禁用防火墙 sudo systemctl stop firewalld sudo systemctl disable firewalld# 3. 禁用透明大页(THP) echo "never" | sudo tee /sys/kernel/mm/transparent_hugepage/enabled echo "never" | sudo tee /sys/kernel/mm/transparent_hugepage/defrag#4.持久胡配置(THP) # 创建配置文件 echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' | sudo tee /etc/rc.d/rc.local echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' | sudo tee -a /etc/rc.d/rc.local sudo chmod +x /etc/rc.d/rc.local
5)MongoDB配置文件优化(/etc/mongod.conf)【所有节点】
vim /etc/mongod.conf# mongod.conf# for documentation of all options, see: # http://docs.mongodb.org/manual/reference/configuration-options/# where to write logging data. systemLog:destination: filelogAppend: truepath: /var/log/mongodb/mongod.loglogRotate: reopen # 日志轮转不重启服务 # Where and how to store data. storage:dbPath: /var/lib/mongowiredTiger:engineConfig:cacheSizeGB: 4 # 设为可用内存的50%-60% # how the process runs processManagement:timeZoneInfo: /usr/share/zoneinfo# network interfaces net:port: 27017bindIp: 0.0.0.0 # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.#security: security:keyFile: /etc/mongodb.keyfile # 集群认证文件authorization: enabled # 启用访问控制 #operationProfiling:#replication: replication:replSetName: "rs0" # 集群唯一标识oplogSizeMB: 2048 # 根据写入量调整(默认5%磁盘空间)#sharding:## Enterprise-Only Options#auditLog:
#上传到另外两个节点上 scp /etc/mongod.conf root@10.1.1.152:/etc/ scp /etc/mongod.conf root@10.1.1.153:/etc/
6)密钥文件生成与分发
# 生成密钥文件(权限严格设置为400)【所有节点】
sudo openssl rand -base64 756 > /etc/mongodb.keyfile
sudo chmod 400 /etc/mongodb.keyfile
sudo chown mongod:mongod /etc/mongodb.keyfile#重启mongodb和查看状态【所有节点】
systemctl restart mongod
systemctl status mongod
# 分发到所有节点(保持权限一致)【Primary节点执行】
scp /etc/mongodb.keyfile root@10.1.1.152:/etc/
scp /etc/mongodb.keyfile root@10.1.1.153:/etc/
#重启mongodb和查看状态【Secondary和Arbiter节点执行】
systemctl restart mongod
systemctl status mongod#查看进程【所有节点】
netstat -naptlu |grep mongod
7)副本集初始化(Primary节点执行)
#连接MongoDB Shell mongosh -u admin -p YourStrongPassword123! --authenticationDatabase admin#初始化副本集 rs.initiate({ _id: "rs0",members: [{ _id: 0, host: "10.1.1.135:27017", priority: 2 },{ _id: 1, host: "10.1.1.136:27017", priority: 1 },{ _id: 2, host: "10.1.1.137:27017", arbiterOnly: true }],settings: {heartbeatTimeoutSecs: 10, // 心跳超时时间electionTimeoutMillis: 10000 // 选举超时时间} })
#检查状态(等待所有节点变为"health": 1)
rs.status()
3.3 验证步骤
1)数据同步验证
#在Primary插入测试数据
for(let i=0; i<1000; i++) {
db.sync_test.insert({ ts: new Date(), data: "Record_" + i })
}
db.products.insertOne({ name: "Laptop", price: 999 })
#在Secondary验证数据(需先启用读权限)
#连接MongoDB Shell
mongosh -u admin -p YourStrongPassword123! --authenticationDatabase admin
rs.secondaryOk() # 启用从节点读权限
db.sync_test.count() // 应返回1000
db.products.find() # 应返回插入的文档
2)数据监控同步状态
# 查看Oplog时间窗口
rs.printReplicationInfo()
# 检查各节点同步延迟
#在主节点执行
db.adminCommand({ replSetGetStatus: 1 }).members.forEach(m => {
const lag = new Date() - new Date(m.optimeDate);
print(`${m.name} 延迟: ${lag}ms`);
});
3)故障转移测试
#查看主节点
rs.isMaster()
# 模拟Primary宕机
# 在10.1.1.151执行
sudo systemctl stop mongod
#观察新主节点选举(等待30秒后检查)
#在10.1.1.152执行
rs.isMaster()
#观察故障转移
# 在Secondary节点查看副本集状态
rs.status() # 检查新Primary是否选举成功(stateStr: "PRIMARY")
恢复原主节点
# 启动原Primary节点服务
sudo systemctl start mongod
# 检查其角色是否变为Secondary
rs.status() # 原Primary的stateStr应为"SECONDARY"
四.项目结论
1)高可用架构对比
模式 | 原理 | 适用场景 | 节点要求 |
副本集(Replica Set) | 自动选举 + OpLog同步 | 中小规模数据(≤TB级) | ≥3节点 |
分片集群 | 水平分片 + 分布式查询 | 超大规模数据(>TB级) | ≥9节点 |
混合架构 | 副本集分片 + 配置服务器 | 高并发读写+高可用 | ≥12节点 |
2)副本集高可用关键机制
自动故障转移:通过心跳检测(默认2秒)触发选举,10-30秒内完成主节点切换。
数据同步:基于Oplog的异步复制,默认保留24小时操作日志(可通过oplogSizeMB调整)。
读写分离:通过连接字符串参数readPreference控制读流量分布。
自动故障转移:主节点(Primary)宕机时,剩余节点通过心跳检测触发选举,秒级切换新主节点。
数据同步:基于Oplog(操作日志)实现主从异步复制,默认容忍约10秒数据延迟。
读写分离:Secondary节点可处理读请求,分担主节点负载。
3) 最佳实践建议
节点规划:
主节点部署在高性能存储(NVMe SSD)
从节点与主节点同机房部署(延迟 <1ms)
仲裁节点独立部署(避免脑裂)
性能优化:
设置合理的cacheSizeGB(总内存的50%-60%)
监控Oplog窗口(rs.printReplicationInfo())
禁用NUMA架构(通过内核参数numa=off)
安全加固:
启用TLS加密(tls.mode=requireTLS)
定期轮换密钥文件(keyFile)
配置审计日志(auditLog)
备份策略:
每日全量备份(mongodump)
增量备份(基于Oplog)
异地灾备(通过mongorestore恢复)
4)常见问题处理
问题现象 | 解决方案 |
初始化失败(NodeNotFound) | 检查防火墙/SELinux设置,验证密钥文件一致性 |
同步延迟过高 | 优化网络带宽,调整oplogSizeMB |
选举失败 | 检查时间同步(NTP),验证节点权重配置 |
总结:
本次实验成功验证了MongoDB副本集的高可用特性,实现了故障自动转移(RTO<30秒)和数据零丢失(RPO=0)。通过读写分离配置,系统吞吐量提升约40%。建议生产环境部署时,结合监控工具(如Prometheus+Grafana)实现实时告警,并定期进行灾难恢复演练。