MongoDB中的Primary Shard详解

 更新时间:2024年08月23日 12:16:36   作者:吃饭端住碗  
在MongoDB的Sharding架构中,每个database中都可以存储两种类型的集合,一种是未分片的集合,一种是通过分片键,被打散的集合,下面给大家介绍MongoDB中的Primary Shard详解,感兴趣的朋友跟随小编一起看看吧

什么是Primary Shard

在MongoDB的Sharding架构中,每个database中都可以存储两种类型的集合,一种是未分片的集合,一种是通过分片键,被打散的集合。被分片键打散的集合数据可以均匀的分布在各个分片上;而对于未分片的集合,则只会存储在所在的database的Primary Shard中,每个database有且只有一个Primary Shard。简单来说就是,Primary Shard存储了当前数据库未分片的集合。示意图如下:

其中Collection I为分片集合,数据被打散到不同的分片上。Collection 2作为未分片集合所有的所有都只存储在Primary Shard中,这里它的Primary Shard为Shard A。

Primary Shard的选择及问题

当我们通过mongos创建一个database时,mongos会根据当前每个分片中存储的数据量来决定哪个分片为当前数据库的Primary Shard,存储数据量最少的作为当前数据库的主分片。数据量判断依据为listDatabases命令中的totalSize的值。

比如我们新建一个test1库,并在里面创建一个未分片的集合,mongos为它挑选的Primary Shard为shard2:

[direct: mongos] test> use test1;
switched to db test1
[direct: mongos] test1> db.foo.insertOne({"name":"aaa"});
{
  acknowledged: true,
  insertedId: ObjectId("66c6f060b47ae218b4ef12aa")
}
[direct: mongos] test1> sh.status()
...
  {
    database: {
      _id: 'test1',
      primary: 'shard2',
      partitioned: false,
      version: {
        uuid: new UUID("a419673b-944b-4cdd-8d11-f3074bbf43fb"),
        timestamp: Timestamp({ t: 1724313695, i: 1 }),
        lastMod: 1
      }
    },
    collections: {}
  }

Primary Shard自动选择存在的问题

问题一

假设有如下需求:有两个专门存储配置集合的database,由于是配置集合,所有数据量比较小,不需要再将其数据打散,但是为了方面管理,需要将这两个配置库存放在同一个分片中。换句话说就是这两个配置库的Primary Shard需要为同一个。

我们知道,mongos在选择Primary Shard的时候是根据当前各个分片现有的数据量来决定的,但是如果当前各个分片的数据量都比较均衡,当我们的业务数据在持续变动的过程中,mongos在选择Primary Shard的时候就会表现出随机性--先后创建的database的Primary Shard极有可能会是不同的分片。

问题二

假设目前需要有一个日志库,然后每个月都会以月份为后缀进行切库,就是说6月份的话我会创建一个叫DB_202406的库,7月份的话会创建一个叫做DB_202407的库,集合的月增量为1个T。由于增量比较大,后面肯定是需要不断加机器扩容的,当单台服务器的磁盘IO能力不是瓶颈的情况下,为了后期加机器扩容时不需要进行历史数据的均衡,所以日志集合的选择了未分片。那么当我进行月底切库,即创建新库的时候,mongos就会判断各个分片上的现有数据量,然后找一个数据量相对较小的分片作为Primary Shard,此时,如果各个分片的服务器磁盘并不是相同大小的,比如说A分片的磁盘大小为10T,B分片磁盘的大小为5T,但是A分片存储的数据为4.8T,B分片存储的数据为4.5T,这时候由于B分片上存储的数据少,mongos会将B分片选为新库的Primary Shard,但是实际情况是B分片所在的主机空闲空间已经完全不足以支持本月的月增数据量了,后面就只能临时扩容本机或删数据或将数据在线同步迁移到有足够空间的新机器上,并进行应用切换。

如何解决

针对上面存在的两个问题,根本原因还是由于在新建库后,mongs自动为当前库选择的Primary Shard可能会出现不合理性,所以我们在进行建库的时候,最好的办法是直接指定新库的Primary Shard,这样就可以规避掉上面两个问题。而且针对第二个问题,还需要做的是当业务上线前需要做好的架构规划和容量规划等。

建库后指定当前库的Primary Shard:

[direct: mongos] test> use DB1
switched to db DB1
[direct: mongos] DB1> sh.enableSharding("DB1","shard1") 
{
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1724317769, i: 3 }),
    signature: {
      hash: Binary(Buffer.from("0000000000000000000000000000000000000000", "hex"), 0),
      keyId: Long("0")
    }
  },
  operationTime: Timestamp({ t: 1724317769, i: 1 })
}
[direct: mongos] DB1> sh.status()
...
  {
    database: {
      _id: 'DB1',
      primary: 'shard1',
      partitioned: false,
      version: {
        uuid: new UUID("ec0e50b8-3029-4333-887b-9ca0b54c4e20"),
        timestamp: Timestamp({ t: 1724317768, i: 1 }),
        lastMod: 1
      }
    },
    collections: {}
  }

只能在use新库之后,立即指定新库的Primary Shard,不能等创建过集合并写入数据之后再指定,因为那时mongos已经为新库选好了Primary Shard,就不支持再次修改了

[direct: mongos] DB1> sh.enableSharding("DB1","shard3") 
MongoServerError: Database DB1 could not be created :: caused by :: database already created on a primary which is different from shard1

到此这篇关于MongoDB中的Primary Shard的文章就介绍到这了,更多相关MongoDB Primary Shard内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MongoDB创建一个索引而性能提升1000倍示例代码

    MongoDB创建一个索引而性能提升1000倍示例代码

    这篇文章主要给大家介绍了关于如何在MongoDB中创建一个索引而性能提升1000倍的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-01-01
  • MongoDB教程之查询操作实例

    MongoDB教程之查询操作实例

    这篇文章主要介绍了MongoDB教程之查询操作实例,本文讲解了基本查询、查询条件、null数据类型的查询、正则查询、数组数据查询、内嵌文档查询等数据查询技巧,需要的朋友可以参考下
    2015-05-05
  • mongodb 数据类型(null/字符串/数字/日期/内嵌文档/数组等)

    mongodb 数据类型(null/字符串/数字/日期/内嵌文档/数组等)

    MongoDB的文档类似于JSON,JSON只是一种简单的表示数据的方式,只包含了6种数据类型(null、布尔、数字、字符串、数组及对象),需要的朋友可以参考下
    2017-04-04
  • MongoDB 查询操作的实例详解

    MongoDB 查询操作的实例详解

    这篇文章主要介绍了MongoDB 查询操作的实例的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下
    2017-09-09
  • Mongodb副本集和分片示例详解

    Mongodb副本集和分片示例详解

    这篇文章主要给大家介绍了关于Mongodb副本集和分片的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Mongodb具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-08-08
  • MongoDB在Windows平台的安装及配置方法

    MongoDB在Windows平台的安装及配置方法

    这篇文章主要介绍了MongoDB在Windows平台的安装及配置方法,简单分析了MongoDB的下载、设置方法、操作命令等具体步骤与相关注意事项,需要的朋友可以参考下
    2017-04-04
  • Mongodb数据库两种启动方法小结

    Mongodb数据库两种启动方法小结

    MongoDB是一种开源的服务器端NoSQL数据库管理系统,它提供了一种灵活的框架,可以快速地存储、处理和管理大量的数据,这篇文章主要给大家介绍了关于Mongodb数据库两种启动方法的相关资料,需要的朋友可以参考下
    2023-12-12
  • mongodb禁止外网访问及添加账号的操作方法

    mongodb禁止外网访问及添加账号的操作方法

    这篇文章主要介绍了mongodb禁止外网访问及添加账号的操作方法,需要的朋友可以参考下
    2017-12-12
  • MongoDB数据库类replace替换字符串指定内容

    MongoDB数据库类replace替换字符串指定内容

    mongoDB是没有定义replace函数的,那么如果有需求需要替换nongo中数据的某一部分,怎么办?下面这篇文章主要给大家介绍了关于MongoDB数据库类replace替换字符串指定内容的相关资料,需要的朋友可以参考下
    2023-05-05
  • MongoDB中实现多表联查的实例教程

    MongoDB中实现多表联查的实例教程

    数据库应用在我们的生活中是很常见的,在编辑一些应用以及软件的时候都需要用到数据库来存储数据,下面这篇文章主要给大家介绍了关于MongoDB中实现多表联查的相关资料,需要的朋友可以参考下
    2022-07-07

最新评论