注册

MongoDB分片测试

当MongoDB的单机性能达到瓶颈后,我们需要将集合分散到多个机器上进行分片(sharding),以便解决数据量增长时的性能问题。而MongoDB的分片功能强大,其架构的分散性和弹性也非常好。所以分片是MongoDB的一个核心功能。

以下是MongoDB分片测试的完整攻略:

运行环境

  • 主机1:192.168.100.1
  • 主机2:192.168.100.2

两台主机的硬件配置都是:16核CPU,64GB内存,硬盘存储使用了RAID 0。操作系统为CentOS 7,安装有MongoDB 4.2版本。

安装配置MongoDB集群

在两台主机上都需要安装MongoDB 4.2,并进行安装和配置。因为在分片的架构中,我们至少需要有3个节点:mongos,config,和shard。其中,mongos节点是控制器,用来将数据分散到shard节点;config节点是MongoDB的元数据库,用于存储集群元信息和配置;shard节点则是数据存储容器。

该部分详细步骤请参考MongoDB4.2安装配置,这里不再赘述。

配置目标文件

接下来需要修改目标文件的配置。以每个节点的配置为例:

mongos节点

mongos节点的目标文件通常在/etc/mongos.conf路径下,需要添加以下内容:

net:
   port: 27017
systemLog:
   destination: file
   path: /var/log/mongodb/mongos.log
   logAppend: true
processManagement:
   fork: true
setParameter:
   enableLocalhostAuthBypass: false
sharding:
   configDB: config01/config02/config03

其中,mongos的默认端口为27017,systemLog选项用于配置日志,fork选项则表示在后台运行mongos。setParameter选项使mongos在本地验证HOST代替AUTH。最后,sharding选项配置configDB参数,标识了元数据库的主机名或IP地址以及端口号。

config节点

config节点的目标文件通常在/etc/mongod.conf路径下,需要添加以下内容:

net:
   port: 27017
systemLog:
   destination: file
   path: /var/log/mongodb/config01.log
   logAppend: true
processManagement:
   fork: true
sharding:
   clusterRole: "configsvr"
replication:
   replSetName: "config01"

其中,net选项配置端口信息,systemLog选项用于配置日志,fork选项则表示在后台运行mongod。sharding选项标志该节点的clusterRole为configsvr,并指定了复制集名称。replication选项同样指定了该节点的复制集名称。

shard节点

shard节点的目标文件通常在/etc/mongod.conf路径下,需要添加以下内容:

net:
   port: 27017
storage:
   dbPath: /data/mongodb/shard1
systemLog:
   destination: file
   path: /var/log/mongodb/shard1.log
   logAppend: true
processManagement:
   fork: true
sharding:
   clusterRole: "shardsvr"
replication:
   replSetName: "shard1"

其中,net选项配置端口信息,storage选项用于指定数据存储路径,systemLog选项用于配置日志,fork选项表示在后台运行,sharding选项标志该节点的clusterRole为shardsvr,并指定了该节点所在复制集的名称。replication选项同样指定了该节点的复制集名称。

启动MongoDB集群

所有节点都启动后打开命令行输入mongo启动mongo shell。进入mongo shell后,使用sh.addShard()方法将shard节点添加到mongos上(示例:向mongos添加位于主机192.168.100.2的shard节点):

sh.addShard("192.168.100.2:27017")

使用sh.enableSharding()方法开启分片功能:

sh.enableSharding("test")

其中,"test"是你将要用来分片的数据库名称。

第二个步骤完成后,在将要分片的集合中进行数据插入测试。首先使用mongo shell命令:

use test
db.createCollection("users")

然后向该集合插入数据:

for(var i=0;i<10000000;i++){
    var age=Math.floor(Math.random()*50)+18;
    db.users.insert({"name":"user"+i,"age":age})
}

以上步骤完成后,使用sh.shardCollection()方法对集合进行分片:

sh.shardCollection("test.users",{age:1})

其中,age:1表示对age字段进行升序分片。

最后,我们可以使用db.users.getShardDistribution()方法来查看分片状态。如果分片状态正常,MongoDB集群分片测试就完成了。

分片测试的两条示例

  • 示例一:单文档查询测试

使用以下mongo shell命令进行测试:

db.users.findOne().pretty()

预期结果为:

{
        "_id" : ObjectId("5f52fbe04ff8de7e9c3e1d6e"),
        "name" : "user0",
        "age" : 58
}

可以看到,该命令返回了一个单一文档,用来测试单机性能和查询速度。

  • 示例二:基于条件的数据查询测试

使用以下mongo shell命令进行测试:

db.users.find({age:{$gt:50}}).sort({"name":1}).limit(10).pretty()

预期结果为:

{
        "_id" : ObjectId("5f52fbe84ff8de7e9c3e3330"),
        "name" : "user102130",
        "age" : 51
}
{
        "_id" : ObjectId("5f52fbe74ff8de7e9c3e2d9b"),
        "name" : "user101915",
        "age" : 51
}
{
        "_id" : ObjectId("5f52fbe54ff8de7e9c3e27ad"),
        "name" : "user101583",
        "age" : 51
}
{
        "_id" : ObjectId("5f52fbe44ff8de7e9c3e21d1"),
        "name" : "user101289",
        "age" : 51
}
{
        "_id" : ObjectId("5f52fbe04ff8de7e9c3e1d6e"),
        "name" : "user0",
        "age" : 58
}
{
        "_id" : ObjectId("5f52fbe74ff8de7e9c3e2cdf"),
        "name" : "user101662",
        "age" : 52
}
{
        "_id" : ObjectId("5f52fbe84ff8de7e9c3e3259"),
        "name" : "user102018",
        "age" : 52
}
{
        "_id" : ObjectId("5f52fbe74ff8de7e9c3e2ad1"),
        "name" : "user101790",
        "age" : 53
}
{
        "_id" : ObjectId("5f52fbe54ff8de7e9c3e2692"),
        "name" : "user101539",
        "age" : 53
}
{
        "_id" : ObjectId("5f52fbe84ff8de7e9c3e32b5"),
        "name" : "user102049",
        "age" : 54
}

可以看到,该命令返回了一个符合条件的数据子集,用于测试分片性能和复杂度。