📅  最后修改于: 2023-12-03 15:17:42.397000             🧑  作者: Mango
MongoDB 是一款开源的面向文档的数据库管理系统。它结合了传统的关系型数据库管理系统的优势和 NoSQL 数据库的特点,可在大规模、高性能和高可用性的场景下使用。MongoDB 支持数据复制和分片功能。
复制是 MongoDB 中实现高可用性的方式。它可以提高数据的可靠性和容错能力。MongoDB 中的复制又称为副本集(Replica Set)。
副本集是一组维护相同数据集的 mongod 实例。其中,一个 mongod 实例为主节点(Primary),其余的 mongod 实例为副本节点(Secondary)。在副本集中,主节点负责所有的写操作和客户端的请求,而副本节点负责复制主节点的数据。
当主节点写入一条数据时,它首先将数据写入自己的 oplog(操作日志)中,然后将数据同步到所有的副本节点上。在同步的过程中,主节点会在 oplog 中记录每条操作的信息,副本节点会读取 oplog 中的记录并按照顺序执行相应的操作。
如果主节点出现故障,副本节点将会自动选举一个新的主节点。选举过程使用的是 Raft 算法,可以保证新的主节点是合法的,所有数据都已经被复制到新的主节点中。
要创建一个副本集,需要至少 3 个不同的 mongod 实例。在创建副本集时,需要指定各个节点的 IP 地址和端口号,以及副本集的名称。
配置文件示例:
# 主节点
systemLog:
destination: file
path: "/var/log/mongodb/mongod.log"
logAppend: true
processManagement:
fork: true
net:
port: 27017
storage:
dbPath: "/data/db"
replication:
replSetName: "rs0"
# 副本节点 1
systemLog:
destination: file
path: "/var/log/mongodb/mongod.log"
logAppend: true
processManagement:
fork: true
net:
port: 27018
storage:
dbPath: "/data/db"
replication:
replSetName: "rs0"
# 副本节点 2
systemLog:
destination: file
path: "/var/log/mongodb/mongod.log"
logAppend: true
processManagement:
fork: true
net:
port: 27019
storage:
dbPath: "/data/db"
replication:
replSetName: "rs0"
在使用副本集时,需要将连接地址指向副本集的名称,而不是指向某个具体的节点地址。这样可以保证客户端的读和写操作都是针对副本集的,而不是针对某个具体的节点。
连接字符串示例:
mongodb://rs0/primary?replicaSet=rs0
其中,rs0/primary
表示连接到副本集 rs0
中的主节点(Primary)。replicaSet=rs0
表示使用副本集模式。
分片是 MongoDB 中处理大规模数据的方式。它可以将数据分散到多台机器上进行存储和查询。
使用分片可以带来以下优点:
分片包含以下组成部分:
将数据进行分片时,需要选择一个合适的键作为分片的依据。一般来说,选择的键应该是数据中最频繁查询的字段。例如,对于用户数据集合,可以选择用户名作为分片键。
在创建分片时,需要先创建配置服务器,然后创建分片服务器组。将数据插入数据库中后,mongos 会将数据路由到正确的分片服务器中。数据路由的过程使用哈希函数来实现,保证了数据的均衡分布。
在使用分片时,需要将连接地址指向 mongos 的 IP 地址和端口号。这样,客户端的查询请求将会由 mongos 负责路由到正确的分片服务器中。
连接字符串示例:
mongodb://mongos1:27017,mongos2:27017,mongos3:27017/?replicaSet=rs0&readPreference=secondaryPreferred
其中,mongos1:27017,mongos2:27017,mongos3:27017
表示连接到三个 mongos 服务器中的任意一个。replicaSet=rs0
表示使用副本集模式,readPreference=secondaryPreferred
表示优先从副本节点读取数据。