1. MongoDB副本集架构扩展概述

MongoDB副本集架构扩展是应对业务增长和性能需求的重要手段,通过水平扩展和垂直扩展来提升系统的处理能力和可用性。副本集扩展包括添加新的副本集成员、配置读写分离、优化数据分布等策略。本文将详细介绍MongoDB副本集架构扩展的各种策略、部署方法、运维管理技巧以及在企业级应用中的最佳实践。

1.1 副本集扩展的核心价值

  1. 性能提升: 通过扩展提升系统的处理能力
  2. 高可用性: 增加副本数量提升系统可用性
  3. 读写分离: 通过扩展实现读写分离提升性能
  4. 负载均衡: 分散读写负载提升整体性能
  5. 容灾能力: 增强系统的容灾和恢复能力

1.2 副本集扩展策略

  • 水平扩展: 添加新的副本集成员
  • 垂直扩展: 提升现有节点的硬件配置
  • 读写分离: 配置专门的读节点
  • 地理分布: 跨数据中心的副本集扩展
  • 混合扩展: 水平扩展和垂直扩展的结合

2. 副本集水平扩展

2.1 水平扩展部署脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
#!/bin/bash
# MongoDB副本集水平扩展部署脚本
# @author 运维实战

# 配置变量
REPLICA_SET_NAME="rs0"
MONGO_PORT=27017
NEW_MEMBER_PORT=27020
DATA_DIR="/data/mongodb"
LOG_DIR="/var/log/mongodb"
CONFIG_DIR="/etc/mongodb"
ADMIN_USER="admin"
ADMIN_PASS="admin123"

# 创建新成员目录
create_new_member_directories() {
echo "创建新副本集成员目录..."

# 创建新成员数据目录
mkdir -p $DATA_DIR/secondary3
chown -R mongodb:mongodb $DATA_DIR/secondary3

# 创建新成员日志目录
mkdir -p $LOG_DIR
chown -R mongodb:mongodb $LOG_DIR

echo "新成员目录创建完成"
}

# 生成新成员配置文件
generate_new_member_config() {
echo "生成新副本集成员配置文件..."

# 新成员配置文件
cat > $CONFIG_DIR/mongod-secondary3.conf << EOF
# MongoDB新从节点配置文件
# @author 运维实战

# 存储配置
storage:
dbPath: $DATA_DIR/secondary3
journal:
enabled: true
commitIntervalMs: 100
wiredTiger:
engineConfig:
cacheSizeGB: 2
journalCompressor: snappy
directoryForIndexes: true
collectionConfig:
blockCompressor: snappy
indexConfig:
prefixCompression: true

# 网络配置
net:
port: $NEW_MEMBER_PORT
bindIp: 0.0.0.0
maxIncomingConnections: 1000
compression:
compressors: snappy,zstd

# 日志配置
systemLog:
destination: file
path: $LOG_DIR/mongod-secondary3.log
logAppend: true
logRotate: reopen
verbosity: 1
component:
accessControl:
verbosity: 1
command:
verbosity: 1

# 进程管理
processManagement:
fork: true
pidFilePath: $DATA_DIR/secondary3/mongod.pid
timeZoneInfo: /usr/share/zoneinfo

# 副本集配置
replication:
replSetName: $REPLICA_SET_NAME
oplogSizeMB: 1024

# 安全配置
security:
authorization: enabled
keyFile: $CONFIG_DIR/keyfile

# 性能优化
operationProfiling:
slowOpThresholdMs: 100
mode: slowOp

# 监控配置
setParameter:
enableLocalhostAuthBypass: false
logLevel: 1

# 新成员特殊配置
replication:
replSetName: $REPLICA_SET_NAME
oplogSizeMB: 1024
# 初始同步配置
initialSyncSourceReadPreference: "nearest"
# 同步延迟配置
secondaryDelaySecs: 0
EOF

echo "新成员配置文件生成完成"
}

# 启动新成员服务
start_new_member_service() {
echo "启动新副本集成员服务..."

# 启动新成员
mongod --config $CONFIG_DIR/mongod-secondary3.conf
sleep 5

echo "新成员服务启动完成"
}

# 添加新成员到副本集
add_new_member_to_replica_set() {
echo "添加新成员到副本集..."

mongo --port $MONGO_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 添加新成员到副本集
// @author 运维实战

use admin;

// 检查当前副本集状态
print("当前副本集状态:");
rs.status();

// 添加新成员
print("添加新成员: localhost:$NEW_MEMBER_PORT");
rs.add({
host: "localhost:$NEW_MEMBER_PORT",
priority: 1,
tags: { "dc": "secondary", "role": "secondary", "type": "new" }
});

// 等待新成员同步
print("等待新成员同步...");
var maxWaitTime = 300; // 最大等待5分钟
var waitTime = 0;
while (waitTime < maxWaitTime) {
var status = rs.status();
var newMember = null;

// 查找新成员
for (var i = 0; i < status.members.length; i++) {
if (status.members[i].name === "localhost:$NEW_MEMBER_PORT") {
newMember = status.members[i];
break;
}
}

if (newMember && newMember.state === 2) {
print("新成员同步完成,状态: " + newMember.stateStr);
break;
}

sleep(1000);
waitTime++;
print("等待同步中... (" + waitTime + "s)");
}

// 显示更新后的副本集状态
print("更新后的副本集状态:");
rs.status();
EOF

echo "新成员添加完成"
}

# 配置新成员优化
configure_new_member_optimization() {
echo "配置新成员优化..."

mongo --port $NEW_MEMBER_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 配置新成员优化
// @author 运维实战

use admin;

// 设置读取偏好
db.getMongo().setReadPref("secondary");

// 配置连接池
db.adminCommand({
setParameter: 1,
maxConns: 1000,
connPoolMaxShardedConnsPerHost: 200,
connPoolMaxConnsPerHost: 200
});

// 配置缓存
db.adminCommand({
setParameter: 1,
wiredTigerConcurrentReadTransactions: 128,
wiredTigerConcurrentWriteTransactions: 128
});

print("新成员优化配置完成");
EOF

echo "新成员优化配置完成"
}

# 验证扩展结果
verify_extension_result() {
echo "验证副本集扩展结果..."

mongo --port $MONGO_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 验证副本集扩展结果
// @author 运维实战

use admin;

// 检查副本集状态
print("=== 副本集扩展验证 ===");
var status = rs.status();
print("副本集成员数量: " + status.members.length);

// 检查每个成员状态
for (var i = 0; i < status.members.length; i++) {
var member = status.members[i];
print("成员 " + (i + 1) + ": " + member.name + " 状态: " + member.stateStr + " 优先级: " + member.priority);
}

// 检查数据同步状态
print("\n=== 数据同步状态 ===");
rs.printSlaveReplicationInfo();

// 检查复制延迟
print("\n=== 复制延迟检查 ===");
var members = status.members;
for (var i = 0; i < members.length; i++) {
var member = members[i];
if (member.state === 2) { // 从节点
var lag = member.optimeDate - member.lastHeartbeat;
print("从节点 " + member.name + " 复制延迟: " + lag + " ms");
}
}

// 检查oplog状态
print("\n=== Oplog状态检查 ===");
use local;
var oplogStats = db.oplog.rs.stats();
print("Oplog大小: " + oplogStats.size + " bytes");
print("Oplog使用率: " + (oplogStats.storageSize / oplogStats.maxSize * 100).toFixed(2) + "%");

print("\n副本集扩展验证完成");
EOF

echo "副本集扩展验证完成"
}

# 主函数
main() {
echo "开始MongoDB副本集水平扩展..."

create_new_member_directories
generate_new_member_config
start_new_member_service
add_new_member_to_replica_set
configure_new_member_optimization
verify_extension_result

echo "MongoDB副本集水平扩展完成!"
echo "新成员: localhost:$NEW_MEMBER_PORT"
echo "副本集成员总数: 4个"
}

# 执行主函数
main "$@"

2.2 多数据中心扩展脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
#!/bin/bash
# MongoDB副本集多数据中心扩展脚本
# @author 运维实战

# 配置变量
REPLICA_SET_NAME="rs0"
PRIMARY_DC="dc1"
SECONDARY_DC="dc2"
MONGO_PORT=27017
REMOTE_MEMBER_PORT=27021
DATA_DIR="/data/mongodb"
LOG_DIR="/var/log/mongodb"
CONFIG_DIR="/etc/mongodb"
ADMIN_USER="admin"
ADMIN_PASS="admin123"

# 创建远程数据中心成员目录
create_remote_member_directories() {
echo "创建远程数据中心成员目录..."

# 创建远程成员数据目录
mkdir -p $DATA_DIR/remote-secondary
chown -R mongodb:mongodb $DATA_DIR/remote-secondary

# 创建远程成员日志目录
mkdir -p $LOG_DIR
chown -R mongodb:mongodb $LOG_DIR

echo "远程成员目录创建完成"
}

# 生成远程成员配置文件
generate_remote_member_config() {
echo "生成远程数据中心成员配置文件..."

# 远程成员配置文件
cat > $CONFIG_DIR/mongod-remote-secondary.conf << EOF
# MongoDB远程数据中心成员配置文件
# @author 运维实战

# 存储配置
storage:
dbPath: $DATA_DIR/remote-secondary
journal:
enabled: true
commitIntervalMs: 100
wiredTiger:
engineConfig:
cacheSizeGB: 2
journalCompressor: snappy
directoryForIndexes: true
collectionConfig:
blockCompressor: snappy
indexConfig:
prefixCompression: true

# 网络配置
net:
port: $REMOTE_MEMBER_PORT
bindIp: 0.0.0.0
maxIncomingConnections: 1000
compression:
compressors: snappy,zstd

# 日志配置
systemLog:
destination: file
path: $LOG_DIR/mongod-remote-secondary.log
logAppend: true
logRotate: reopen
verbosity: 1
component:
accessControl:
verbosity: 1
command:
verbosity: 1

# 进程管理
processManagement:
fork: true
pidFilePath: $DATA_DIR/remote-secondary/mongod.pid
timeZoneInfo: /usr/share/zoneinfo

# 副本集配置
replication:
replSetName: $REPLICA_SET_NAME
oplogSizeMB: 1024

# 安全配置
security:
authorization: enabled
keyFile: $CONFIG_DIR/keyfile

# 性能优化
operationProfiling:
slowOpThresholdMs: 100
mode: slowOp

# 监控配置
setParameter:
enableLocalhostAuthBypass: false
logLevel: 1

# 远程成员特殊配置
replication:
replSetName: $REPLICA_SET_NAME
oplogSizeMB: 1024
# 网络延迟优化
heartbeatIntervalMillis: 5000
electionTimeoutMillis: 20000
# 同步优化
initialSyncSourceReadPreference: "nearest"
secondaryDelaySecs: 0
EOF

echo "远程成员配置文件生成完成"
}

# 启动远程成员服务
start_remote_member_service() {
echo "启动远程数据中心成员服务..."

# 启动远程成员
mongod --config $CONFIG_DIR/mongod-remote-secondary.conf
sleep 5

echo "远程成员服务启动完成"
}

# 添加远程成员到副本集
add_remote_member_to_replica_set() {
local remote_host=$1
local remote_port=$2

echo "添加远程数据中心成员到副本集: $remote_host:$remote_port..."

mongo --port $MONGO_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 添加远程数据中心成员到副本集
// @author 运维实战

use admin;

// 检查当前副本集状态
print("当前副本集状态:");
rs.status();

// 添加远程成员
print("添加远程成员: $remote_host:$remote_port");
rs.add({
host: "$remote_host:$remote_port",
priority: 0.5,
tags: { "dc": "$SECONDARY_DC", "role": "secondary", "type": "remote" }
});

// 等待远程成员同步
print("等待远程成员同步...");
var maxWaitTime = 600; // 最大等待10分钟
var waitTime = 0;
while (waitTime < maxWaitTime) {
var status = rs.status();
var remoteMember = null;

// 查找远程成员
for (var i = 0; i < status.members.length; i++) {
if (status.members[i].name === "$remote_host:$remote_port") {
remoteMember = status.members[i];
break;
}
}

if (remoteMember && remoteMember.state === 2) {
print("远程成员同步完成,状态: " + remoteMember.stateStr);
break;
}

sleep(1000);
waitTime++;
if (waitTime % 30 === 0) {
print("等待同步中... (" + waitTime + "s)");
}
}

// 显示更新后的副本集状态
print("更新后的副本集状态:");
rs.status();
EOF

echo "远程成员添加完成"
}

# 配置数据中心标签
configure_datacenter_tags() {
echo "配置数据中心标签..."

mongo --port $MONGO_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 配置数据中心标签
// @author 运维实战

use admin;

// 获取当前配置
var config = rs.conf();

// 配置数据中心标签
config.members[0].tags = { "dc": "$PRIMARY_DC", "role": "primary" };
config.members[1].tags = { "dc": "$PRIMARY_DC", "role": "secondary" };
config.members[2].tags = { "dc": "$PRIMARY_DC", "role": "secondary" };
config.members[3].tags = { "dc": "$SECONDARY_DC", "role": "secondary" };

// 应用配置
rs.reconfig(config);

print("数据中心标签配置完成");
EOF

echo "数据中心标签配置完成"
}

# 配置读写分离
configure_read_write_separation() {
echo "配置读写分离..."

mongo --port $MONGO_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 配置读写分离
// @author 运维实战

use admin;

// 配置读取偏好
db.getMongo().setReadPref("secondaryPreferred");

// 配置写入关注
db.getMongo().setWriteConcern({
w: "majority",
j: true,
wtimeout: 5000
});

// 配置读取关注
db.getMongo().setReadConcern("majority");

print("读写分离配置完成");
EOF

echo "读写分离配置完成"
}

# 验证多数据中心扩展
verify_multidatacenter_extension() {
echo "验证多数据中心扩展结果..."

mongo --port $MONGO_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 验证多数据中心扩展结果
// @author 运维实战

use admin;

// 检查副本集状态
print("=== 多数据中心扩展验证 ===");
var status = rs.status();
print("副本集成员数量: " + status.members.length);

// 按数据中心分组显示成员
var primaryDCMembers = [];
var secondaryDCMembers = [];

for (var i = 0; i < status.members.length; i++) {
var member = status.members[i];
var tags = member.tags || {};
var dc = tags.dc || "unknown";

if (dc === "$PRIMARY_DC") {
primaryDCMembers.push(member);
} else if (dc === "$SECONDARY_DC") {
secondaryDCMembers.push(member);
}
}

print("\n=== 主数据中心成员 ($PRIMARY_DC) ===");
for (var i = 0; i < primaryDCMembers.length; i++) {
var member = primaryDCMembers[i];
print("成员: " + member.name + " 状态: " + member.stateStr + " 优先级: " + member.priority);
}

print("\n=== 次数据中心成员 ($SECONDARY_DC) ===");
for (var i = 0; i < secondaryDCMembers.length; i++) {
var member = secondaryDCMembers[i];
print("成员: " + member.name + " 状态: " + member.stateStr + " 优先级: " + member.priority);
}

// 检查网络延迟
print("\n=== 网络延迟检查 ===");
for (var i = 0; i < status.members.length; i++) {
var member = status.members[i];
if (member.state === 2) { // 从节点
var lag = member.optimeDate - member.lastHeartbeat;
var tags = member.tags || {};
var dc = tags.dc || "unknown";
print("数据中心 " + dc + " 成员 " + member.name + " 复制延迟: " + lag + " ms");
}
}

print("\n多数据中心扩展验证完成");
EOF

echo "多数据中心扩展验证完成"
}

# 主函数
main() {
local remote_host=${1:-"remote-dc2.example.com"}
local remote_port=${2:-$REMOTE_MEMBER_PORT}

echo "开始MongoDB副本集多数据中心扩展..."

create_remote_member_directories
generate_remote_member_config
start_remote_member_service
add_remote_member_to_replica_set $remote_host $remote_port
configure_datacenter_tags
configure_read_write_separation
verify_multidatacenter_extension

echo "MongoDB副本集多数据中心扩展完成!"
echo "远程成员: $remote_host:$remote_port"
echo "主数据中心: $PRIMARY_DC"
echo "次数据中心: $SECONDARY_DC"
}

# 执行主函数
main "$@"

3. 副本集垂直扩展

3.1 垂直扩展配置脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#!/bin/bash
# MongoDB副本集垂直扩展配置脚本
# @author 运维实战

# 配置变量
MONGO_PORT=27017
ADMIN_USER="admin"
ADMIN_PASS="admin123"
CONFIG_DIR="/etc/mongodb"

# 优化内存配置
optimize_memory_config() {
echo "优化内存配置..."

mongo --port $MONGO_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 优化内存配置
// @author 运维实战

use admin;

// 获取当前内存配置
var serverStatus = db.serverStatus();
print("当前内存使用情况:");
print(" 物理内存: " + serverStatus.mem.resident + " MB");
print(" 虚拟内存: " + serverStatus.mem.virtual + " MB");
print(" 映射内存: " + serverStatus.mem.mapped + " MB");

// 配置WiredTiger缓存
db.adminCommand({
setParameter: 1,
wiredTigerEngineRuntimeConfig: "cache_size=4GB,eviction=(threads_min=4,threads_max=8)"
});

// 配置连接池
db.adminCommand({
setParameter: 1,
maxConns: 2000,
connPoolMaxShardedConnsPerHost: 500,
connPoolMaxConnsPerHost: 500
});

// 配置并发事务
db.adminCommand({
setParameter: 1,
wiredTigerConcurrentReadTransactions: 256,
wiredTigerConcurrentWriteTransactions: 256
});

print("内存配置优化完成");
EOF

echo "内存配置优化完成"
}

# 优化存储配置
optimize_storage_config() {
echo "优化存储配置..."

mongo --port $MONGO_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 优化存储配置
// @author 运维实战

use admin;

// 配置WiredTiger存储引擎
db.adminCommand({
setParameter: 1,
wiredTigerEngineRuntimeConfig: "cache_size=4GB,eviction=(threads_min=4,threads_max=8),checkpoint=(wait=60,log_size=2GB)"
});

// 配置压缩
db.adminCommand({
setParameter: 1,
wiredTigerCollectionBlockCompressor: "snappy",
wiredTigerIndexPrefixCompression: true
});

// 配置日志
db.adminCommand({
setParameter: 1,
wiredTigerLogCompressor: "snappy",
wiredTigerLogFileMax: "10GB"
});

print("存储配置优化完成");
EOF

echo "存储配置优化完成"
}

# 优化网络配置
optimize_network_config() {
echo "优化网络配置..."

mongo --port $MONGO_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 优化网络配置
// @author 运维实战

use admin;

// 配置网络参数
db.adminCommand({
setParameter: 1,
maxIncomingConnections: 2000,
connPoolMaxShardedConnsPerHost: 500,
connPoolMaxConnsPerHost: 500
});

// 配置压缩
db.adminCommand({
setParameter: 1,
networkMessageCompressors: "snappy,zstd"
});

// 配置超时
db.adminCommand({
setParameter: 1,
socketTimeoutMS: 30000,
connectTimeoutMS: 10000
});

print("网络配置优化完成");
EOF

echo "网络配置优化完成"
}

# 优化副本集配置
optimize_replica_set_config() {
echo "优化副本集配置..."

mongo --port $MONGO_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 优化副本集配置
// @author 运维实战

use admin;

// 获取当前配置
var config = rs.conf();

// 优化副本集设置
config.settings.heartbeatIntervalMillis = 2000;
config.settings.electionTimeoutMillis = 10000;
config.settings.catchUpTimeoutMillis = 2000;
config.settings.catchUpTakeoverDelayMillis = 30000;

// 应用配置
rs.reconfig(config);

// 配置oplog大小
db.adminCommand({
setParameter: 1,
oplogSize: 2048
});

print("副本集配置优化完成");
EOF

echo "副本集配置优化完成"
}

# 优化索引配置
optimize_index_config() {
echo "优化索引配置..."

mongo --port $MONGO_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 优化索引配置
// @author 运维实战

use admin;

// 配置索引构建
db.adminCommand({
setParameter: 1,
maxIndexBuildMemoryUsageMegabytes: 1024
});

// 配置后台索引构建
db.adminCommand({
setParameter: 1,
backgroundIndexBuildRetry: true
});

print("索引配置优化完成");
EOF

echo "索引配置优化完成"
}

# 验证垂直扩展效果
verify_vertical_extension() {
echo "验证垂直扩展效果..."

mongo --port $MONGO_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 验证垂直扩展效果
// @author 运维实战

use admin;

// 获取服务器状态
var serverStatus = db.serverStatus();
print("=== 垂直扩展效果验证 ===");

// 内存使用情况
print("内存使用情况:");
print(" 物理内存: " + serverStatus.mem.resident + " MB");
print(" 虚拟内存: " + serverStatus.mem.virtual + " MB");
print(" 映射内存: " + serverStatus.mem.mapped + " MB");

// 连接情况
print("\n连接情况:");
print(" 当前连接数: " + serverStatus.connections.current);
print(" 可用连接数: " + serverStatus.connections.available);
print(" 总连接数: " + serverStatus.connections.totalCreated);

// 网络情况
print("\n网络情况:");
print(" 字节输入: " + serverStatus.network.bytesIn);
print(" 字节输出: " + serverStatus.network.bytesOut);
print(" 请求数: " + serverStatus.network.numRequests);

// 存储情况
print("\n存储情况:");
print(" 数据大小: " + serverStatus.storageSize);
print(" 索引大小: " + serverStatus.indexSize);
print(" 总大小: " + (serverStatus.storageSize + serverStatus.indexSize));

// 副本集情况
print("\n副本集情况:");
var status = rs.status();
print(" 成员数量: " + status.members.length);
print(" 主节点: " + status.primary);

print("\n垂直扩展效果验证完成");
EOF

echo "垂直扩展效果验证完成"
}

# 主函数
main() {
echo "开始MongoDB副本集垂直扩展..."

optimize_memory_config
optimize_storage_config
optimize_network_config
optimize_replica_set_config
optimize_index_config
verify_vertical_extension

echo "MongoDB副本集垂直扩展完成!"
}

# 执行主函数
main "$@"

4. 副本集扩展监控

4.1 扩展监控脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
#!/bin/bash
# MongoDB副本集扩展监控脚本
# @author 运维实战

# 配置变量
MONGO_PORT=27017
ADMIN_USER="admin"
ADMIN_PASS="admin123"
LOG_FILE="/var/log/mongodb/extension_monitor.log"
ALERT_EMAIL="admin@example.com"

# 记录日志
log_message() {
local message=$1
echo "$(date '+%Y-%m-%d %H:%M:%S') - $message" >> $LOG_FILE
}

# 监控副本集扩展状态
monitor_replica_set_extension() {
echo "监控副本集扩展状态..."

mongo --port $MONGO_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 监控副本集扩展状态
// @author 运维实战

use admin;

// 获取副本集状态
var status = rs.status();
var members = status.members;

print("=== 副本集扩展状态监控 ===");
print("副本集成员数量: " + members.length);

// 检查每个成员状态
for (var i = 0; i < members.length; i++) {
var member = members[i];
var state = member.state;
var name = member.name;
var tags = member.tags || {};
var dc = tags.dc || "unknown";
var role = tags.role || "unknown";

print("成员 " + (i + 1) + ": " + name);
print(" 状态: " + member.stateStr);
print(" 优先级: " + member.priority);
print(" 数据中心: " + dc);
print(" 角色: " + role);

// 检查复制延迟
if (state === 2) { // 从节点
var lag = member.optimeDate - member.lastHeartbeat;
print(" 复制延迟: " + lag + " ms");

if (lag > 10000) {
print(" 警告: 复制延迟过高");
}
}

// 检查网络延迟
var lastHeartbeat = member.lastHeartbeat;
var now = new Date();
var networkLag = now - lastHeartbeat;
print(" 网络延迟: " + networkLag + " ms");

if (networkLag > 5000) {
print(" 警告: 网络延迟过高");
}
}

// 检查数据分布
print("\n=== 数据分布检查 ===");
var primaryDCMembers = [];
var secondaryDCMembers = [];

for (var i = 0; i < members.length; i++) {
var member = members[i];
var tags = member.tags || {};
var dc = tags.dc || "unknown";

if (dc === "dc1") {
primaryDCMembers.push(member);
} else if (dc === "dc2") {
secondaryDCMembers.push(member);
}
}

print("主数据中心成员数量: " + primaryDCMembers.length);
print("次数据中心成员数量: " + secondaryDCMembers.length);

// 检查负载均衡
print("\n=== 负载均衡检查 ===");
var activeMembers = 0;
for (var i = 0; i < members.length; i++) {
if (members[i].state === 1 || members[i].state === 2) {
activeMembers++;
}
}

print("活跃成员数量: " + activeMembers);
print("负载分布: " + (100 / activeMembers).toFixed(2) + "% per member");
EOF

log_message "副本集扩展状态监控完成"
}

# 监控性能指标
monitor_performance_metrics() {
echo "监控性能指标..."

mongo --port $MONGO_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 监控性能指标
// @author 运维实战

use admin;

// 获取服务器状态
var serverStatus = db.serverStatus();

print("=== 性能指标监控 ===");

// 内存使用情况
print("内存使用情况:");
print(" 物理内存: " + serverStatus.mem.resident + " MB");
print(" 虚拟内存: " + serverStatus.mem.virtual + " MB");
print(" 映射内存: " + serverStatus.mem.mapped + " MB");

// 连接情况
print("\n连接情况:");
print(" 当前连接数: " + serverStatus.connections.current);
print(" 可用连接数: " + serverStatus.connections.available);
print(" 总连接数: " + serverStatus.connections.totalCreated);

// 网络情况
print("\n网络情况:");
print(" 字节输入: " + serverStatus.network.bytesIn);
print(" 字节输出: " + serverStatus.network.bytesOut);
print(" 请求数: " + serverStatus.network.numRequests);

// 操作情况
print("\n操作情况:");
print(" 插入操作: " + serverStatus.opcounters.insert);
print(" 查询操作: " + serverStatus.opcounters.query);
print(" 更新操作: " + serverStatus.opcounters.update);
print(" 删除操作: " + serverStatus.opcounters.delete);

// 存储情况
print("\n存储情况:");
print(" 数据大小: " + serverStatus.storageSize);
print(" 索引大小: " + serverStatus.indexSize);
print(" 总大小: " + (serverStatus.storageSize + serverStatus.indexSize));

// 检查性能阈值
var connections = serverStatus.connections;
if (connections.current > 1000) {
print("警告: 连接数过高: " + connections.current);
}

var memory = serverStatus.mem;
if (memory.resident > 8000) {
print("警告: 内存使用过高: " + memory.resident + " MB");
}
EOF

log_message "性能指标监控完成"
}

# 监控扩展效果
monitor_extension_effectiveness() {
echo "监控扩展效果..."

mongo --port $MONGO_PORT -u $ADMIN_USER -p $ADMIN_PASS --authenticationDatabase admin << EOF
// 监控扩展效果
// @author 运维实战

use admin;

// 获取副本集状态
var status = rs.status();
var members = status.members;

print("=== 扩展效果监控 ===");

// 计算扩展效果指标
var totalMembers = members.length;
var activeMembers = 0;
var primaryDCMembers = 0;
var secondaryDCMembers = 0;

for (var i = 0; i < members.length; i++) {
var member = members[i];
var tags = member.tags || {};
var dc = tags.dc || "unknown";

if (member.state === 1 || member.state === 2) {
activeMembers++;
}

if (dc === "dc1") {
primaryDCMembers++;
} else if (dc === "dc2") {
secondaryDCMembers++;
}
}

print("扩展效果指标:");
print(" 总成员数: " + totalMembers);
print(" 活跃成员数: " + activeMembers);
print(" 主数据中心成员数: " + primaryDCMembers);
print(" 次数据中心成员数: " + secondaryDCMembers);

// 计算可用性
var availability = (activeMembers / totalMembers * 100).toFixed(2);
print(" 系统可用性: " + availability + "%");

// 计算负载分布
var loadDistribution = (100 / activeMembers).toFixed(2);
print(" 负载分布: " + loadDistribution + "% per member");

// 检查扩展效果
if (availability < 80) {
print("警告: 系统可用性过低: " + availability + "%");
}

if (activeMembers < 3) {
print("警告: 活跃成员数过少: " + activeMembers);
}

print("扩展效果监控完成");
EOF

log_message "扩展效果监控完成"
}

# 发送告警
send_alert() {
local message=$1
echo "发送告警: $message"

# 发送邮件告警
echo "$message" | mail -s "MongoDB副本集扩展告警" $ALERT_EMAIL

log_message "告警发送完成: $message"
}

# 生成监控报告
generate_monitor_report() {
echo "生成监控报告..."

local report_file="/var/log/mongodb/extension_monitor_report_$(date +%Y%m%d).txt"

cat > $report_file << EOF
MongoDB副本集扩展监控报告
生成时间: $(date)
========================================

1. 副本集扩展状态监控
$(monitor_replica_set_extension)

2. 性能指标监控
$(monitor_performance_metrics)

3. 扩展效果监控
$(monitor_extension_effectiveness)

========================================
EOF

echo "监控报告生成完成: $report_file"
log_message "监控报告生成完成: $report_file"
}

# 主函数
main() {
echo "开始MongoDB副本集扩展监控..."

monitor_replica_set_extension
monitor_performance_metrics
monitor_extension_effectiveness
generate_monitor_report

echo "MongoDB副本集扩展监控完成"
}

# 执行主函数
main "$@"

5. 总结

5.1 MongoDB副本集扩展最佳实践

  1. 合理规划扩展: 根据业务需求选择合适的扩展策略
  2. 渐进式扩展: 采用渐进式扩展避免系统不稳定
  3. 监控扩展效果: 建立完善的监控机制跟踪扩展效果
  4. 负载均衡: 合理配置负载均衡提升整体性能
  5. 容灾设计: 考虑容灾和故障恢复能力

5.2 扩展策略建议

  • 水平扩展: 适用于需要提升可用性和处理能力的场景
  • 垂直扩展: 适用于需要提升单节点性能的场景
  • 混合扩展: 结合水平扩展和垂直扩展的优势
  • 地理分布: 适用于需要跨地域部署的场景
  • 读写分离: 适用于读写负载不均衡的场景

5.3 运维管理要点

  • 扩展规划: 根据业务增长规划扩展策略
  • 性能监控: 持续监控扩展后的性能表现
  • 容量管理: 合理管理扩展后的系统容量
  • 故障处理: 建立扩展后的故障处理流程
  • 成本控制: 平衡扩展效果和成本投入

通过本文的MongoDB副本集架构扩展运维实战指南,您可以掌握MongoDB副本集扩展的各种策略、部署方法、监控技巧和运维管理要点,构建高可用、高性能、可扩展的MongoDB副本集系统!