设为首页收藏本站

爱吱声

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

[信息技术] MongoDB架构概览

[复制链接]

该用户从未签到

跳转到指定楼层
楼主
发表于 2012-9-18 12:31:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    关于MongoDB,我们能看到的资料,基本都是在指导大家如何使用MongoDB,但是,MongoDB内部是如何运作的,资料不是很多。
/ j7 G5 C2 H( l5 I
# Q. {3 G/ e* L# F/ u* U2 Q    阅读使用手册,会有很多疑惑之处。例如,有人说,MongoDB 等同于分布式的 MySQL。它把一个Table ,按 row,分割成多个Shards,分别存放在不同的 Servers 上。这种说法是否正确?3 y+ e4 T& ^3 m3 J) `4 V6 g. A
$ U! n' }( R0 Q- u5 d
    不深入了解 MongoDB 的内部结构,就无法透彻地回答类似问题。这个系列文章,就来和大家探讨MongoDB的内部的工作方式。8 r2 _& u# {( G
" h' T4 N% m/ g; k4 m
; B) H; e( o4 e0 j& Z

- h* \1 F  S1 g# H4 o图1-1 MongoDB架构图
2 L2 `- ]1 b; M0 U

* \, w+ [- f4 b4 H+ L    MongoDB 通常运行在一个服务器集群上,而不是一个单机。图1-1,描述了一个MongoDB集群的基本组成部分,包括若干shards,至少一个config server,至少一个routing servers(又称 mongos)。' H( K( W3 B) K

$ P, ^- b# d2 Z& w5 G/ _% E0 pShards
3 N; S3 s% a5 ^
9 G. Z6 ~) P9 K+ W    MongoDB的最基本的数据单元,叫document,类似于关系式数据库中的行 row。一系列documents,组成了一个collection,相当于关系式数据库中的table。当一个 collection 数据量太大时,可以把该collection按documents切分,分成多个数据块,每个数据块叫做一个chunk,多个chunks聚集在一起,组成了一个shard。! r3 H/ O7 U8 [9 N! Z
: q) g/ t4 ?( m3 {2 x9 M
    Sharding 的意义,不仅保障了数据库的扩容(scalability),同时也保障了系统的负载均衡(load balance)。
* W- t3 X2 a$ `+ b3 t6 {
# J. W/ U( W9 v. I    每一个shard存储在一个物理服务器(server)上。Server上运行着mongod进程,通过这个进程,对shard中的数据进行操作,主要是增删改查。( [. O' W7 M2 K0 G+ g" f/ g* ]

5 x9 h( O" U  u0 Q    如果系统中的每个shard,只存储了一份数据,没有备份,那么当这个shard所在的server挂了,数据就丢失了。在生产环境中,为了保证数据不丢失,为了提高系统的可用性(availability),每一个shard被存储多份,每个备份所在的servers,组成了一个replica set。; f, |$ \6 {% Q! Y& N3 Q
3 l' @- D. a$ b# ~: E' K
Shard keys
: ?' K% i& P% l$ _        ( U; \7 t9 H3 X" L) e$ I2 `
    为了把collection切分成不同的chunks,从而存放到不同的shards中,我们需要制定一个切分的方式。* c  w/ j0 O& k; [7 y* }

% R# x2 f1 {% h0 f- w1 Z% T    如前所述,在 MongoDB 数据库中,一个表collection由多个行 documents 组成,而每个 document,有多个属性 fields。同一个 collection 中的不同的 documents,可能会有不同的 fields。例如,有个 collection 叫 Media,包含两条 documents,' ~; Q, a% m# y; }5 y" l" U# H
! `" z5 W) N  b+ H
{& [* h3 `1 n7 L$ q' u
  "ISBN": "987-30-3652-5130-82",. W* p8 ^  w/ T9 e
  "Type": "CD",1 Y) Z- n. b4 K( D3 K" i; `
  "Author": "Nirvana",
& ^. m* }& ?* E; K. b  "Title": "Nevermind",
: C- V. ~& r5 S+ Q2 P- {  "Genre": "Grunge",- s3 s$ L4 h! j! |9 |
   "Releasedate": "1991.09.24",: M4 J, a) x; J6 h
   "Tracklist": [' s4 F, `/ k% k- A3 O) y5 l
     {# }" X) C* b$ P
        "Track" : "1",/ J" U# d+ P8 J  _7 _, I" F; g
        "Title" : "Smells like teen spirit",& T: F7 |0 l: z
        "Length" : "5:02"" z. C" D' I7 X# W9 h$ B) N
     },' W0 V- Z& l) f+ n5 r, A
     {
6 r3 f. D9 f: R/ R& W: j: L. x        "Track" : "2",
8 o4 H3 _! n+ Z) S+ a        "Title" : "In Bloom",6 l# H4 A  H4 r& k+ B6 D
        "Length" : "4:15"
4 ^) A* l6 G$ H8 Z8 a, S# @0 T     }
6 V6 g9 W' N, d, S4 M1 }   ]
+ P7 _; K" k' N9 n5 ?# L) I}
! r0 r! b  |& l8 L/ h3 d
, Y3 Y: G7 q! q{
& M  u8 ~+ T8 I$ d& J6 J& n  "ISBN": "987-1-4302-3051-9",
$ k9 W3 U, D# A) {0 d7 R" O0 R  "Type": "Book",. M' W9 y9 w4 F6 w9 C
  "Title": "Definite Guide to MongoDB: The NoSQL Database",9 X  Q2 c. w' r. \- k' W
  "Publisher": "Apress",
% K' m- @% L: H6 K: C& z$ |  "Author": " Eelco Plugge",
) S* `& F' n- V. c  "Releasedate": "2011.06.09"
1 ~! U) q8 i6 f/ L9 K! W7 j}% S, C4 W0 y: A; Q- U' P9 S2 ]
; C3 D& X; \* t
    假如,在同一个 collection 中的所有 document,都包含某个共同的 field,例如前例中的“ISBN”,那么我们就可以按照这个 field 的值,来分割 collection。这个 field 的值,又称为 shard key。
0 \; U7 h. D" H$ T5 w$ j  f+ s4 e2 {' i$ B$ \& _. q& }
    在选择shard key的时候,一定要确保这个key能够把collection均匀地切分成很多chunks。
: U6 U% u: w) r/ c' p. p4 F1 I9 T2 f4 H/ ?% S. j& W
    例如,如果我们选择“author”作为shard key,如果有大量的作者是重名的,那么就会有大量的数据聚集在同一个chunk中。当然,假设很少有作者同名同姓,那么“author”也可以作为一个shard key。换句话说,shard key 的选择,与使用场景密切相关。
; g; @* _4 `# {6 u3 g" C8 G3 c" {* z# `% _; ~
    很多情况下,无论选择哪一个单一的 field 作为shard key,都无法均匀分割 collection。在这种情况下,我们可以考虑,用多个 fields,构成一个复合的shard key。
# Q+ H8 f) n$ F# U; h) M3 L# x3 B6 ^
    延续前例,假如有很多作者同名同姓,他们都叫“王二”。用 author 作为 shard key,显然无法均匀切割 collection。这时我们可以加上release-date,组成name-date的复合 shard key,例如“王二 2011”。# T! z. h# e4 ?# @: S3 z

+ A& R) J- [" w. N+ SChunks
/ O) a+ ~* U3 [3 A1 p8 d6 q        
; {$ B$ i; j( a+ B" Z0 o    MongoDB按 shard key,把 collection切割成若干 chunks。每个 chunk 的数据结构,是一个三元组,{collection,minKey,maxKey},如图1-2 所示。
2 O! @, A0 _6 }2 K7 k& \: V/ L
! u, A2 a: j/ F( h
! `0 [; A- ^0 w2 {& V/ g
图1-2 chunk的三元组

* c1 z- W  i8 Q7 C- s, u$ F0 z& ~/ S6 j& B7 Z# ]9 X1 r1 |8 K
    其中,collection 是数据库中某一个表的名称,而 minKey 和 maxKey 是 shard key的范围。每一个 document 的shard key 的值,决定了这条document应该存放在哪个chunk中。
8 P7 t: y4 o5 [5 C
9 O3 M$ R( f, ~: K7 Z$ k& C  ^    如果两条 documents 的 shard keys 的值很接近,这两条 documents 很可能被存放在同一个 chunk 中。
  P( b; [& ^' k
3 H& P. m& t2 l; \1 x. k& Y( D    Shard key 的值的顺序,决定了 document 存放的 chunk。在 MongoDB 的文献中,这种切割 collection 的方式,称为order-preserving。5 y  U! N9 r' |& R+ v* N# C+ I/ d8 i
9 _  X  Z6 e# d2 \6 d- ?
    一个 chunk最多能够存储64MB的数据。 当某个chunk存储的 documents包含的数据量,接近这个阈值时,一个chunk会被切分成两个新的chunks。4 `" c4 j. m% _  ?* `! d

6 A; n) l1 Z$ F5 i+ ~& f; L% R0 x6 r    当一个shard存储了过多的chunks,这个shard中的某些chunks会被迁移到其它 shard中。
4 r% T% v3 F2 @' ~8 t- K, h' `: A5 H# d1 w
    这里有个问题,假如某一条 document 包含的数据量很大,超过 64MB,一个 chunk 存放不下,怎么办?在后续章节介绍 GridFS 时,我们会详细讨论。: _' L% J! _3 L% Y6 _, A1 B

5 o; F( c5 ]" I! A. R7 BReplica set+ {2 q: F3 L0 D  O; A5 K
        
3 o6 A0 i) S# c2 A0 w  K    在生产环境中,为了保证数据不丢失,为了提高系统的可用性(availability),每一个shard被存储多份,每个备份所在的servers,组成了一个replica set。
% h  B2 r4 K4 a# {& ]# S! ?  K' y$ G/ }7 L+ l* r+ n) C
    这个replica set包括一个primary DB和多个secondary DBs。为了数据的一致性,所有的修改(insert / update / deletes) 请求都交给primary处理。处理结束之后,再异步地备份到其他secondary中。5 k9 n& c$ q* n5 h+ R1 A. q' `

! k) E4 w. c. R7 [8 _. n) m# E: i    Primary DB由replica set中的所有servers,共同选举产生。当这个primaryDB server出错的时候,可以从replica set中重新选举一个新的primaryDB,从而避免了单点故障。
6 i. a, {5 H9 A! M
* J/ y, B0 h7 i8 T' t2 h8 _$ c    Replica set的选举策略和数据同步机制,确保了系统的数据的一致性。后文详述。
4 n6 Y7 ?$ s5 `
6 \8 d/ C! P1 G4 {$ G# H7 f1 C3 SConfig Server& Q2 s; d) D6 \: u( h' ^; \' m0 b
        6 s3 b& W: e! I0 _
    Config servers用于存储MongoDB集群的元数据 metadata,这些元数据包括如下两个部分,每一个shard server包括哪些chunks,每个chunk存储了哪些 collections 的哪些 documents。
& {* p, f6 Z: g; j1 l% J) O$ y* B& Q* e9 }# _
    每一个config server都包括了MongoDB中所有chunk的信息。
( H, t4 Z* [3 H( p9 d
$ B% i; [  |" f" M* Q1 S* g% l, w    Config server也需要 replication。但是有趣的是,config server 采用了自己独特的replication模式,而没有沿用 replica set。1 {2 A9 ~# G8 D6 t- Y( g
& a- J5 |! W! n% C) b0 \
    如果任何一台config server挂了,整个 config server 集群中,其它 config server变成只读状态。这样做的原因,是避免在系统不稳定的情况下,冒然对元数据做任何改动,导致在不同的 config servers 中,出现元数据不一致的情况。, p5 f( n. I! v+ V2 D" X6 Z

& K0 ]4 |4 T: `3 b5 n0 \0 O- {0 m: P    MongoDB的官方文档建议,配置3个config servers比较合适,既提供了足够的安全性,又避免了更多的config servers实例之间的数据同步,引起的元数据不一致的麻烦。" J) e- C+ O' f" }. h# |8 Z. G4 K

+ [) x1 b5 R& ~1 U8 e' MMongos
- f/ H$ U, j  ]. w* a- g8 i& ?0 D5 m- \7 \
    用户使用MongoDB 时,用户的操作请求,全部由mongos来转发。
5 P8 c- L  O. {( {& d2 M' A! s
! N  w: }& S( n6 j    当 mongos 接收到用户请求时,它先查询 config server,找到存放相应数据的shard servers。然后把用户请求,转发到这些 shard servers。当这些 shard servers完成操作后,它们把结果分别返回给 mongos。而当 mongos 汇总了所有的结果后,它把结果返回给用户。: H. B4 e' @8 H0 P
0 G! u" _1 ^& h! J/ J/ A( A
    Mongos每次启动的时候,都要到config servers中读取元数据,并缓存在本地。每当 config server中的元数据有改动,它都会通知所有的mongos。
) T2 u# {$ y0 H$ p( m+ @$ P6 L* t+ h
    Mongos之间,不存在彼此协同工作的问题。因此,MongoDB所需要配置的mongos server的数量,没有限制。
' ^4 t3 m$ N; y, k: g
4 q8 }7 n" ^5 X    通过以上的介绍,我们对每个组成部分都有了基本的了解,但是涉及到工作的细节,我们尚有诸多疑问,例如,一个chunk的数据太大,如何切分?一个shard数据太多,如何迁移?在replica set中,如何选择primary?server挂了,怎么进行故障恢复?接下来的章节,我们逐个回答这些问题。
, ^( X0 |8 G% Z, v* Q2 @& H2 `  U, k% s$ P, v: s0 X# u& f
8 H  A6 V6 e0 O9 f: I
Reference,
% R) }: [2 b8 Y8 t) \9 J5 o' \) `  H% I
[0] Architectural Overview3 j; |% e4 o( e2 x8 e  g
http://www.mongodb.org/display/DOCS/Sharding+Introduction5 t) O1 v8 L7 B

评分

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

查看全部评分

该用户从未签到

沙发
发表于 2012-9-18 12:40:50 | 只看该作者
本帖最后由 PenPen 于 2012-9-18 12:44 编辑   e% l, }/ R6 C( Z+ ~5 C

" s$ s) [2 [1 Y/ u7 G$ b4 T
0 O9 S7 j* x7 {& F, s您是和邓侃一起写文章的盛楠么?

该用户从未签到

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

该用户从未签到

地板
 楼主| 发表于 2012-9-18 12:44:45 | 只看该作者
PenPen 发表于 2012-9-18 12:40 0 I+ q% Q9 J( B4 N( B( z% m5 `
您是和邓侃一起写文章的盛楠么?
3 P4 U/ P! g# Y) x  W
是我啊。。。这都能被认出来。。。

该用户从未签到

5#
发表于 2012-9-18 12:47:20 | 只看该作者
shengnan007 发表于 2012-9-18 12:44 ) L' k9 C: W8 p4 K
是我啊。。。这都能被认出来。。。
) y4 P0 ^8 j3 `: T$ X: y
这篇文章我读过。开始以为是转贴的,后来再一看id就发现真相了~

该用户从未签到

6#
 楼主| 发表于 2012-9-18 12:49:50 | 只看该作者
PenPen 发表于 2012-9-18 12:47 ; t0 ]& O3 T6 u! p: a* b
这篇文章我读过。开始以为是转贴的,后来再一看id就发现真相了~
0 y$ D) E% Y- \, U1 x( S
多谢支持。还有两篇一会帖过来。后续的还在写。边看源码边写,比较慢,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 ( W8 j8 }6 n$ Q; m) z: j
    多谢支持。还有两篇一会帖过来。后续的还在写。边看源码边写,比较慢,hoho。这里是要推荐才能变成正式会 ...
    . ~. T$ b, C4 z/ c# |: t
    欢迎,欢迎,已经给你变成正式会员了。

    该用户从未签到

    8#
     楼主| 发表于 2012-9-18 12:57:15 | 只看该作者
    不爱吱声 发表于 2012-9-18 12:51 4 m$ L' @7 O8 {
    欢迎,欢迎,已经给你变成正式会员了。

    + t" B& K" U! K8 M- ~/ q多谢多谢啦~~
  • TA的每日心情
    慵懒
    2020-1-15 02:37
  • 签到天数: 1287 天

    [LV.10]大乘

    9#
    发表于 2012-9-19 03:38:34 | 只看该作者
    我们现在的 technology stack 就是 php + mongodb,涉及财务方面的东西用 postgres。
    & I4 o3 n) d3 @+ q% k4 S6 H1 ]! l1 Y) ^5 q- G

    该用户从未签到

    10#
    发表于 2012-9-19 04:21:40 | 只看该作者
    谢谢。
    . Y- X9 E9 J- k* p" }( M8 n+ [% x/ N$ r& P! w+ j0 r2 {! a
    中文看得真累,大部分还是英文术语。
    . o( K; W6 X5 k" Z2 {2 S# b+ K6 |. k6 V$ ~% W
    这应该是一个系列吧,后面怎样寻找,执行指令等开始入门,还是说的太简单了。( J) s- B; X& b5 F2 P! N. H$ t# h

    4 g9 t1 ~" k2 A. Z* H/ x& i现在distributed DB在那些大网站很重要,现在开始有跟已有DB分庭抗礼的苗头,不过不是那里工作的话,其中的奥妙大概难说清楚。

    该用户从未签到

    11#
     楼主| 发表于 2012-9-19 08:40:52 | 只看该作者
    巴山 发表于 2012-9-19 03:38 . l  m8 E0 m2 ]& x. h6 |8 Q
    我们现在的 technology stack 就是 php + mongodb,涉及财务方面的东西用 postgres。9 k% @, h. `! a+ a

    6 b8 Z# }. X1 e& V0 O3 c ...
    5 e' `# O" X6 T2 |
    mongoDB作为存储是没有问题的,财务这种核心数据,还是不建议使用mongoDB的

    点评

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

    该用户从未签到

    12#
     楼主| 发表于 2012-9-19 08:44:52 | 只看该作者
    梦晓半生 发表于 2012-9-19 04:21 0 y3 S6 s! \; n2 P6 ^
    谢谢。
    + [3 |5 Y. y* b+ m: z
    , q' g1 r6 I/ u+ J2 X中文看得真累,大部分还是英文术语。
    & i; B  R) q' ~8 y
    现在关于mongoDB的文章,大部分都是在告诉大家怎么用,涉及到内部运行机理的文章,数量不多,而且不成体系。这个系列文章的目的,是让大家了解mongoDB的基本的运行机理,这样以后使用的时候,可以知其所以然。但是由于这方面的资料很少,我也是到处找资料,写了这么几篇,再往后,就是边使用,边看源码,边写了。
  • TA的每日心情
    奋斗
    2018-1-6 00:24
  • 签到天数: 1 天

    [LV.1]炼气

    13#
    发表于 2012-9-19 14:16:01 | 只看该作者
    shengnan007 发表于 2012-9-18 12:44 5 q# l- R! y( y1 M5 n
    是我啊。。。这都能被认出来。。。
    0 x: d6 u7 d  N" P- e
    是邓嫂么?

    该用户从未签到

    14#
     楼主| 发表于 2012-9-19 14:17:53 | 只看该作者
    profer 发表于 2012-9-19 14:16 4 O+ }. {. t8 ~8 E7 I3 Q$ N
    是邓嫂么?
    ! r- `+ ]8 ~: X& H/ x
    是邓的小兵
  • 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
    3 p# \4 z( E' w! t/ B, P" s现在关于mongoDB的文章,大部分都是在告诉大家怎么用,涉及到内部运行机理的文章,数量不多,而且不成体 ...

    2 H6 E% P$ h0 g2 o  D太好了,期待中,希望都带上英文reference。
    7 }! j; g% \4 f4 j5 Y6 @/ [* Q# W& e; D$ e
    现在这种新技术很多,Mongo是比较流行的一个,我这里附带一下一堆NoSQL的新系统,到最后估计会有几个胜出。9 O- @1 e2 Z9 P% r
    " y$ t2 u! E6 F: o
    http://en.wikipedia.org/wiki/NoSQL

    该用户从未签到

    17#
     楼主| 发表于 2012-9-20 08:53:41 | 只看该作者
    梦晓半生 发表于 2012-9-20 00:57 $ o. e6 \1 `/ c+ [
    太好了,期待中,希望都带上英文reference。0 f  @. E# b/ s) y

    : B; P- P# f$ D1 k现在这种新技术很多,Mongo是比较流行的一个,我这里附带一 ...
    ! E6 B; c" s! ~$ p8 v+ ^
    现在写的也很纠结,资料太少了,哈哈

    该用户从未签到

    18#
    发表于 2012-9-21 11:52:33 | 只看该作者
    shengnan007 发表于 2012-9-20 08:53   W6 \! J- }2 k
    现在写的也很纠结,资料太少了,哈哈
    , T7 ]9 b; R/ c6 Z% U
    建议从NoSQL写起,这是推动新数据库设计的需求关系,原始动力。8 j- r) q) X" ]

    / J& {+ W( I5 M! S4 Z1 z1 q  E/ rhttp://en.wikipedia.org/wiki/NoSQL
    3 [) ~5 t$ s- H
    , v0 t  K. \9 l3 d
  • TA的每日心情
    郁闷
    2019-4-22 08:49
  • 签到天数: 38 天

    [LV.5]元婴

    19#
    发表于 2012-9-21 17:03:12 | 只看该作者
    恶魔吹笛来 发表于 2012-9-19 18:35 ; m. h9 H8 W7 @. p' H( R- T5 k# W
    有点惊讶 居然在这里看到这篇文章 呵呵 静待大作
    0 a+ L0 H5 `# R4 P, O+ O; i5 e
    有什么可惊讶的邓侃在前一个爱坛版本是很早的注册用户呢,从开心网一块迁移的。。。

    该用户从未签到

    20#
     楼主| 发表于 2012-9-24 09:11:03 | 只看该作者
    梦晓半生 发表于 2012-9-21 11:52
    1 d3 \3 \% n& K1 S0 K( [建议从NoSQL写起,这是推动新数据库设计的需求关系,原始动力。
    * d5 j& m! f: e# I3 K8 l7 x+ Q/ K0 J% d6 M3 E/ R
    http://en.wikipedia.org/wiki/NoSQL
    , A4 x" C) m0 P! a2 \
    好的好的,现在这个写完,然后开始写nosql

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

    GMT+8, 2026-9-15 01:02 , Processed in 0.090594 second(s), 21 queries , Gzip On.

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

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