MongoDB的分布式架构是通过使用Sharding(分片)来实现的,使用MongoDB的sharding可以带来以下好处:

  • 横向扩展:通过添加更多的shard,MongoDB能够处理更大的数据集和更高的并发访问,提供更好的性能和可扩展性。
  • 高可用性:通过将数据复制到多个shard上,并使用复制集提供数据冗余和自动故障转移,MongoDB能够提供高可用性。
  • 负载均衡:Mongos路由请求到不同的shard上,从而实现负载均衡,避免单个shard成为瓶颈。

一、分片集群组件

在一个分片集群中,包含以下组件:

  1. 分片(shards),实际存储数据的节点。
  2. 集群配置集(config),存储整个分片集群的metadata信息。
  3. 路由(mongos),作为应用接入路由节点,是mongodb数据的入口。

1.1 Shards

  • 每个shard是一个独立的MongoDB实例,负责存储一部分数据,多个独立的shard分片组成整个shards分片集群。
  • 每个shard都可以是一个独立的物理服务器或一个复制(Replica Set)。
  • Shard可以动态地添加或删除,以适应数据量的变化。
  • Shard Key用来将数据分发到不同shard。MongoDB根据Shard Key决定将数据存储在哪个shard上。

1.2 Config servers(metadata)

  • Config Server是存储集群的元数据(metadata)的特殊MongoDB实例。
  • 元数据包括分片键(shard key)的范围和每个分片负责的数据范围。
  • Config Server通常以复制集的形式部署,官方推荐至少3个节点,以提供高可用性和数据冗余。

作为config server的复制集必须采用 WiredTiger storage engine。
副本节点中没有arbiter。
副本节点中没有delayed members。
副本节点中必须build indexes。

1.3 Router(mongos)

  • mongos是应用程序和分片集群之间的接口,所有对集群的操作及数据读写都连接到mongos进行。
  • 应用程序通过Mongos与集群交互,Mongos负责将请求路由到正确的shard上。
  • Mongos还负责跟踪分片集群的状态和管理元数据。

二、配置高可用mongodb分片集群

MongoDB sharding 高可用集群配置要点:

  1. 配置mongodb分片集群时,推荐对每个mongod组件使用用域名或hosts绑定。
  2. shard集群至少配置2个分片,每个分片都为复制集(1 Primary + 1 Replica + 1 Arbiter),实现数据冗余。
  3. 至少3个config server,实现集群高可用。
  4. 启用多个mongos实例,通过在应用上配置,实现负载均衡。

2.1 集群配置说明

通常按以下顺序进行集群配置:

  1. 分别创建shards、config、mongos配置文件
  2. 确认mongodb各目录是否存在及权限正确
  3. 按顺序配置并启动分片集群各个组件实例(依次启动config->shards->mongos)
  4. 初始化复制集分片
  5. 初始化config server复制集
  6. 配置集群分片,对DB或Collection开启分片功能
  7. 使用数据库都连接到mongos节点进行操作

2.2 各组件的配置文件

2.2.1 shard 配置文件 shard.conf

多个shard节点配置相同,需注意dbPath是否存在且权限正确。

processManagement:
    fork: true
net:
    port: 27018
    bindIp: 0.0.0.0

systemLog:
    destination: file
    path: /opt/mongodb.log
    logAppend: true
    logRotate: rename

storage:
    journal:
        enabled: true
    dbPath: /opt/data/mongodb/
    directoryPerDB: true
    engine: wiredTiger
    wiredTiger:
        engineConfig:
            cacheSizeGB: 10
            directoryForIndexes: true
        collectionConfig:
            blockCompressor: zlib
        indexConfig:
            prefixCompression: true

replication:
    oplogSizeMB: 20480
    replSetName: shardN

sharding:
    clusterRole: shardsvr

2.2.2 config server 配置文件 config.conf

多个config节点配置相同,需注意dbPath是否存在且权限正确。

processManagement:
    fork: true

net:
    port: 27019
    bindIp: 0.0.0.0

systemLog:
    destination: file
    path: /opt/configsrv.log
    logAppend: true
    logRotate: rename

storage:
    journal:
        enabled: true
    dbPath: /opt/data/configsrv/
    directoryPerDB: true
    engine: wiredTiger
    wiredTiger:
        engineConfig:
            cacheSizeGB: 1
            directoryForIndexes: true
        collectionConfig:
            blockCompressor: zlib
        indexConfig:
            prefixCompression: true

replication:
    replSetName: config

sharding:
    clusterRole: configsvr

2.2.3 Router 配置文件 mongos.conf

processManagement:
    fork: true

net:
    port: 27017
    bindIp: 0.0.0.0

systemLog:
    destination: file
    path: /opt/mongos.log
    logAppend: true
    logRotate: rename

sharding:
    configDB: config/config_server1:27019,config/config_server2:27019,config/config_server3:27019,

2.3 启动各个组件的实例

需要注意目录权限及用户,一般这两都默认都是mongodb。

shard和config的启动都是使用mongod启动:

mongod --config /opt/shard.conf
mongod --config /opt/config.conf

启动mongos:

mongos --config /opt/config.conf

三、 初始化分片集群

3.1 初始化shard

连接到每个shard,分别执行以下命令进行初始化:

mongo shard1:27018
use admin
db.runCommand({
    "replSetInitiate":{
        "_id":"RsDBNAME",
        "members":[
            {"_id":1,"host":"shard1:27018","priority": 2},
            {"_id":2,"host":"shard2:27018"},
            {"_id":3,"host":"shard3:27018","arbiterOnly":true}
        ]
    }
})

3.2 初始化config server复制集

连接到每个config server,分别执行以下命令进行初始化:

mongo config1:27019
use admin
rs.initiate({
    _id: "configReplSetNAME",
    configsvr: true,
    members: [
        { _id: 1, host: "config1:27019", "priority": 2 },
        { _id: 2, host: "config2:27019" },
        { _id: 3, host: "config3:27019" }
   ]
})

3.3 连接到mongos进行集群分片的配置

mongo mongos1:27017
use admin
sh.addShard("shardN/shard1:27018")
sh.addShard("shardN/shard2:27018")
sh.addShard("shardN/shard3:27018")

shardN为配置文件中replica_set的名字,按需进行修改。

四、启用分片功能

4.1 对某个库开启分片

先连接mongos在执行:

mongo mongos1:27017
use admin
sh.enableSharding("DBtest")

4.2 对某个Collection启用分片

对Collection启用分片需先创建索引:

db.MYcollection.createIndex({ field1: 1 })
sh.shardCollection("MYdatabase.MYcollection", { field1: 1 })

五、日常使用及测试

使用数据库都要连接到mongos节点进行操作:

mongo mongos1:27017
use test
db.MYcollection.insert({"test": 1})
db.MYcollection.find()

参考文章:
https://www.mongodb.com/docs/manual/sharding/
https://vastxiao.github.io/article/2019/12/06/mongodb-setup-config-sharding-cluster/