热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

解剖MongoDB【1】系统概览

By盛楠、邓侃关于MongoDB,我们能看到的资料,基本都是在指导大家如何使用MongoDB,但是,MongoDB内部是如

By 盛楠、邓侃

关于MongoDB,我们能看到的资料,基本都是在指导大家如何使用MongoDB,但是,MongoDB内部是如何运作的,资料不是很多。

阅读使用手册,会有很多疑惑之处。例如,有人说,MongoDB 等同于分布式的 MySQL。它把一个Table ,按 row,分割成多个Shards,分别存放在不同的 Servers 上。这种说法是否正确?

不深入了解 MongoDB 的内部结构,就无法透彻地回答类似问题。这个系列文章,就来和大家探讨MongoDB的内部的工作方式。

MongoDB架构概览

图1-1 MongoDB架构图

MongoDB 通常运行在一个服务器集群上,而不是一个单机。图1-1,描述了一个MongoDB集群的基本组成部分,包括若干shards,至少一个config server,至少一个routing servers(又称 mongos)。


Shards

MongoDB的最基本的数据单元,叫document,类似于关系式数据库中的行 row。一系列documents,组成了一个collection,相当于关系式数据库中的table。当一个 collection 数据量太大时,可以把该collection按documents切分,分成多个数据块,每个数据块叫做一个chunk,多个chunks聚集在一起,组成了一个shard。

Sharding 的意义,不仅保障了数据库的扩容(scalability),同时也保障了系统的负载均衡(load balance)。


Shard keys

为了把collection切分成不同的chunks,从而存放到不同的shards中,我们需要制定一个切分的方式。

如前所述,在 MongoDB 数据库中,一个表collection由多个行 documents 组成,而每个 document,有多个属性 fields。同一个 collection 中的不同的 documents,可能会有不同的 fields。例如,有个 collection 叫 Media,包含两条 documents,

  {
     "ISBN": "987-30-3652-5130-82",
     "Type": "CD",
     "Author": "Nirvana",
     "Title": "Nevermind",
     "Genre": "Grunge",
     "Releasedate": "1991.09.24",
     "Tracklist": [
        {
          "Track" : "1",
          "Title" : "Smells like teen spirit",
          "Length" : "5:02"
        },
        {
          "Track" : "2",
          "Title" : "In Bloom",
          "Length" : "4:15"
        }
      ]
   }
  
  {
      "ISBN": "987-1-4302-3051-9",
      "Type": "Book",
      "Title": "Definite Guide to MongoDB: The NoSQL Database",
      "Publisher": "Apress",
      "Author": " Eelco Plugge",
      "Releasedate": "2011.06.09"
  }

假如,在同一个 collection 中的所有 document,都包含某个共同的 field,例如前例中的“ISBN”,那么我们就可以按照这个 field 的值,来分割 collection。这个 field 的值,又称为 shard key。

在选择 shard key 的时候,一定要确保这个 key 能够把 collection 均匀地切分成很多 chunks。

例如,如果我们选择“author”作为 shard key,如果有大量的作者是重名的,那么就会有大量的数据聚集在同一个 chunk 中。当然,假设很少有作者同名同姓,那么“author”也可以作为一个shard key。换句话说,shard key 的选择,与使用场景密切相关。

很多情况下,无论选择哪一个单一的 field 作为 shard key,都无法均匀分割 collection。在这种情况下,我们可以考虑,用多个 fields,构成一个复合的 shard key

延续前例,假如有很多作者同名同姓,他们都叫“王二”。用 author 作为 shard key,显然无法均匀切割 collection。这时我们可以加上 release-date,组成 name-date 的复合的 shard key,例如“王二 2011”。


Chunks

    MongoDB 按 shard key,把 collection切割成若干chunks。每个 chunk 的数据结构,是一个三元组,{collection,minKey,maxKey},如图1-2 所示。

MongoDB架构概览
图1-2 chunk的三元组

其中,collection 是数据库中某一个表的名称,而 minKey 和 maxKey 是 shard key的范围。每一个 document 的shard key 的值,决定了这条document应该存放在哪个chunk中。

如果两条 documents 的 shard keys 的值很接近,这两条 documents 很可能被存放在同一个 chunk 中。

Shard key 的值的顺序,决定了 document 存放的 chunk。在 MongoDB 的文献中,这种切割 collection 的方式,称为 order-preserving。

一个 chunk 最多能够存储64MB的数据。 当某个 chunk 存储的 documents 包含的数据量,接近这个阈值时,一个 chunk 会被切分成两个新的 chunks。

当一个 shard 存储了过多的 chunks,这个shard中的某些 chunks 会被迁移到其它 shard 中。

这里有个问题,假如某一条 document 包含的数据量很大,超过 64MB,一个 chunk 存放不下,怎么办?在后续章节介绍 GridFS 时,我们会详细讨论。


Replica set

在生产环境中,为了保证数据不丢失,为了提高系统的可用性(availability),每一个shard被存储多份,每个备份所在的 servers,组成了一个 replica set。

这个 replica set 包括一个 primary DB 和多个secondary DBs。为了数据的一致性,所有的修改 (insert / update / deletes) 请求都交给 primary 处理。处理结束之后,再异步地备份到其他 secondary 中。

Primary DB 由 replica set中的所有 servers,共同选举产生。当这个 primaryDB server 出错的时候,可以从 replica set 中重新选举一个新的 primaryDB,从而避免了单点故障。

Replica set 的选举策略和数据同步机制,确保了系统的数据的一致性。后文详述。


Config Server

Config servers 用于存储 MongoDB 集群的元数据 metadata,这些元数据包括如下两个部分,每一个 shard server 包括哪些 chunks,每个 chunk 存储了哪些 collections 的哪些 documents。

    每一个 config server 都包括了 MongoDB 中所有 chunk 的信息。

Config server 也需要 replication。但是有趣的是,config server 采用了自己独特的 replication 模式,而没有沿用 replica set。

如果任何一台 config server 挂了,整个 config server 集群中,其它 config server 变成只读状态。这样做的原因,是避免在系统不稳定的情况下,冒然对元数据做任何改动,导致在不同的 config servers 中,出现元数据不一致的情况。

MongoDB 的官方文档建议,配置 3 个 config servers 比较合适,既提供了足够的安全性,又避免了更多的 config servers 实例之间的数据同步,引起的元数据不一致的麻烦。


Mongos

    用户使用MongoDB 时,用户的操作请求,全部由 mongos 来转发。

当 mongos 接收到用户请求时,它先查询 config server,找到存放相应数据的 shard servers。然后把用户请求,转发到这些 shard servers。当这些 shard servers完成操作后,它们把结果分别返回给 mongos。而当 mongos 汇总了所有的结果后,它把结果返回给用户。

Mongos 每次启动的时候,都要到 config servers 中读取元数据,并缓存在本地。每当 config server中的元数据有改动,它都会通知所有的 mongos。

Mongos 之间,不存在彼此协同工作的问题。因此,MongoDB 所需要配置的 mongos server的数量,没有限制。


通过以上的介绍,我们对每个组成部分都有了基本的了解,但是涉及到工作的细节,我们尚有诸多疑问,例如,一个chunk的数据太大,如何切分?一个shard数据太多,如何迁移?在 replica set 中,如何选择primary?server挂了,怎么进行故障恢复?接下来的章节,我们逐个回答这些问题。


,出现元数据不一致的情况。

MongoDB 的官方文档建议,配置 3 个 config servers 比较合适,既提供了足够的安全性,又避免了更多的 config servers 实例之间的数据同步,引起的元数据不一致的麻烦。


Mongos

    用户使用MongoDB 时,用户的操作请求,全部由 mongos 来转发。

当 mongos 接收到用户请求时,它先查询 config server,找到存放相应数据的 shard servers。然后把用户请求,转发到这些 shard servers。当这些 shard servers完成操作后,它们把结果分别返回给 mongos。而当 mongos 汇总了所有的结果后,它把结果返回给用户。

Mongos 每次启动的时候,都要到 config servers 中读取元数据,并缓存在本地。每当 config server中的元数据有改动,它都会通知所有的 mongos。

Mongos 之间,不存在彼此协同工作的问题。因此,MongoDB 所需要配置的 mongos server的数量,没有限制。


通过以上的介绍,我们对每个组成部分都有了基本的了解,但是涉及到工作的细节,我们尚有诸多疑问,例如,一个chunk的数据太大,如何切分?一个shard数据太多,如何迁移?在 replica set 中,如何选择primary?server挂了,怎么进行故障恢复?接下来的章节,我们逐个回答这些问题。



推荐阅读
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了SpringCloudRibbon部分源码相关的知识,希望对你有一定的参考价值。1:ribbon是提供通过servi ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 本文介绍了将mysql从5.6.15升级到5.7.15的详细步骤,包括关闭访问、备份旧库、备份权限、配置文件备份、关闭旧数据库、安装二进制、替换配置文件以及启动新数据库等操作。 ... [详细]
  • Intellij IDEA中详细图解连接MySQL腾讯云数据库以及基础操作
    虽然小编记录的是在IDEA中连接mysql腾讯云数据库。当然,如果读者使用的是本地数据库,也是一样的操作,只是数据库的url书写有所不同。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
  • 本文介绍了在使用Laravel和sqlsrv连接到SQL Server 2016时,如何在插入查询中使用输出子句,并返回所需的值。同时讨论了使用CreatedOn字段返回最近创建的行的解决方法以及使用Eloquent模型创建后,值正确插入数据库但没有返回uniqueidentifier字段的问题。最后给出了一个示例代码。 ... [详细]
  • 负载均衡_Nginx反向代理动静分离负载均衡及rewrite隐藏路径详解(Nginx Apache MySQL Redis)–第二部分
    nginx反向代理、动静分离、负载均衡及rewrite隐藏路径详解 ... [详细]
  • 在单位的一台4cpu的服务器上部署了esxserver,挂载了6个虚拟机,目前运行正常。在安装部署过程中,得到了cnvz.net论坛精华区 ... [详细]
  • 域名解析系统DNS
    文章目录前言一、域名系统概述二、因特网的域名结构三、域名服务器1.根域名服务器2.顶级域名服务器(TLD,top-leveldomain)3.权威(Authoritative)域名 ... [详细]
  • 目录Atlas介绍Atlas部署Atlas基本管理Atlas结合MHA故障恢复读写分离建议Atlas介绍Atlas是由Qihoo360Web平台部基础架构团队开发维护的一个基于My ... [详细]
  • php网站设计实验报告,php网站开发实训报告
    本文目录一览:1、php动态网站设计的关键技术有哪些软件,及搭建步骤需要哪些页面,分别完成 ... [详细]
author-avatar
北京雅舍
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有