適用場景:生產環境搭建高可用 MongoDB 副本集,確保數據冗餘與自動故障轉移
MongoDB 版本:7.0.28(社區版)
操作系統:CentOS 7.9
架構:1 主(Primary) + 2 從(Secondary),共 3 個數據承載節點(P-S-S)
文件系統:XFS(推薦 XFS)
一、為什麼需要副本集?
MongoDB 副本集(Replica Set)是實現 高可用性 和 數據冗餘 的核心機制:
- 自動故障轉移:主節點宕機後,從節點自動選舉新主,服務不中斷;
- 數據多副本:每個從節點保存完整數據副本,防止單點數據丟失;
- 讀寫分離(可選):從節點可承擔部分讀請求,提升系統吞吐。
![8fdce0d1ddd44c91a2a2063beb5c582c]()
推薦配置:3 個數據節點(P-S-S),主節點負責所有寫入操作,從節點則從主節點複製數據,提供讀操作的負載均衡,兩個從節點都可以在選舉中成為主節點。
二、環境準備
1. 服務器信息
| 主機名 | IP 地址 | 角色 |
|---|---|---|
| mongo-node1 | 10.0.0.10 | Primary |
| mongo-node2 | 10.0.0.11 | Secondary |
| mongo-node3 | 10.0.0.12 | Secondary |
所有操作需在 三台主機上分別執行(除非特別説明)。
2. 系統初始化(所有節點)
# 配置 yum 源
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.huaweicloud.com/repository/conf/CentOS-7-anon.repo
yum clean all && yum makecache
# 安裝基礎工具
yum install -y telnet bind-utils net-tools vim-enhanced lrzsz unzip gcc gcc-c++ ntpdate vim sysstat nmap
# 時間同步
ntpdate -s ntp1.aliyun.com
# 關閉 SELinux
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
# 關閉防火牆與 postfix
systemctl stop firewalld && systemctl disable firewalld
systemctl stop postfix && systemctl disable postfix
# 設置主機名(每台不同)
hostnamectl set-hostname mongo-node1 # node2 改為 mongo-node2,以此類推
# 配置 hosts
cat >> 'EOF' << /etc/hosts
10.0.0.10 mongo-node1
10.0.0.11 mongo-node2
10.0.0.12 mongo-node3
EOF
三、系統優化與用户配置
# 設置最大文件與最大進程打開數 cat >> /etc/security/limits.conf << EOF mongodb soft nproc 65535 mongodb hard nproc 65535 mongodb soft nofile 81920 mongodb hard nofile 81920 EOF # 關閉透明大頁,並使設置開機自啓 echo "never" > /sys/kernel/mm/transparent_hugepage/enabled echo "never" > /sys/kernel/mm/transparent_hugepage/defrag chmod +x /etc/rc.d/rc.local vim /etc/rc.d/rc.local 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 /etc/sysctl.conf vm.swappiness=0 net.core.somaxconn = 65535 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_max_tw_buckets = 65535 net.ipv4.tcp_max_syn_backlog = 65535 fs.file-max = 1000000 fs.inotify.max_user_watches = 65536 vm.max_map_count=262144 # 創建 mongodb 用户與目錄 useradd -r -s /sbin/nologin mongodb mkdir -p /app/data/mongodb/{db,logs,conf} chown -R mongodb:mongodb /app/data
四、安裝 MongoDB 7.0
# 安裝依賴
yum install -y libcurl openssl xz-libs
# 下載並解壓 MongoDB
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-7.0.28.tgz
tar -xzf mongodb-linux-x86_64-rhel70-7.0.28.tgz -C /app/
mv /app/mongodb-linux-x86_64-rhel70-7.0.28 /app/mongodb
chown -R mongodb:mongodb /app/mongodb
# 配置環境變量
cat >> /etc/profile << EOF
export MONGODB_HOME=/app/mongodb
export PATH=$MONGODB_HOME/bin:$PATH
EOF
source /etc/profile
# 配置文件(所有節點內容一致)
cat >> /app/data/mongodb/conf/mongod.conf <<EOF
storage:
dbPath: /app/data/mongodb/db
wiredTiger:
engineConfig:
cacheSizeGB: 5 # 根據內存調整
systemLog:
destination: file
logAppend: true
path: /app/data/mongodb/logs/mongod.log
logRotate: rename
net:
port: 27017
bindIp: 0.0.0.0
processManagement:
fork: false # systemd 管理時不 fork
replication:
replSetName: rs0
operationProfiling:
slowOpThresholdMs: 3000 # 記錄慢操作的閾值,單位為毫秒
mode: slowOp
#security: # 認證
# authorization: enabled
# keyFile: /app/data/mongodb/conf/mongo-keyfile
EOF
# 添加權限
chown mongodb:mongodb /app/data/mongodb/conf/mongod.conf
# 生成密鑰文件(僅在主節點執行,然後複製到 node2、node3 的相同路徑,注意權限)
openssl rand -base64 753 >/app/data/mongodb/conf/mongo-keyfile
chmod 600 /app/data/mongodb/conf/mongo-keyfile
chown mongodb:mongodb /app/data/mongodb/conf/mongo-keyfile
# 配置 systemd 服務(所有節點)
cat >> /etc/systemd/system/mongodb.service <<EOF
[Unit]
Description=MongoDB Database Server (Binary Install)
Documentation=https://docs.mongodb.org/manual
After=network.target
Wants=network.target
[Service]
Type=simple
User=mongodb
Group=mongodb
ExecStart=/app/mongodb/bin/mongod -f /app/data/mongodb/conf/mongod.conf
Restart=on-failure
RestartSec=10
TimeoutSec=300
LimitNOFILE=64000
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now mongodb
systemctl status mongodb # 檢查是否啓動成功
出處:https://www.cnblogs.com/liucx/
五、初始化副本集
1. 安裝 mongosh(僅需在一台節點操作)
wget https://repo.mongodb.org/yum/redhat/7/mongodb-org/7.0/x86_64/RPMS/mongodb-mongosh-2.2.15.x86_64.rpm rpm -ivh mongodb-mongosh-2.2.15.x86_64.rpm
2. 連接並初始化副本集(先不啓用認證)
注意:首次初始化時,mongod.conf 中 暫時註釋掉 security 部分,否則無法無認證連接。
mongosh mongo-node1:27017 // 在 mongosh 中執行 rs.initiate({ _id: "rs0", members: [ { _id: 0, host: "mongo-node1:27017" }, { _id: 1, host: "mongo-node2:27017" }, { _id: 2, host: "mongo-node3-:27017" } ] }) ## 成功後提示:{ ok: 1 },shell 提示符變為 rs0:PRIMARY>
3. 驗證副本集狀態
rs.conf() // 查看配置 rs.status() // 查看各節點狀態(應顯示 1 Primary + 2 Secondary)
4. 創建管理員賬號
use admin db.createUser({ user: "root", pwd: "T6WBVZBAdY1ddflzq", // 請務必使用強密碼並妥善保管 roles: [{ role: "root", db: "admin" }] })
六、啓用認證並重啓服務
1. 取消註釋 security 配置
確保 /app/data/mongodb/conf/mongod.conf 中包含:
security:
authorization: enabled
keyFile: /app/data/mongodb/conf/mongo-keyfile
2. 滾動重啓 MongoDB 服務
為避免集羣腦裂,按以下順序操作:
# 1. 先停止兩個從節點 ssh mongo-node2 "systemctl stop mongodb" ssh mongo-node3 "systemctl stop mongodb" # 2. 再停止主節點 systemctl stop mongodb # 3. 先啓動主節點 systemctl start mongodb # 4. 再啓動兩個從節點 ssh mongo-node2 "systemctl start mongodb" ssh mongo-node3 "systemctl start mongodb"
七、驗證副本集與數據同步
1. 使用認證方式連接
mongosh "mongodb://mongo-node1:27017" -u root -p 'T6WBVZBAdY1ddflzq' --authenticationDatabase admin
2. 查看副本集狀態
rs.conf() // 查看配置 rs.status() // 查看各節點狀態(應顯示 1 Primary + 2 Secondary)
3. 插入測試數據(驗證同步)
use test db.tt.insertOne({ articleid: "100003", content: "今天天氣真好,陽光明媚", userid: "1001", nickname: "liu" })
4. 查詢數據(可在任意節點驗證)
db.tt.find().pretty()
從節點默認不允許讀取(出於一致性考慮),如需讀從,需顯式開啓:
// 在從節點執行 rs.slaveOk(true) db.tt.find()
附:連接字符串示例(應用端使用)
mongodb://root:T6WBVZBAdY1ddflzq@10.0.0.10:27017,10.0.0.10:27017,10.0.0.10:27017/?replicaSet=rs0&authSource=admin&readPreference=primary
注意事項:
認證與權限:啓用副本集時,務必配置安全性(如 必須設置為 600權限 和 配置用户權限)。
網絡延遲:使用 rs.status() 中的 pingMs 字段監控節點間延遲,建議 < 10ms。確保節點之間的網絡連接良好,以減少數據同步延遲。
節點數量:推薦奇數個數據承載節點(如 3、5),避免“腦裂。最小高可用配置為 3 節點(P-S-S);若成本受限,可採用 2 數據節點 + 1 仲裁節點(Arbiter),但仲裁節點不存儲數據,。
數據一致性:默認情況下,所有讀寫操作都在 Primary 上執行,保證強一致性。
參考:
Mongodb生產説明:https://www.mongodb.com/zh-cn/docs/manual/administration/production-notes/
Mongodb副本集説明:https://www.mongodb.com/zh-cn/docs/v7.0/core/replica-set-architecture-three-members/
Mongodb部署説明:https://www.mongodb.com/zh-cn/docs/v7.0/tutorial/deploy-replica-set/
