阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 复制集(Replica Set)架构

复制集(Replica Set)架构

作者:陈川 阅读数:60256人阅读 分类: MongoDB

复制集(Replica Set)架构的基本概念

MongoDB的复制集是一组维护相同数据集的mongod进程,提供数据冗余和高可用性。一个复制集包含多个数据承载节点和一个可选的仲裁节点,其中数据承载节点分为主节点(Primary)和多个从节点(Secondary)。主节点接收所有写操作,从节点通过复制主节点的操作日志(oplog)来保持数据同步。

复制集的最小推荐配置包含三个成员:一个主节点和两个从节点。这种配置可以确保在主节点不可用时,系统能够自动选举出新的主节点,实现故障自动转移。复制集还支持最多50个成员,但只有7个成员可以参与投票。

// 连接复制集的示例代码
const { MongoClient } = require('mongodb');
const uri = "mongodb://host1:port1,host2:port2,host3:port3/?replicaSet=myReplicaSet";
const client = new MongoClient(uri);

async function run() {
  try {
    await client.connect();
    const database = client.db("sampleDB");
    const collection = database.collection("sampleCollection");
    // 执行操作...
  } finally {
    await client.close();
  }
}
run().catch(console.dir);

复制集成员角色与类型

复制集中的节点可以扮演不同角色,每种角色有特定功能。主节点是唯一接收写操作的成员,所有从节点都会复制主节点的数据变更。从节点又分为几种类型:普通从节点、隐藏节点(Hidden)、延迟节点(Delayed)和投票节点(Arbiter)。

隐藏节点不参与选举,通常用于专用报告或备份等场景。延迟节点会故意保持与主节点的数据延迟,用于防止人为错误导致的数据丢失。仲裁节点不存储数据,仅参与选举投票,帮助在偶数成员情况下打破平局。

// 配置复制集成员的示例
rs.initiate({
  _id: "myReplicaSet",
  members: [
    { _id: 0, host: "mongodb1:27017", priority: 2 },
    { _id: 1, host: "mongodb2:27017", priority: 1 },
    { _id: 2, host: "mongodb3:27017", arbiterOnly: true }
  ]
})

复制集的选举机制

MongoDB使用Raft一致性算法变体来实现复制集选举。当主节点不可达时,符合条件的从节点会发起选举成为新的主节点。选举成功需要获得大多数投票成员的支持,这里的"大多数"指的是超过半数。

选举触发条件包括:主节点不可达、复制集初始化、添加新节点或配置变更等。节点优先级(priority)影响选举结果,优先级高的节点更可能成为主节点。节点必须满足以下条件才能参与选举:与大多数成员保持连接、具有最新数据、优先级大于0。

// 查看复制集状态的命令
rs.status()
// 输出示例
{
  "set": "myReplicaSet",
  "date": ISODate("2023-05-01T10:00:00Z"),
  "myState": 1,
  "members": [
    {
      "_id": 0,
      "name": "mongodb1:27017",
      "health": 1,
      "state": 1,
      "stateStr": "PRIMARY",
      "uptime": 1000,
      "optime": { "ts": Timestamp(1682928000, 1), "t": 1 },
      "optimeDate": ISODate("2023-05-01T00:00:00Z"),
      "lastHeartbeat": ISODate("2023-05-01T10:00:00Z"),
      "pingMs": 10
    },
    // 其他成员信息...
  ]
}

数据同步与oplog机制

复制集通过oplog(操作日志)实现数据同步。oplog是一个有上限的集合,记录所有修改数据的操作。主节点将写操作记录到自己的oplog中,从节点异步复制并应用这些操作。

oplog大小很重要,太小的oplog可能导致从节点无法及时同步而需要完全重新同步。默认情况下,oplog大小取决于存储引擎和磁盘空间:WiredTiger引擎通常分配5%的可用空间,最小1GB,最大50GB。

// 查看oplog状态的命令
use local
db.oplog.rs.find().limit(1).sort({$natural:-1}).pretty()
// 输出示例
{
  "ts": Timestamp(1682928000, 1),
  "t": 1,
  "h": NumberLong("1234567890123456789"),
  "v": 2,
  "op": "i",
  "ns": "test.users",
  "o": {
    "_id": ObjectId("645a1b2e3c4d5e6f78901234"),
    "name": "John Doe",
    "email": "john@example.com"
  }
}

读写关注与一致性保证

MongoDB提供不同级别的读写关注(Read Concern/Write Concern)来控制数据一致性和持久性。写关注决定写操作何时被认为是成功的,读关注决定读取操作返回的数据版本。

常见的写关注级别包括:w:1(默认,主节点确认)、w:majority(大多数节点确认)、w:"all"(所有节点确认)。读关注级别包括:local(默认,读取节点最新数据)、available(分片集群专用)、majority(读取已写入大多数节点的数据)、linearizable(线性一致性读取)。

// 使用写关注的示例
db.products.insertOne(
  { item: "envelope", qty: 100, type: "Clasp" },
  { writeConcern: { w: "majority", wtimeout: 5000 } }
)

// 使用读关注的示例
db.products.find({ item: "envelope" }).readConcern("majority")

复制集的部署与维护

部署复制集需要考虑硬件配置、网络拓扑和地理位置分布。生产环境建议将成员部署在不同机架或可用区,防止单点故障。维护操作包括添加/删除成员、重新配置优先级、强制重新选举等。

监控复制集健康状态很重要,关键指标包括:复制延迟、oplog窗口、成员状态和心跳延迟。MongoDB提供多种工具监控复制集,如mongostat、mongotop和Cloud Manager等。

// 添加新成员的示例
rs.add("mongodb4:27017")

// 移除成员的示例
rs.remove("mongodb4:27017")

// 配置成员优先级的示例
rs.reconfig({
  _id: "myReplicaSet",
  version: 2,
  members: [
    { _id: 0, host: "mongodb1:27017", priority: 3 },
    { _id: 1, host: "mongodb2:27017", priority: 2 },
    { _id: 2, host: "mongodb3:27017", priority: 1 }
  ]
})

故障处理与恢复策略

复制集可能遇到各种故障场景,如网络分区、脑裂情况、主节点宕机等。理解故障检测机制很重要:成员每2秒发送一次心跳,如果10秒内未收到响应则认为不可达。

常见问题解决方法包括:强制重新配置复制集、手动干预选举、处理回滚情况等。回滚发生在原主节点恢复时,如果它包含未复制到大多数节点的写操作,这些操作会被回滚并保存到回滚目录。

// 强制重新配置复制集(谨慎使用)
rs.reconfig(config, {force: true})

// 手动触发选举(在主节点上运行)
rs.stepDown(300) // 300秒内不参与选举

// 查看回滚数据的命令
db.getSiblingDB("admin").aggregate([
  { $currentOp: {} },
  { $match: { "operationType": "command", "command.rollback": 1 } }
])

复制集与分片集群的关系

复制集是MongoDB分片集群的基础组件。在分片集群中,每个分片通常是一个复制集,配置服务器也是复制集。这种架构结合了水平扩展(分片)和高可用性(复制集)的优势。

分片集群中的查询路由(mongos)会自动处理复制集成员变化,应用开发者通常不需要关心底层拓扑变化。但理解这种关系有助于更好地设计应用和排查问题。

// 连接分片集群的示例
const uri = "mongodb://mongos1:27017,mongos2:27017/?replicaSet=shardRS";
const client = new MongoClient(uri);

// 查看分片状态的命令
sh.status()
// 输出示例
{
  "shardingVersion": {
    "_id": 1,
    "minCompatibleVersion": 5,
    "currentVersion": 6,
    "clusterId": ObjectId("645a1b2e3c4d5e6f78901235")
  },
  "shards": [
    {
      "_id": "shard0000",
      "host": "shard1/myShard1-1:27018,myShard1-2:27018",
      "state": 1
    },
    // 其他分片信息...
  ]
}

复制集的性能优化

优化复制集性能涉及多个方面:合理配置oplog大小、优化网络延迟、调整写关注级别等。读操作可以通过读取首选项(Read Preference)分散到从节点,减轻主节点负载。

监控复制延迟是关键,延迟过高可能导致读取不一致和故障转移问题。优化建议包括:使用专用网络连接、确保成员硬件配置相似、避免长时间运行影响复制的操作等。

// 设置读取首选项的示例
const client = new MongoClient(uri, {
  readPreference: 'secondary',
  readPreferenceTags: [{ dc: 'east', usage: 'reporting' }]
});

// 监控复制延迟的命令
db.printReplicationInfo()
db.printSlaveReplicationInfo()

// 输出示例
configured oplog size:   2048MB
log length start to end: 1234567secs (342.94hrs)
oplog first event time:  Thu May 01 2023 10:00:00 GMT+0800
oplog last event time:   Thu May 15 2023 12:00:00 GMT+0800
now:                     Thu May 15 2023 12:00:01 GMT+0800

安全性与访问控制

复制集的安全配置包括:启用身份验证、配置网络加密、设置适当的角色权限等。X.509证书认证常用于成员间通信,Kerberos认证适用于企业环境。

关键安全措施包括:限制成员间通信端口、配置防火墙规则、定期轮换密钥等。MongoDB提供内置角色如clusterAdmin、clusterManager和clusterMonitor来管理复制集。

// 启用复制集身份验证的配置示例
security:
  keyFile: /path/to/keyfile
  authorization: enabled

// 创建集群管理用户的示例
use admin
db.createUser({
  user: "clusterAdmin",
  pwd: "securePassword",
  roles: [ { role: "clusterAdmin", db: "admin" } ]
})

// 使用X.509认证连接复制集的示例
const uri = "mongodb://host1:port1,host2:port2/?replicaSet=myReplicaSet&ssl=true";
const client = new MongoClient(uri, {
  tlsCertificateKeyFile: '/path/to/client.pem',
  authMechanism: 'MONGODB-X509'
});

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌