0

0

MongoDB如何实现读写分离 读写分离配置减轻主库压力

穿越時空

穿越時空

发布时间:2025-06-06 23:36:02

|

895人浏览过

|

来源于php中文网

原创

mongodb实现读写分离主要依赖于副本集配置。1. 配置副本集,通过主节点处理写操作并复制到多个从节点;2. 设置读偏好(如primary、secondary等)决定读操作分发策略;3. 使用写关注和读关注机制保证数据一致性;4. 监控复制延迟及节点状态以维护系统稳定性。不同节点类型(主节点、从节点、仲裁节点等)各司其职,支持灵活扩展与高可用性。

MongoDB如何实现读写分离 读写分离配置减轻主库压力

读写分离,简单来说,就是把数据库的读操作和写操作分摊到不同的数据库服务器上。这样,写操作集中在一个主库上,而读操作则分散到多个从库上,从而减轻主库的压力,提高整体的性能和可用性。MongoDB实现读写分离,主要通过配置副本集来实现。

解决方案

MongoDB的读写分离主要依赖于副本集(Replica Set)的配置。副本集由一个主节点(Primary)和多个从节点(Secondary)组成。所有写操作都必须先在主节点上执行,然后通过oplog复制到从节点。读操作则可以根据配置,分发到主节点或从节点。

配置副本集

首先,你需要搭建一个MongoDB副本集。这涉及到配置多个MongoDB实例,并将它们连接到一个副本集。每个实例都需要在配置文件中指定replSetName,确保它们属于同一个副本集。

# mongod.conf
replication:
  replSetName: myReplicaSet

net:
  bindIp: localhost,<其他节点IP>
  port: 27017

storage:
  dbPath: /data/db

启动各个MongoDB实例后,使用rs.initiate()命令初始化副本集。

// 在其中一个节点上执行
rs.initiate(
   {
      _id : "myReplicaSet",
      members: [
         { _id: 0, host: "localhost:27017" },
         { _id: 1, host: "localhost:27018" },
         { _id: 2, host: "localhost:27019" }
      ]
   }
)

配置读偏好

配置副本集后,就可以通过连接字符串或驱动程序的选项来指定读偏好(Read Preference)。读偏好决定了客户端从哪个节点读取数据。常见的读偏好包括:

  • primary: 只从主节点读取。这是默认的读偏好。
  • primaryPreferred: 优先从主节点读取,如果主节点不可用,则从从节点读取。
  • secondary: 只从从节点读取。
  • secondaryPreferred: 优先从从节点读取,如果从节点不可用,则从主节点读取。
  • nearest: 从网络延迟最低的节点读取,无论是主节点还是从节点。

例如,在MongoDB的Node.js驱动程序中,可以这样指定读偏好:

Difeye-敏捷的轻量级PHP框架
Difeye-敏捷的轻量级PHP框架

Difeye是一款超轻量级PHP框架,主要特点有: Difeye是一款超轻量级PHP框架,主要特点有: ◆数据库连接做自动主从读写分离配置,适合单机和分布式站点部署; ◆支持Smarty模板机制,可灵活配置第三方缓存组件; ◆完全分离页面和动作,仿C#页面加载自动执行Page_Load入口函数; ◆支持mysql,mongodb等第三方数据库模块,支持读写分离,分布式部署; ◆增加后台管理开发示例

下载
const { MongoClient } = require('mongodb');

const uri = "mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=myReplicaSet&readPreference=secondaryPreferred";

const client = new MongoClient(uri);

async function run() {
  try {
    await client.connect();
    const database = client.db("mydatabase");
    const collection = database.collection("mycollection");

    // 从从节点读取数据
    const result = await collection.find({}).toArray();
    console.log(result);

  } finally {
    await client.close();
  }
}
run().catch(console.dir);

监控和维护

读写分离配置完成后,还需要进行监控和维护,确保系统的稳定运行。需要关注主节点的负载、从节点的复制延迟、以及节点的可用性。可以使用MongoDB自带的监控工具,或者第三方监控工具,例如Prometheus和Grafana。

副本集成员类型有哪些?各自作用是什么?

MongoDB副本集不仅仅只有主节点和从节点两种类型。实际上,它还包括以下几种成员类型,每种成员都有其特定的作用:

  • Primary (主节点): 负责处理所有的写操作。同时,也处理读操作(除非客户端指定了其他的读偏好)。主节点通过心跳机制与副本集中的其他成员保持联系。如果主节点宕机,副本集会自动选举出一个新的主节点。
  • Secondary (从节点): 复制主节点上的数据。从节点可以处理读操作,从而分担主节点的压力。从节点还可以作为选举的候选者,参与主节点的选举。
  • Arbiter (仲裁节点): 不存储数据,只参与主节点的选举。仲裁节点的作用是帮助副本集在节点数量为偶数时,避免出现“脑裂”的情况。脑裂指的是,当网络分区导致副本集被分成两个或多个独立的部分时,每个部分都可能选出一个主节点,从而导致数据不一致。仲裁节点通过投票,帮助副本集选出一个唯一的主节点。
  • Hidden (隐藏节点): 不对外提供服务,不能被客户端直接访问。隐藏节点通常用于备份、数据分析等场景。隐藏节点也可以作为选举的候选者。
  • Delayed (延迟节点): 也是一种隐藏节点,但它复制的数据有一定的延迟。延迟节点可以用于从过去某个时间点恢复数据,或者用于审计。

不同的节点类型,可以根据实际需求进行配置。例如,对于读多写少的应用,可以增加从节点的数量,从而提高读性能。对于需要高可用性的应用,可以增加仲裁节点,从而避免脑裂。

如何选择合适的读偏好?

选择合适的读偏好,需要根据应用的具体需求进行权衡。不同的读偏好,在性能、一致性、可用性等方面各有优劣。

  • primary: 一致性最高,但性能最差。因为所有的读操作都必须在主节点上执行。适用于对数据一致性要求非常高的场景,例如金融交易。
  • primaryPreferred: 兼顾了一致性和可用性。优先从主节点读取,如果主节点不可用,则从从节点读取。适用于对数据一致性要求较高,但允许一定程度的延迟的场景。
  • secondary: 性能最好,但一致性最差。因为所有的读操作都在从节点上执行,而从节点的数据可能存在延迟。适用于对数据一致性要求不高,但对性能要求非常高的场景,例如日志分析。
  • secondaryPreferred: 兼顾了性能和可用性。优先从从节点读取,如果从节点不可用,则从主节点读取。适用于对数据一致性要求不高,但对可用性要求较高的场景。
  • nearest: 性能最好,但一致性最差。从网络延迟最低的节点读取,无论是主节点还是从节点。适用于对性能要求非常高,且节点分布在多个地理位置的场景。

在实际应用中,可以根据不同的业务场景,选择不同的读偏好。例如,对于需要实时显示数据的页面,可以选择primaryprimaryPreferred。对于不需要实时显示数据的页面,可以选择secondarysecondaryPreferred

读写分离后,如何保证数据一致性?

读写分离虽然能提升性能,但也会带来数据一致性的问题。由于数据从主节点复制到从节点需要时间,因此从节点上的数据可能存在延迟。为了保证数据一致性,可以采取以下措施:

  • 选择合适的读偏好: 如前所述,不同的读偏好,在一致性方面各有优劣。选择合适的读偏好,可以根据应用的具体需求进行权衡。
  • 监控复制延迟: 监控从节点的复制延迟,可以了解数据的同步情况。如果复制延迟过高,需要及时处理,例如优化网络、调整配置等。
  • 使用w: 写关注: 写关注(Write Concern)是指,写操作需要被复制到多少个节点后,才算成功。通过设置w参数,可以控制写操作的可靠性。例如,w: majority表示写操作需要被复制到大多数节点后,才算成功。
  • 使用readConcern: "majority"读关注: 读关注(Read Concern)是指,读操作需要读取到多少个节点上的数据,才算有效。通过设置readConcern参数,可以控制读操作的一致性。readConcern: "majority"表示读操作需要读取到大多数节点上的数据,确保读取到的数据是最新的。
// 使用写关注和读关注
const { MongoClient } = require('mongodb');

const uri = "mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=myReplicaSet";

const client = new MongoClient(uri);

async function run() {
  try {
    await client.connect();
    const database = client.db("mydatabase");
    const collection = database.collection("mycollection");

    // 插入数据,并设置写关注
    await collection.insertOne({ name: "test" }, { w: "majority" });

    // 读取数据,并设置读关注
    const result = await collection.find({}).readConcern("majority").toArray();
    console.log(result);

  } finally {
    await client.close();
  }
}
run().catch(console.dir);

通过以上措施,可以有效地保证读写分离后的数据一致性。当然,在实际应用中,还需要根据具体的业务场景,进行灵活的调整和优化。

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

258

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

209

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1468

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

620

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

550

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

545

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

165

2025.07.29

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

81

2025.08.07

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MongoDB 教程
MongoDB 教程

共17课时 | 2.2万人学习

黑马云课堂mongodb实操视频教程
黑马云课堂mongodb实操视频教程

共11课时 | 3.1万人学习

MongoDB 教程
MongoDB 教程

共42课时 | 25.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号