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安装及接入springboot的详细过程

    MongoDB安装及接入springboot的详细过程

    MongoDB是一个开源、高性能、无模式(模式自由)的文档(Bson)型数据库,这篇文章主要介绍了MongoDB安装及接入springboot,需要的朋友可以参考下
    2024-05-05
  • Mongodb数据库两种启动方法小结

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

    MongoDB是一种开源的服务器端NoSQL数据库管理系统,它提供了一种灵活的框架,可以快速地存储、处理和管理大量的数据,这篇文章主要给大家介绍了关于Mongodb数据库两种启动方法的相关资料,需要的朋友可以参考下
    2023-12-12
  • 浅析MongoDB之安全认证

    浅析MongoDB之安全认证

    MongoDB是基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。默认情况下,MongoDB实例启动运行时是没有启用用户访问权限控制的,在实例本机服务器上都可以随意连接到实例进行各种操作,MongoDB不会对连接客户端进行用户验证
    2021-06-06
  • Mongodb单字段索引应用详解

    Mongodb单字段索引应用详解

    mongodb支持在文档中的任何一个字段建立单字段索引,包括文档的顶级字段,针对嵌入式文档建立索引或者针对嵌入式文档的某个字段建立索引,本文给大家介绍Mongodb单字段索引的相关知识,感兴趣的朋友一起看看吧
    2024-07-07
  • mongodb中根据时间过滤进行查询的操作方法

    mongodb中根据时间过滤进行查询的操作方法

    这篇文章主要介绍了mongodb中简单的根据时间过滤进行查询,文末补充介绍了如何根据日期过滤/查找MongoDB中的记录,结合实例给大家介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • MongoDB数据去重与保存最新数据操作指南

    MongoDB数据去重与保存最新数据操作指南

    在 MongoDB 数据库中,我们经常需要进行数据去重并保留最新的数据,本文将介绍如何使用 MongoDB 聚合操作完成这一任务,并将结果保存到新的集合或者覆盖原有的集合,感兴趣的小伙伴跟着小编一起来看看吧
    2024-01-01
  • mongodb 修改用户密码 2种方法

    mongodb 修改用户密码 2种方法

    mongodb的用户信息是存放在system.users表中的,修改密码不能直接更新表数据,这样的话,存到表里的密码是明文的,这就不对了。
    2014-07-07
  • MongoDB常用数据库命令大全

    MongoDB常用数据库命令大全

    这篇文章主要介绍了MongoDB 常用数据库命令大全,需要的朋友可以参考下
    2020-02-02
  • 解决net start MongoDB 报错之服务名无效的问题

    解决net start MongoDB 报错之服务名无效的问题

    这篇文章主要介绍了解决net start MongoDB 报错之服务名无效的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • MongoDB进阶之动态字段设计详解

    MongoDB进阶之动态字段设计详解

    这篇文章主要给大家介绍了MongoDB进阶之动态字段设计的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编一起来学习学习吧。
    2017-06-06

最新评论