设为首页收藏本站

爱吱声

 找回密码
 注册
搜索
查看: 7887|回复: 19
打印 上一主题 下一主题

[信息技术] MongoDB架构概览

[复制链接]

该用户从未签到

跳转到指定楼层
楼主
发表于 2012-9-18 12:31:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    关于MongoDB,我们能看到的资料,基本都是在指导大家如何使用MongoDB,但是,MongoDB内部是如何运作的,资料不是很多。
% C( F9 V# ^8 h; h9 j+ ?7 ~8 ~$ h( i9 ^, ~% p
    阅读使用手册,会有很多疑惑之处。例如,有人说,MongoDB 等同于分布式的 MySQL。它把一个Table ,按 row,分割成多个Shards,分别存放在不同的 Servers 上。这种说法是否正确?
: P9 l# F& s: Y. L9 j; F* v0 i  }: `7 T
    不深入了解 MongoDB 的内部结构,就无法透彻地回答类似问题。这个系列文章,就来和大家探讨MongoDB的内部的工作方式。1 b& q( B* C5 U* i

) R, }& M1 x5 K; h6 k! J: z

+ |, V/ {3 |4 N1 x0 _" ?/ f, I/ f! U9 v2 C5 Z( N. P; n
图1-1 MongoDB架构图

0 i! ]* I5 z  K, R
7 o* ?& h% O8 u$ E/ _# {% D    MongoDB 通常运行在一个服务器集群上,而不是一个单机。图1-1,描述了一个MongoDB集群的基本组成部分,包括若干shards,至少一个config server,至少一个routing servers(又称 mongos)。. D* N" B! L9 {' \

0 E8 _# g2 ?: `Shards
3 O* z- g0 U9 o2 W+ p, s! A/ y& d! e% S' f: L- i
    MongoDB的最基本的数据单元,叫document,类似于关系式数据库中的行 row。一系列documents,组成了一个collection,相当于关系式数据库中的table。当一个 collection 数据量太大时,可以把该collection按documents切分,分成多个数据块,每个数据块叫做一个chunk,多个chunks聚集在一起,组成了一个shard。* o5 G  v/ m5 c: h7 L" y

* Y- q7 _, F  `    Sharding 的意义,不仅保障了数据库的扩容(scalability),同时也保障了系统的负载均衡(load balance)。
5 l- ], r  k( }$ i3 V
& F( }: d8 E1 n6 z  F; t" {    每一个shard存储在一个物理服务器(server)上。Server上运行着mongod进程,通过这个进程,对shard中的数据进行操作,主要是增删改查。
0 B3 F7 k4 `7 u, n" L! m9 h3 P  ^3 t9 E4 ]; F* P5 B
    如果系统中的每个shard,只存储了一份数据,没有备份,那么当这个shard所在的server挂了,数据就丢失了。在生产环境中,为了保证数据不丢失,为了提高系统的可用性(availability),每一个shard被存储多份,每个备份所在的servers,组成了一个replica set。) c7 A* G. O6 Y8 p# O" b' l
, ~) I9 @; l# h+ f- b
Shard keys
+ @! |' Y/ a% r        
8 s' D% {( n; G# A# n4 v    为了把collection切分成不同的chunks,从而存放到不同的shards中,我们需要制定一个切分的方式。: V2 o( E  A* O$ T$ N7 q8 ?( r

7 _9 }9 R; ]# v& {3 \& @6 Q    如前所述,在 MongoDB 数据库中,一个表collection由多个行 documents 组成,而每个 document,有多个属性 fields。同一个 collection 中的不同的 documents,可能会有不同的 fields。例如,有个 collection 叫 Media,包含两条 documents,
6 _# O4 `( ^4 Z" G$ N3 u2 }+ u, N7 `) F) p1 A3 f) e  l5 i
{
# E# P7 \( V& q! B, P  "ISBN": "987-30-3652-5130-82",& V7 a" d: {2 J$ Q5 g* W
  "Type": "CD",. e, o0 E; R1 e- E  [# z6 e
  "Author": "Nirvana"," ^% Y2 e" H1 Y2 q4 {
  "Title": "Nevermind",
/ u* q# A0 H+ H! [  "Genre": "Grunge",
6 U9 c( ~- C  M   "Releasedate": "1991.09.24",
/ _1 B" W5 y% I1 d. L( C( ?/ `   "Tracklist": [
4 e2 e- F4 B' I$ Y9 |     {& `& T% ^( c4 a: z1 H: M
        "Track" : "1",+ E( L$ i) m0 Q# |, D
        "Title" : "Smells like teen spirit",- U3 Z, _! ^3 f. w" j0 q1 D& p; f
        "Length" : "5:02"4 j+ y7 H2 q; Z) V+ i$ F+ g0 e
     },
6 f& S+ @7 W/ l- \- ]$ q     {- b$ H3 g; U2 l& {4 F. y6 B
        "Track" : "2",6 v9 S0 ]# E- l# v! Y$ p
        "Title" : "In Bloom",
6 ^  O( [6 _9 c        "Length" : "4:15"" z& r, n4 \& G; ^  x
     }
3 A9 V% Z! m" P' `   ]* r$ N; U1 X; }: r' N
}; z7 {8 N# Z! z
% h. p- c6 o0 p+ Q6 ~- ]3 u
{( ~' X- R% |- T/ T5 V& k; A
  "ISBN": "987-1-4302-3051-9",
# L2 v; e7 v) w% q# z; h1 @  "Type": "Book",
: x2 ?1 [# [0 u/ l/ F! i  "Title": "Definite Guide to MongoDB: The NoSQL Database",
! c7 H9 d1 T, [& n  "Publisher": "Apress",
2 g# D7 i" o0 S. C5 @8 F  "Author": " Eelco Plugge",
2 O6 `3 O) x2 G& S, k+ E  "Releasedate": "2011.06.09"6 o( e; T, U" ?- ~5 j7 n) {
}5 }2 \8 v! J& y  L% [
5 M- M. j' Y9 x9 W. R
    假如,在同一个 collection 中的所有 document,都包含某个共同的 field,例如前例中的“ISBN”,那么我们就可以按照这个 field 的值,来分割 collection。这个 field 的值,又称为 shard key。
: P0 G8 b0 Z; P3 P( t3 A& w4 B! H
" k) T: E9 S5 M  `) O    在选择shard key的时候,一定要确保这个key能够把collection均匀地切分成很多chunks。9 t" k, t$ f$ u. z9 |5 ~

  a! X6 A1 x5 O: ?    例如,如果我们选择“author”作为shard key,如果有大量的作者是重名的,那么就会有大量的数据聚集在同一个chunk中。当然,假设很少有作者同名同姓,那么“author”也可以作为一个shard key。换句话说,shard key 的选择,与使用场景密切相关。  K& A# o7 }* \8 H8 m0 B; @  U( W1 y

& n: t% L& P7 C4 p. |. ?    很多情况下,无论选择哪一个单一的 field 作为shard key,都无法均匀分割 collection。在这种情况下,我们可以考虑,用多个 fields,构成一个复合的shard key。
* ]' q9 ?/ s# m$ k5 H9 f1 [% g+ A* ~( C4 {) \5 }6 q
    延续前例,假如有很多作者同名同姓,他们都叫“王二”。用 author 作为 shard key,显然无法均匀切割 collection。这时我们可以加上release-date,组成name-date的复合 shard key,例如“王二 2011”。4 P% Z8 b& _. T2 e2 F- F* W
/ G! F: k% x* b0 \& N- T- g
Chunks  r! R8 w( i: h; Y1 e) d5 ]( n+ l# a
        
# W! @# `+ L8 @* [$ r( l3 s, ]1 b    MongoDB按 shard key,把 collection切割成若干 chunks。每个 chunk 的数据结构,是一个三元组,{collection,minKey,maxKey},如图1-2 所示。) E8 Q7 d3 o; H/ s+ t

2 b9 C/ N# x% Q

- E, Q; G9 K7 I( Z) e% D7 {6 Q图1-2 chunk的三元组
5 \" F$ c- Z/ B8 H6 ]# j3 c- V9 v
! M7 n' s5 l# Q. g
    其中,collection 是数据库中某一个表的名称,而 minKey 和 maxKey 是 shard key的范围。每一个 document 的shard key 的值,决定了这条document应该存放在哪个chunk中。
5 T- w* H& d  ]" W3 c6 z( q
1 M+ j  @+ e! @# V4 A8 b    如果两条 documents 的 shard keys 的值很接近,这两条 documents 很可能被存放在同一个 chunk 中。
$ ^/ a) L  d5 U, Z5 U$ j3 _: M  P. a6 I' j
    Shard key 的值的顺序,决定了 document 存放的 chunk。在 MongoDB 的文献中,这种切割 collection 的方式,称为order-preserving。2 @$ r8 M' d! t7 ]1 }+ o
+ b1 V3 K2 e! m3 `& e7 F2 e
    一个 chunk最多能够存储64MB的数据。 当某个chunk存储的 documents包含的数据量,接近这个阈值时,一个chunk会被切分成两个新的chunks。. J2 y$ N8 b* l$ j3 `. T

2 x" D4 {  w3 e1 H5 a' o  Y  ^    当一个shard存储了过多的chunks,这个shard中的某些chunks会被迁移到其它 shard中。
% j. M" f5 V5 i+ W) y1 Y1 a( j
3 d/ y7 K& c# P8 D! J' _5 H    这里有个问题,假如某一条 document 包含的数据量很大,超过 64MB,一个 chunk 存放不下,怎么办?在后续章节介绍 GridFS 时,我们会详细讨论。
  k( y. A0 D' t5 w0 e' f% z' ?& v$ n8 r% ?6 U# s# F5 ?4 u  {! ?
Replica set/ @* h% O5 h$ J% q; u: x' N
        8 F9 _1 x" g) g: k5 r
    在生产环境中,为了保证数据不丢失,为了提高系统的可用性(availability),每一个shard被存储多份,每个备份所在的servers,组成了一个replica set。
. @& K+ }, N* d. h# y3 f9 \6 T+ N* N
    这个replica set包括一个primary DB和多个secondary DBs。为了数据的一致性,所有的修改(insert / update / deletes) 请求都交给primary处理。处理结束之后,再异步地备份到其他secondary中。3 {2 J. S4 f5 d6 ~0 V+ w' z* V

0 Q6 _9 f; S& m0 A( C    Primary DB由replica set中的所有servers,共同选举产生。当这个primaryDB server出错的时候,可以从replica set中重新选举一个新的primaryDB,从而避免了单点故障。
% h9 B, y3 G3 Y, S9 ?1 ~1 q& C9 b; l
    Replica set的选举策略和数据同步机制,确保了系统的数据的一致性。后文详述。0 S7 s5 ^3 Y7 ^" x1 ~& C

! @, v, J3 {; _  O, sConfig Server
( r# e7 x8 G. H& q        
+ Y& I8 d& b7 a    Config servers用于存储MongoDB集群的元数据 metadata,这些元数据包括如下两个部分,每一个shard server包括哪些chunks,每个chunk存储了哪些 collections 的哪些 documents。
# T' L! t# x) d5 G
( t" ]2 a: I- b+ ^; ~    每一个config server都包括了MongoDB中所有chunk的信息。
  b3 _+ X4 S1 Z7 n0 V
* o2 y! `; F, c5 N3 o    Config server也需要 replication。但是有趣的是,config server 采用了自己独特的replication模式,而没有沿用 replica set。
0 r  f; |" J7 S0 t. `3 o3 O0 M1 S$ N% _" N& Y0 [! s
    如果任何一台config server挂了,整个 config server 集群中,其它 config server变成只读状态。这样做的原因,是避免在系统不稳定的情况下,冒然对元数据做任何改动,导致在不同的 config servers 中,出现元数据不一致的情况。) c3 v5 ~' d" H" A

/ s: m5 m' z( S5 K" x* K) ~  _    MongoDB的官方文档建议,配置3个config servers比较合适,既提供了足够的安全性,又避免了更多的config servers实例之间的数据同步,引起的元数据不一致的麻烦。
3 v3 }8 \! G1 Y1 n5 X, @
7 h; K& ]5 Q% {" F: @  E/ s! O7 OMongos1 A7 y2 d' `) s8 |. O! ^6 W0 w+ O
% U& t1 X& O4 c9 o* p# ]
    用户使用MongoDB 时,用户的操作请求,全部由mongos来转发。: ?' N8 _4 H( S6 O- s* r, a
% g* G9 Z9 w2 Q# p( w6 o5 v
    当 mongos 接收到用户请求时,它先查询 config server,找到存放相应数据的shard servers。然后把用户请求,转发到这些 shard servers。当这些 shard servers完成操作后,它们把结果分别返回给 mongos。而当 mongos 汇总了所有的结果后,它把结果返回给用户。
# `: I5 u. }& D4 Z+ c! k
3 ~6 V2 [% R1 u( ^" }' [    Mongos每次启动的时候,都要到config servers中读取元数据,并缓存在本地。每当 config server中的元数据有改动,它都会通知所有的mongos。
$ T0 o5 l. U3 e$ o( R9 e' G" h7 L) D
    Mongos之间,不存在彼此协同工作的问题。因此,MongoDB所需要配置的mongos server的数量,没有限制。
7 Z/ ^# n' i6 p/ y7 \6 V2 L( i$ `" s
    通过以上的介绍,我们对每个组成部分都有了基本的了解,但是涉及到工作的细节,我们尚有诸多疑问,例如,一个chunk的数据太大,如何切分?一个shard数据太多,如何迁移?在replica set中,如何选择primary?server挂了,怎么进行故障恢复?接下来的章节,我们逐个回答这些问题。# J; }( a2 f$ B# _5 R+ |

5 K' \7 x  P8 P1 f/ t8 ]# L! e1 m0 e( w
Reference,
+ Z, W% p( ~4 l* P3 D6 _, D6 q0 Z- e! J) K
[0] Architectural Overview
+ u/ v3 D5 S* G3 E5 ^) l3 Ohttp://www.mongodb.org/display/DOCS/Sharding+Introduction
) [( }8 ^+ \  k

评分

参与人数 1爱元 +10 学识 +5 收起 理由
不爱吱声 + 10 + 5 谢谢!有你,爱坛更精彩

查看全部评分

该用户从未签到

沙发
发表于 2012-9-18 12:40:50 | 只看该作者
本帖最后由 PenPen 于 2012-9-18 12:44 编辑
  M" u. g/ t2 l& a- B  H
+ [! ?: X: A0 l! M0 z0 f% ?" B
0 e* m. h# W$ l. p& K! R' ~您是和邓侃一起写文章的盛楠么?

该用户从未签到

板凳
 楼主| 发表于 2012-9-18 12:44:19 | 只看该作者
呃。。。是我啊。。。

该用户从未签到

地板
 楼主| 发表于 2012-9-18 12:44:45 | 只看该作者
PenPen 发表于 2012-9-18 12:40 9 A" b1 V0 n) M3 r  v2 I
您是和邓侃一起写文章的盛楠么?
' @# ^% A2 J7 i) P
是我啊。。。这都能被认出来。。。

该用户从未签到

5#
发表于 2012-9-18 12:47:20 | 只看该作者
shengnan007 发表于 2012-9-18 12:44 4 N) l1 h" k  Z8 R
是我啊。。。这都能被认出来。。。
1 w! |7 @9 P( z8 F  Y
这篇文章我读过。开始以为是转贴的,后来再一看id就发现真相了~

该用户从未签到

6#
 楼主| 发表于 2012-9-18 12:49:50 | 只看该作者
PenPen 发表于 2012-9-18 12:47 ( q. G3 B! ^! C, g
这篇文章我读过。开始以为是转贴的,后来再一看id就发现真相了~

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

点评

你已经是会员了~  发表于 2012-9-18 12:50
  • TA的每日心情
    奋斗
    2022-2-8 01:13
  • 签到天数: 171 天

    [LV.7]分神

    7#
    发表于 2012-9-18 12:51:42 | 只看该作者
    shengnan007 发表于 2012-9-17 22:49
    3 Q1 s9 C4 s; x* B0 {. q' \. E! u多谢支持。还有两篇一会帖过来。后续的还在写。边看源码边写,比较慢,hoho。这里是要推荐才能变成正式会 ...
      T# U$ P" F6 i! a* O3 [: I3 d
    欢迎,欢迎,已经给你变成正式会员了。

    该用户从未签到

    8#
     楼主| 发表于 2012-9-18 12:57:15 | 只看该作者
    不爱吱声 发表于 2012-9-18 12:51 / J  z3 N0 n, H; L' n
    欢迎,欢迎,已经给你变成正式会员了。

      b# Y* T' O8 O: c' v- t多谢多谢啦~~
  • TA的每日心情
    慵懒
    2020-1-15 02:37
  • 签到天数: 1287 天

    [LV.10]大乘

    9#
    发表于 2012-9-19 03:38:34 | 只看该作者
    我们现在的 technology stack 就是 php + mongodb,涉及财务方面的东西用 postgres。
    2 e' g1 [. h. |6 D; z; j0 i* p* _7 A& x# ?$ \

    该用户从未签到

    10#
    发表于 2012-9-19 04:21:40 | 只看该作者
    谢谢。8 o8 f; k% C8 Q# l$ Z* G
    * w4 ~9 G. o2 w+ I7 t* W4 H7 S
    中文看得真累,大部分还是英文术语。
    ; h- m# e0 ^+ H! D  I! U3 y$ Z8 r% ?
    这应该是一个系列吧,后面怎样寻找,执行指令等开始入门,还是说的太简单了。  i- A3 S: O* ?' q
    - m- X/ j" b! ^
    现在distributed DB在那些大网站很重要,现在开始有跟已有DB分庭抗礼的苗头,不过不是那里工作的话,其中的奥妙大概难说清楚。

    该用户从未签到

    11#
     楼主| 发表于 2012-9-19 08:40:52 | 只看该作者
    巴山 发表于 2012-9-19 03:38
    5 q, K3 H9 g7 P, }  b$ f9 `我们现在的 technology stack 就是 php + mongodb,涉及财务方面的东西用 postgres。' E# ?4 t- V! t+ \
    & V% m  V# a# ~4 ?6 \: N
    ...
    0 f2 c) H/ Y' @6 V& }
    mongoDB作为存储是没有问题的,财务这种核心数据,还是不建议使用mongoDB的

    点评

    主要是transaction acid的问题。  发表于 2012-9-27 17:12

    该用户从未签到

    12#
     楼主| 发表于 2012-9-19 08:44:52 | 只看该作者
    梦晓半生 发表于 2012-9-19 04:21
    0 P0 W4 H. k7 X7 i' M# O谢谢。) |  q2 {  R; q! @+ _. g3 `6 j
    - F3 M  Y# k; q
    中文看得真累,大部分还是英文术语。

    6 |: B* K, `' {) H1 u1 }: W现在关于mongoDB的文章,大部分都是在告诉大家怎么用,涉及到内部运行机理的文章,数量不多,而且不成体系。这个系列文章的目的,是让大家了解mongoDB的基本的运行机理,这样以后使用的时候,可以知其所以然。但是由于这方面的资料很少,我也是到处找资料,写了这么几篇,再往后,就是边使用,边看源码,边写了。
  • TA的每日心情
    奋斗
    2018-1-6 00:24
  • 签到天数: 1 天

    [LV.1]炼气

    13#
    发表于 2012-9-19 14:16:01 | 只看该作者
    shengnan007 发表于 2012-9-18 12:44
    * u0 s9 {; Z) d$ j( s是我啊。。。这都能被认出来。。。

    ! L, O! t% z2 X6 M是邓嫂么?

    该用户从未签到

    14#
     楼主| 发表于 2012-9-19 14:17:53 | 只看该作者
    profer 发表于 2012-9-19 14:16 5 d$ h/ p5 t8 u' Y' p) L- q
    是邓嫂么?
    ' a: N: g$ ?7 l2 J
    是邓的小兵
  • TA的每日心情
    奋斗
    2019-9-9 20:24
  • 签到天数: 1 天

    [LV.1]炼气

    15#
    发表于 2012-9-19 18:35:28 | 只看该作者
    有点惊讶 居然在这里看到这篇文章 呵呵 静待大作

    该用户从未签到

    16#
    发表于 2012-9-20 00:57:50 | 只看该作者
    shengnan007 发表于 2012-9-19 08:44
    : V1 ]# h( X4 R9 B现在关于mongoDB的文章,大部分都是在告诉大家怎么用,涉及到内部运行机理的文章,数量不多,而且不成体 ...

    " f! t2 p9 T8 k" t& _太好了,期待中,希望都带上英文reference。
    6 T# @8 f! K8 Z# B
    8 p5 l! w0 G  B/ K' e现在这种新技术很多,Mongo是比较流行的一个,我这里附带一下一堆NoSQL的新系统,到最后估计会有几个胜出。
    # j  E4 W) u$ P  z) H
    ) i+ Y: [5 m% T! ^http://en.wikipedia.org/wiki/NoSQL

    该用户从未签到

    17#
     楼主| 发表于 2012-9-20 08:53:41 | 只看该作者
    梦晓半生 发表于 2012-9-20 00:57 8 W" B# |  h$ c; _
    太好了,期待中,希望都带上英文reference。
    / q& c8 r: t8 V/ v4 e) m: f4 q5 [' H8 n+ i% E  A8 d" q
    现在这种新技术很多,Mongo是比较流行的一个,我这里附带一 ...

    , o3 _; o: ^7 _7 N/ Z7 d& N! L1 a现在写的也很纠结,资料太少了,哈哈

    该用户从未签到

    18#
    发表于 2012-9-21 11:52:33 | 只看该作者
    shengnan007 发表于 2012-9-20 08:53 ! e, {9 q# }& p9 p! ~
    现在写的也很纠结,资料太少了,哈哈
    + b+ y2 ~( V! N3 g! s6 S
    建议从NoSQL写起,这是推动新数据库设计的需求关系,原始动力。( c! D# E& k% Y9 M
    9 d( m' m: I1 z9 g6 g# C- C
    http://en.wikipedia.org/wiki/NoSQL* y* A7 p( R: ?7 T1 a( B" E
    6 e* E0 `: `: g; F" l" F
  • TA的每日心情
    郁闷
    2019-4-22 08:49
  • 签到天数: 38 天

    [LV.5]元婴

    19#
    发表于 2012-9-21 17:03:12 | 只看该作者
    恶魔吹笛来 发表于 2012-9-19 18:35 3 n% Q# S) E) K' R2 c2 e- x
    有点惊讶 居然在这里看到这篇文章 呵呵 静待大作
    ( Q2 }9 `+ o% ^5 \* @- K8 d
    有什么可惊讶的邓侃在前一个爱坛版本是很早的注册用户呢,从开心网一块迁移的。。。

    该用户从未签到

    20#
     楼主| 发表于 2012-9-24 09:11:03 | 只看该作者
    梦晓半生 发表于 2012-9-21 11:52 9 N) b  B7 \4 s" [: ]
    建议从NoSQL写起,这是推动新数据库设计的需求关系,原始动力。
    . W1 T. b8 I- k3 j) Q; Q
    : Y, A! S, k5 G$ V% ^7 Hhttp://en.wikipedia.org/wiki/NoSQL
    8 d% s3 P8 K# K0 {
    好的好的,现在这个写完,然后开始写nosql

    手机版|小黑屋|Archiver|网站错误报告|爱吱声   

    GMT+8, 2025-10-14 16:32 , Processed in 0.042973 second(s), 21 queries , Gzip On.

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表