面试题答案
一键面试- 数据迁移:
- 首先,确保新搭建的备用服务器已正确安装并配置好MongoDB,且其网络、存储等资源能够承载迁移的数据量。
- 在MongoDB分片集群中,使用
moveChunk
命令来迁移数据块。例如,假设要迁移的分片名为shard0001
,目标备用服务器地址为new_server:port
:- 连接到MongoDB集群的配置服务器:
mongo configsvr1:27019,configsvr2:27019,configsvr3:27019/admin
- 执行如下命令迁移数据块,将
ns
替换为要迁移的数据库和集合名,min
和max
定义要迁移的数据范围(可以根据实际的分片键来确定):db.adminCommand({moveChunk: "ns", find: {shardKeyField: {$gte: min, $lte: max}}, to: "new_server:port"});
- 可以使用
listChunks
命令来监控迁移进度:db.getSiblingDB("config").chunks.find({ns: "ns"}).sort({lastmod: -1});
- 连接到MongoDB集群的配置服务器:
- 集群配置更新:
- 数据迁移完成后,需要更新集群配置。连接到MongoDB集群的配置服务器。
- 使用
removeShard
命令从集群中移除原主分片服务器:db.adminCommand({removeShard: "original_shard_server:port"});
- 使用
addShard
命令将新服务器添加为分片,例如:db.adminCommand({addShard: "new_server:port"});
- 在完成上述操作后,更新分片的主从关系。通过调整副本集配置来实现,假设新服务器和原主分片服务器都在同一个副本集中:
- 连接到副本集的主节点:
mongo new_server:port
- 获取当前副本集配置:
cfg = rs.conf();
- 调整配置中成员的优先级,将新服务器的优先级设为较高值(如1),原主分片服务器优先级设为较低值(如0):
for (var i = 0; i < cfg.members.length; i++) { if (cfg.members[i].host === "new_server:port") { cfg.members[i].priority = 1; } else if (cfg.members[i].host === "original_shard_server:port") { cfg.members[i].priority = 0; } }
- 应用新的副本集配置:
rs.reconfig(cfg);
- 连接到副本集的主节点:
- 确保业务最小化中断:
- 数据迁移阶段:
- 选择业务低峰期进行数据迁移,减少对正常业务的影响。
- 采用逐步迁移数据块的方式,而不是一次性迁移所有数据,避免瞬间网络和磁盘I/O压力过大影响业务。在迁移每个数据块前,可以先暂停对该数据块相关数据的写入操作(可通过业务逻辑控制,如暂时将写请求重定向到缓存),迁移完成后再恢复写入。
- 集群配置更新阶段:
- 在更新集群配置前,通过MongoDB的读偏好(read preference)设置,将应用程序的读请求暂时切换到其他分片或副本集成员,减少对即将调整的分片的读压力。
- 在调整副本集配置时,先执行
rs.stepDown()
命令使原主分片服务器主动让出主节点地位,让新服务器平稳成为主节点,避免主节点切换时可能出现的短暂不可用。在完成配置更新后,将应用程序的读写请求重新切换回正常路径。
- 数据迁移阶段: