shengnan007 发表于 2012-9-18 12:31:10

MongoDB架构概览

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

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

    不深入了解 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存储在一个物理服务器(server)上。Server上运行着mongod进程,通过这个进程,对shard中的数据进行操作,主要是增删改查。

    如果系统中的每个shard,只存储了一份数据,没有备份,那么当这个shard所在的server挂了,数据就丢失了。在生产环境中,为了保证数据不丢失,为了提高系统的可用性(availability),每一个shard被存储多份,每个备份所在的servers,组成了一个replica set。

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 所示。


图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挂了,怎么进行故障恢复?接下来的章节,我们逐个回答这些问题。


Reference,

Architectural Overview
http://www.mongodb.org/display/DOCS/Sharding+Introduction

PenPen 发表于 2012-9-18 12:40:50

本帖最后由 PenPen 于 2012-9-18 12:44 编辑


您是和邓侃一起写文章的盛楠么?{:soso__3497941138224448238_4:}

shengnan007 发表于 2012-9-18 12:44:19

呃。。。是我啊。。。

shengnan007 发表于 2012-9-18 12:44:45

PenPen 发表于 2012-9-18 12:40 static/image/common/back.gif
您是和邓侃一起写文章的盛楠么?

是我啊。。。这都能被认出来。。。

PenPen 发表于 2012-9-18 12:47:20

shengnan007 发表于 2012-9-18 12:44 static/image/common/back.gif
是我啊。。。这都能被认出来。。。

这篇文章我读过。开始以为是转贴的,后来再一看id就发现真相了~

shengnan007 发表于 2012-9-18 12:49:50

PenPen 发表于 2012-9-18 12:47 static/image/common/back.gif
这篇文章我读过。开始以为是转贴的,后来再一看id就发现真相了~

多谢支持。还有两篇一会帖过来。后续的还在写。边看源码边写,比较慢,hoho。这里是要推荐才能变成正式会员是么?

不爱吱声 发表于 2012-9-18 12:51:42

shengnan007 发表于 2012-9-17 22:49 static/image/common/back.gif
多谢支持。还有两篇一会帖过来。后续的还在写。边看源码边写,比较慢,hoho。这里是要推荐才能变成正式会 ...

欢迎,欢迎,{:209:}已经给你变成正式会员了。

shengnan007 发表于 2012-9-18 12:57:15

不爱吱声 发表于 2012-9-18 12:51 static/image/common/back.gif
欢迎,欢迎,已经给你变成正式会员了。

多谢多谢啦~~

巴山 发表于 2012-9-19 03:38:34

我们现在的 technology stack 就是 php + mongodb,涉及财务方面的东西用 postgres。

梦晓半生 发表于 2012-9-19 04:21:40

谢谢。

中文看得真累,大部分还是英文术语。{:191:}

这应该是一个系列吧,后面怎样寻找,执行指令等开始入门,还是说的太简单了。

现在distributed DB在那些大网站很重要,现在开始有跟已有DB分庭抗礼的苗头,不过不是那里工作的话,其中的奥妙大概难说清楚。

shengnan007 发表于 2012-9-19 08:40:52

巴山 发表于 2012-9-19 03:38 static/image/common/back.gif
我们现在的 technology stack 就是 php + mongodb,涉及财务方面的东西用 postgres。

...

mongoDB作为存储是没有问题的,财务这种核心数据,还是不建议使用mongoDB的

shengnan007 发表于 2012-9-19 08:44:52

梦晓半生 发表于 2012-9-19 04:21 static/image/common/back.gif
谢谢。

中文看得真累,大部分还是英文术语。


现在关于mongoDB的文章,大部分都是在告诉大家怎么用,涉及到内部运行机理的文章,数量不多,而且不成体系。这个系列文章的目的,是让大家了解mongoDB的基本的运行机理,这样以后使用的时候,可以知其所以然。但是由于这方面的资料很少,我也是到处找资料,写了这么几篇,再往后,就是边使用,边看源码,边写了。

profer 发表于 2012-9-19 14:16:01

shengnan007 发表于 2012-9-18 12:44 static/image/common/back.gif
是我啊。。。这都能被认出来。。。

是邓嫂么?

shengnan007 发表于 2012-9-19 14:17:53

profer 发表于 2012-9-19 14:16 static/image/common/back.gif
是邓嫂么?

是邓的小兵

恶魔吹笛来 发表于 2012-9-19 18:35:28

有点惊讶 居然在这里看到这篇文章 呵呵 静待大作

梦晓半生 发表于 2012-9-20 00:57:50

shengnan007 发表于 2012-9-19 08:44 static/image/common/back.gif
现在关于mongoDB的文章,大部分都是在告诉大家怎么用,涉及到内部运行机理的文章,数量不多,而且不成体 ...

太好了,期待中,希望都带上英文reference。

现在这种新技术很多,Mongo是比较流行的一个,我这里附带一下一堆NoSQL的新系统,到最后估计会有几个胜出。

http://en.wikipedia.org/wiki/NoSQL

shengnan007 发表于 2012-9-20 08:53:41

梦晓半生 发表于 2012-9-20 00:57 static/image/common/back.gif
太好了,期待中,希望都带上英文reference。

现在这种新技术很多,Mongo是比较流行的一个,我这里附带一 ...

现在写的也很纠结,资料太少了,哈哈

梦晓半生 发表于 2012-9-21 11:52:33

shengnan007 发表于 2012-9-20 08:53 static/image/common/back.gif
现在写的也很纠结,资料太少了,哈哈

建议从NoSQL写起,这是推动新数据库设计的需求关系,原始动力。

http://en.wikipedia.org/wiki/NoSQL

定风波 发表于 2012-9-21 17:03:12

恶魔吹笛来 发表于 2012-9-19 18:35 static/image/common/back.gif
有点惊讶 居然在这里看到这篇文章 呵呵 静待大作

有什么可惊讶的邓侃在前一个爱坛版本是很早的注册用户呢,从开心网一块迁移的。。。

shengnan007 发表于 2012-9-24 09:11:03

梦晓半生 发表于 2012-9-21 11:52 static/image/common/back.gif
建议从NoSQL写起,这是推动新数据库设计的需求关系,原始动力。

http://en.wikipedia.org/wiki/NoSQL


好的好的,现在这个写完,然后开始写nosql
页: [1] 2
查看完整版本: MongoDB架构概览