MST
星途 面试题库

面试题:MongoDB副本集读写分离基础实现

请阐述在MongoDB副本集中实现读写分离的基本步骤,包括配置副本集以及应用程序如何配置才能实现读写分离?
50.1万 热度难度
数据库MongoDB

知识考点

AI 面试

面试题答案

一键面试

配置副本集

  1. 初始化节点
    • 准备多个MongoDB实例,例如三个节点,分别作为主节点(primary)、从节点(secondary)和仲裁节点(arbiter,可选)。每个实例需要配置不同的端口和数据存储路径。
    • 启动每个MongoDB实例。例如,使用以下命令启动(假设数据目录为/data/db1,端口为27017):
    mongod --port 27017 --dbpath /data/db1
    
  2. 初始化副本集
    • 连接到其中一个MongoDB实例,通常是主节点。例如:
    mongo --port 27017
    
    • 在Mongo shell中,运行以下命令初始化副本集:
    rs.initiate({
        _id: "myReplSet",
        members: [
            { _id: 0, host: "localhost:27017" },
            { _id: 1, host: "localhost:27018" },
            { _id: 2, host: "localhost:27019", arbiterOnly: true }
        ]
    });
    
    • 这里_id是副本集的名称,members数组包含了副本集成员的信息,arbiterOnly: true表示该节点为仲裁节点,不存储数据,只参与选举。
  3. 验证副本集状态
    • 在Mongo shell中运行rs.status()命令,确保副本集状态正常,主节点和从节点状态正确显示。

应用程序配置实现读写分离

  1. 驱动程序选择
    • 根据应用程序使用的编程语言,选择合适的MongoDB驱动程序,如Node.js的mongodb驱动,Java的mongodb - driver - sync等。
  2. 配置读偏好
    • Node.js示例
      const { MongoClient } = require('mongodb');
      const uri = "mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=myReplSet&readPreference=secondaryPreferred";
      const client = new MongoClient(uri);
      async function run() {
          try {
              await client.connect();
              const database = client.db('test');
              const collection = database.collection('users');
              const result = await collection.find({}).toArray();
              console.log(result);
          } finally {
              await client.close();
          }
      }
      run().catch(console.dir);
      
      • 这里通过在连接字符串中设置readPreference=secondaryPreferred,表示优先从从节点读取数据,如果从节点不可用,则从主节点读取。
    • Java示例
      import com.mongodb.client.MongoClients;
      import com.mongodb.client.MongoClient;
      import com.mongodb.client.MongoCollection;
      import com.mongodb.client.MongoDatabase;
      import org.bson.Document;
      import com.mongodb.ReadPreference;
      public class MongoReadWriteSeparation {
          public static void main(String[] args) {
              String uri = "mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=myReplSet";
              MongoClient mongoClient = MongoClients.create(uri);
              mongoClient.getReadPreference(ReadPreference.secondaryPreferred());
              MongoDatabase database = mongoClient.getDatabase("test");
              MongoCollection<Document> collection = database.getCollection("users");
              collection.find().forEach(doc -> System.out.println(doc));
              mongoClient.close();
          }
      }
      
      • 通过mongoClient.getReadPreference(ReadPreference.secondaryPreferred());设置读偏好为优先从从节点读取。