【赵渝强老师】MongoDB的分布式存储架构

本文涉及的产品
云原生多模数据库 Lindorm,多引擎 多规格 0-4节点
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: MongoDB分片通过将数据分布到多台服务器,实现海量数据的高效存储与读写。其架构包含路由、配置服务器和分片服务器,支持水平扩展,结合复制集保障高可用性,适用于大规模生产环境。

b394.png

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


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


一、 MongoDB分片的架构


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

image.png


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


  • 前端路由服务器:Router,客户端应用程序从Router接入MongoDB分片集群。Router可以让分片集群看上去像一个单一的数据库。Router通过mongos的命令来启动。


  • 配置服务器:Config Server,负责存储MongoDB分片的元信息以及后端的分片服务器信息。从MongoDB 3.4的版本开始,Config Server必须配置成一个复制集的形式。


  • 分片服务器:Shard Server,负责存储实际的数据块。在实际生产环境中一个Shard Server可以由几台服务器组成一个复制集,从而防止主机单点故障造成数据的丢失。分片服务器也必须是一个复制集的形式。


视频讲解如下:


二、 【实战】部署MongoDB分片


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

image.png


提示:表中列举的的信息是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的复制集上。因此可以得出结论,数据实现了分布式存储但效果不是很好。为了实现更好的数据分布式存储应当合理地选择片键。


相关文章
|
4月前
|
存储 负载均衡 NoSQL
【赵渝强老师】Redis Cluster分布式集群
Redis Cluster是Redis的分布式存储解决方案,通过哈希槽(slot)实现数据分片,支持水平扩展,具备高可用性和负载均衡能力,适用于大规模数据场景。
342 2
|
5月前
|
人工智能 Kubernetes 数据可视化
Kubernetes下的分布式采集系统设计与实战:趋势监测失效引发的架构进化
本文回顾了一次关键词监测任务在容器集群中失效的全过程,分析了中转IP复用、调度节奏和异常处理等隐性风险,并提出通过解耦架构、动态IP分发和行为模拟优化采集策略,最终实现稳定高效的数据抓取与分析。
Kubernetes下的分布式采集系统设计与实战:趋势监测失效引发的架构进化
|
2月前
|
缓存 Cloud Native 中间件
《聊聊分布式》从单体到分布式:电商系统架构演进之路
本文系统阐述了电商平台从单体到分布式架构的演进历程,剖析了单体架构的局限性与分布式架构的优势,结合淘宝、京东等真实案例,深入探讨了服务拆分、数据库分片、中间件体系等关键技术实践,并总结了渐进式迁移策略与核心经验,为大型应用架构升级提供了全面参考。
|
6月前
|
存储 机器学习/深度学习 缓存
软考软件评测师——计算机组成与体系结构(分级存储架构)
本内容全面解析了计算机存储系统的四大核心领域:虚拟存储技术、局部性原理、分级存储体系架构及存储器类型。虚拟存储通过软硬件协同扩展内存,支持动态加载与地址转换;局部性原理揭示程序运行特性,指导缓存设计优化;分级存储架构从寄存器到外存逐级扩展,平衡速度、容量与成本;存储器类型按寻址和访问方式分类,并介绍新型存储技术。最后探讨了存储系统未来优化趋势,如异构集成、智能预取和近存储计算等,为突破性能瓶颈提供了新方向。
|
6月前
|
监控 算法 关系型数据库
分布式事务难题终结:Seata+DRDS全局事务一致性架构设计
在分布式系统中,CAP定理限制了可用性、一致性与分区容错的三者兼得,尤其在网络分区时需做出取舍。为应对这一挑战,最终一致性方案成为常见选择。以电商订单系统为例,微服务化后,原本的本地事务演变为跨数据库的分布式事务,暴露出全局锁失效、事务边界模糊及协议差异等问题。本文深入探讨了基于 Seata 与 DRDS 的分布式事务解决方案,涵盖 AT 模式实践、分片策略优化、典型问题处理、性能调优及高级特性实现,结合实际业务场景提供可落地的技术路径与架构设计原则。通过压测验证,该方案在事务延迟、TPS 及失败率等方面均取得显著优化效果。
335 61
|
5月前
|
存储 NoSQL MongoDB
MongoDB数据库详解-针对大型分布式项目采用的原因以及基础原理和发展-卓伊凡|贝贝|莉莉
MongoDB数据库详解-针对大型分布式项目采用的原因以及基础原理和发展-卓伊凡|贝贝|莉莉
273 8
MongoDB数据库详解-针对大型分布式项目采用的原因以及基础原理和发展-卓伊凡|贝贝|莉莉
|
6月前
|
存储 关系型数据库 分布式数据库
【赵渝强老师】基于PostgreSQL的分布式数据库:Citus
Citus 是基于 PostgreSQL 的开源分布式数据库,采用 shared nothing 架构,具备良好的扩展性。它以插件形式集成,部署简单,适用于处理大规模数据和高并发场景。本文介绍了 Citus 的基础概念、安装配置步骤及其在单机环境下的集群搭建方法。
492 2
|
6月前
|
存储 关系型数据库 MySQL
成本直降30%!RDS MySQL存储自动分层实战:OSS冷热分离架构设计指南
在日均订单量超500万的场景下,MySQL数据年增200%,但访问集中在近7天(85%)。通过冷热数据分离,将历史数据迁移至OSS,实现存储成本下降48%,年省72万元。结合RDS、OSS与Redis构建分层架构,自动化管理数据生命周期,优化查询性能与资源利用率,支撑PB级数据扩展。
357 3
|
6月前
|
存储 关系型数据库 数据库
高性能云盘:一文解析RDS数据库存储架构升级
性能、成本、弹性,是客户实际使用数据库过程中关注的三个重要方面。RDS业界率先推出的高性能云盘(原通用云盘),是PaaS层和IaaS层的深度融合的技术最佳实践,通过使用不同的存储介质,为客户提供同时满足低成本、低延迟、高持久性的体验。

相关产品

  • 云数据库 MongoDB 版
  • 推荐镜像

    更多