MongoDB的分布式存储架构详解

 更新时间:2025年12月19日 09:13:28   作者:赵渝强老师  
MongoDB分片技术通过将数据分割存储在多台服务器上,实现数据的分布式存储,满足大数据量的需求,分片架构包括前端路由服务器、配置服务器和分片服务器,本文介绍MongoDB的分布式存储架构,感兴趣的朋友跟随小编一起看看吧

在MongoDB存在另一种集群就是MongoDB的分片技术。通过使用分片可以满足MongoDB数据量大量增长的需求。当MongoDB存储海量的数据时,一台MongoDB服务器可能不能满足存储数据的要求,也可能不足以提供可接受的读写吞吐量。MongoDB为了解决这一系列的问题提出了将数据分割存储在多台服务器上,使得数据库系统能存储和处理更多的数据,以实现数据的分布式存储。这就是MongoDB的分片。

提示:单个MongoDB复制集中的节点不能超过12个节点。
因此复制集从本质上并不能解决数据海量存储的问题。

一、 MongoDB分片的架构

MongoDB分片的架构需要依赖MongoDB的复制集为基础来实现,下图展示了分片的体系架构。

从图中可以看出,MongoDB的分片主要包含以下几个组成的部分:

  • 前端路由服务器:Router,客户端应用程序从Router接入MongoDB分片集群。Router可以让分片集群看上去像一个单一的数据库。Router通过mongos的命令来启动。
  • 配置服务器:Config Server,负责存储MongoDB分片的元信息以及后端的分片服务器信息。从MongoDB 3.4的版本开始,Config Server必须配置成一个复制集的形式。
  • 分片服务器:Shard Server,负责存储实际的数据块。在实际生产环境中一个Shard Server可以由几台服务器组成一个复制集,从而防止主机单点故障造成数据的丢失。分片服务器也必须是一个复制集的形式。

点击这里查看视频讲解:【赵渝强老师】MongoDB的分布式存储架构

二、 【实战】部署MongoDB分片

在了解到了MongoDB分片的架构与组成以后,下表列举了MongoDB分片中的各个节点信息。

提示:表中列举的的信息是MongoDB分片架构的最简信息。
例如这里的前端路由服务器只使用了一个节点来实现,
在实际的生产环境中可以搭建多个节点前端路由服务器。

下面通过具体的步骤来演示如何部署一个MongoDB的分片。

(1)创建各个节点数据的存储路径。

mkdir -p /data/27017
mkdir -p /data/37017
mkdir -p /data/37018
mkdir -p /data/47017
mkdir -p /data/47018

(2)创建前端路由服务器的配置信息文件/data/27017/mongos.conf

port=27017
fork=true
logpath=/data/27017/mongos.log
configdb=myshardingconfig/127.0.0.1:37017,127.0.0.1:37018
其中:configdb用于指定配置服务器的地址。

(3)创建第一个配置服务器的配置信息文件/data/37017/mongo_configsvr_37017.conf

dbpath=/data/37017 
port=37017 
fork=true
logpath=/data/37017/configsvr37017.log
replSet=myshardingconfig
configsvr=true
其中:configsvr=true,表示这是一台配置服务器。

(4)创建第一个配置服务器的配置信息文件/data/37018/mongo_configsvr_37018.conf

dbpath=/data/37018
port=37018 
fork=true
logpath=/data/37018/configsvr37018.log
replSet=myshardingconfig
configsvr=true

(5)创建第一个分片服务器的配置信息文件/data/47017/mongo_shardsvr_47017.conf

dbpath=/data/47017
port=47017 
fork=true
logpath=/data/47017/shardsvr47017.log
shardsvr=true
replSet=myshardone
其中:shardsvr=true,表示这是一台分片服务器。

(6)创建第二个分片服务器的配置信息文件/data/47018/mongo_shardsvr_47018.conf

dbpath=/data/47018
port=47018
fork=true
logpath=/data/47018/shardsvr47018.log
shardsvr=true
replSet=myshardtwo

(7)启动所有的MongoDB实例。

mongod --config /data/37017/mongo_configsvr_37017.conf
mongod --config /data/37018/mongo_configsvr_37018.conf
mongod --config /data/47017/mongo_shardsvr_47017.conf
mongod --config /data/47018/mongo_shardsvr_47018.conf

(8)启动前端路由服务器

mongos --config /data/27017/mongos.conf

(9)使用mongoshell连接37017端口上的MongoDB实例完成配置服务器复制集的初始化。

mongo --port 37017

(10)将37017和37018端口上的MongoDB实例加入复制集中。

> cfg = {"_id":"myshardingconfig",
	   "members":[{"_id":0,"host":"127.0.0.1:37017"},
				  {"_id":1,"host":"127.0.0.1:37018"}]}
> rs.initiate(cfg)

(11)查看复制集myshardingconfig的状态信息。

> rs.status()
# 输出的信息如下:
......
"members" : [
	{
		"_id" : 0,
		"name" : "127.0.0.1:37017",
		"health" : 1,
		"state" : 1,
		"stateStr" : "PRIMARY",
		......
	},
	{
		"_id" : 1,
		"name" : "127.0.0.1:37018",
		"health" : 1,
		"state" : 2,
		"stateStr" : "SECONDARY",
		......
	}
],
......

(12)使用mongoshell连接前端路由服务器。

mongo

(13)查看MongoDB分片服务器的信息。

> sh.status()
# 输出的信息如下:
--- Sharding Status --- 
  sharding version: {
  	"_id" : 1,
  	"minCompatibleVersion" : 5,
  	"currentVersion" : 6,
  	"clusterId" : ObjectId("624d60d6675d42fb9b900362")
  }
  shards:   			--> 此处还没有添加任何的分片服务器地址信息。
  active mongoses:
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled: yes
        Currently running: no
        Failed balancer rounds in last 5 attempts: 0
        Migration results for the last 24 hours: 
                No recent migrations
  databases:
        { "_id" : "config", "primary" : "config","partitioned" :true}

(14)初始化47017上的复制集。

> cfg = {"_id":"myshardone", 
       "members":[{"_id":0,"host":"127.0.0.1:47017"}]}
> rs.initiate(cfg)

(15)初始化47018上的复制集。

> cfg = {"_id":"myshardtwo", 
       "members":[{"_id":0,"host":"127.0.0.1:47018"}]}
> rs.initiate(cfg)

(16)添加分片服务器

> sh.addShard("myshardone/127.0.0.1:47017")
> sh.addShard("myshardtwo/127.0.0.1:47018")

(17)重新查看MongoDB分片的信息。

> sh.status()
# 输出的信息如下:
--- Sharding Status --- 
  sharding version: {
  	"_id" : 1,
  	"minCompatibleVersion" : 5,
  	"currentVersion" : 6,
  	"clusterId" : ObjectId("624d60d6675d42fb9b900362")
  }
  shards:  --> 分片中的服务器地址。
		{"_id":"myshardone","host":"myshardone/127.0.0.1:47017",
"state":1,"topologyTime":Timestamp(1649238845,3)}
		{"_id":"myshardtwo","host":"myshardtwo/127.0.0.1:47018",
"state":1,"topologyTime":Timestamp(1649238865,3)}
  active mongoses:
        "5.0.6" : 1
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled: yes
        Currently running: no
        Failed balancer rounds in last 5 attempts: 0
        Migration results for the last 24 hours: 
                No recent migrations
  databases:
        {"_id":"config","primary":"config","partitioned" : true }

(18)添加一个分片数据库。

> sh.enableSharding("myshardDB")

(19)查看分片数据库的信息。

> sh.status()
# 输出的信息如下:
......
databases:
	{  "_id" : "config",  "primary" : "config",  "partitioned" : true }
			config.system.sessions
					shard key: { "_id" : 1 }
					unique: false
					balancing: true
					chunks:
					myshardone	992
					myshardtwo	32
			too many chunks to print, use verbose if you want to force print
	{  "_id" : "myshardDB",  "primary" : "myshardtwo",  
"partitioned" : true,  
"version":{"uuid": UUID("4c640f1f-77fe-45a6-92b4-b7c90692b845"), 
	 "timestamp" : Timestamp(1649239126, 36),
  "lastMod" : 1 } }

(20)修改数据分片的大小。

> use config
> db.settings.save( { _id:"chunksize", value:1})
注意:默认情况下,分片大小(chunk size)是64M。只有达到了分片的大小,才会进行分片。

(21)开启集合上数据的分片。

> sh.shardCollection("myshardDB.table1",{"_id":1})
提示:这里使用了插入文档的_id作为片键来实现文档的分布式存储。

(22)在数据库myshardDB中创建集合,并插入10万条文档

> use myshardDB
> for(var i = 1; i <= 100000; i++)
{db.table1.insert({"_id":i,"action":"write","iteration no:":i});}

(23)再次查看分片数据库的信息。

> sh.status()
# 输出的信息如下:
......
myshardDB.table1
		shard key: { "_id" : 1 }
		unique: false
		balancing: true
		chunks:
				myshardone	6
				myshardtwo	1
{"_id":{"$minKey":1}}-->>{"_id":2} on:myshardone Timestamp(2,0)
{"_id":	   2}-->>{"_id":20241} on:myshardtwo Timestamp(3,1)
{"_id":20241}-->>{"_id":37933} on:myshardone Timestamp(3,2)
{"_id":37933}-->>{"_id":55627} on:myshardone Timestamp(3,4)
{"_id":55627}-->>{"_id":74150} on:myshardone Timestamp(3,6)
{"_id":74150}-->>{"_id":91829} on:myshardone Timestamp(3,8)
{"_id":91829}-->>{"_id":{"$maxKey":1}}on:myshardoneTimestamp(3,9)
......

从输出的信息可以看出,id值在{2,20241}的数据存储在了myshardtwo 的复制集上;而其他id值对应的数据存储在了myshardone的复制集上。因此可以得出结论,数据实现了分布式存储但效果不是很好。为了实现更好的数据分布式存储应当合理地选择片键。

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

相关文章

  • MongoDB的$sample、aggregate和$rand实现随机选取数据

    MongoDB的$sample、aggregate和$rand实现随机选取数据

    在MongoDB中,我们可以使用内置的$sample聚合操作符来随机生成数据,$sample可以从集合文档中随机选择指定数量的文档,但由于其查询整个集合的性能问题,应该慎用,aggregate方法以及$rand函数的结合使用可以实现更加灵活的查询操作,并且可以对查询结果进行精细筛选
    2024-01-01
  • MongoDB搭建高可用集群的完整步骤(3个分片+3个副本)

    MongoDB搭建高可用集群的完整步骤(3个分片+3个副本)

    这篇文章主要给大家介绍了关于MongoDB搭建高可用集群(3个分片+3个副本)的完整步骤,文中通过示例代码介绍的非常详细,对大家学习或者使用MongoDB具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-08-08
  • MongoDB查询字段没有创建索引导致的连接超时异常解案例分享

    MongoDB查询字段没有创建索引导致的连接超时异常解案例分享

    这篇文章主要介绍了MongoDB查询字段没有创建索引导致的连接超时异常解案例分享,本文是生产环境下总结而来,需要的朋友可以参考下
    2014-10-10
  • MongoDB 数据库的命名、设计规范详解

    MongoDB 数据库的命名、设计规范详解

    随着MongoDB的普及和使用量的快速增长,为了规范使用,便于管理和获取更高的性能,整理此文档
    2020-02-02
  • 给MongoDB添加用户权限方法分享

    给MongoDB添加用户权限方法分享

    这篇文章主要介绍了给MongoDB添加用户权限方法分享,十分的细致全面,推荐给大家,有需要的小伙伴可以参考下。
    2015-03-03
  • MongoDB orm框架的注意事项及简单使用

    MongoDB orm框架的注意事项及简单使用

    MongoDB官方提供的orm的轻量级封装的 zfoo orm 框架,只对官方提供的进行了简单的封装,还做了一些官方不支持的语法校验。本文介绍了该框架的注意事项及简单使用
    2021-06-06
  • 详解MongoDB中创建集合与删除集合的操作方法

    详解MongoDB中创建集合与删除集合的操作方法

    因为MongoDB属于NoSQL,所以集合collection相当于关系型数据库中的表table,这里我们就来详解MongoDB中创建集合与删除集合的操作方法:
    2016-06-06
  • 映射MongoDB _id字段的几种常见方式

    映射MongoDB _id字段的几种常见方式

    在 Spring Data MongoDB 中,将 Java POJO 的字段映射到 MongoDB 文档的 _id 字段非常直接,主要通过 @Id 注解(org.springframework.data.annotation.Id)来完成,本文介绍了映射 MongoDB _id 字段的几种常见方式和关键点,需要的朋友可以参考下
    2025-05-05
  • MongoDB和mysql的区别对比分析

    MongoDB和mysql的区别对比分析

    MongoDB 是一个基于分布式文件存储的数据库,而MySQL 是一款安全、跨平台、高效的,并与 PHP、Java 等主流编程语言紧密结合的数据库系统,本文重点给大家介绍MongoDB和mysql的区别,需要的朋友可以参考下
    2023-01-01
  • 迁移sqlserver数据到MongoDb的方法

    迁移sqlserver数据到MongoDb的方法

    这篇文章主要介绍了迁移sqlserver数据到MongoDb的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12

最新评论