设为首页收藏本站

爱吱声

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

[信息技术] MongoDB架构概览

[复制链接]

该用户从未签到

跳转到指定楼层
楼主
发表于 2012-9-18 12:31:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    关于MongoDB,我们能看到的资料,基本都是在指导大家如何使用MongoDB,但是,MongoDB内部是如何运作的,资料不是很多。2 z9 P  b! n& f

( r' ~1 W; W/ q, x    阅读使用手册,会有很多疑惑之处。例如,有人说,MongoDB 等同于分布式的 MySQL。它把一个Table ,按 row,分割成多个Shards,分别存放在不同的 Servers 上。这种说法是否正确?
2 V, C0 T+ I8 `5 V/ i5 o5 T1 f8 `5 h- M1 d; ]; r# w
    不深入了解 MongoDB 的内部结构,就无法透彻地回答类似问题。这个系列文章,就来和大家探讨MongoDB的内部的工作方式。
  d* i! D0 T; J, `- f
7 d4 \. ^7 M' l7 I6 F
' H/ ^  C1 P; Q. ~0 ]5 a

' |8 N" [+ ?. y1 I图1-1 MongoDB架构图

  H" z2 `2 b5 w, x$ r
" t( I* I$ E5 }    MongoDB 通常运行在一个服务器集群上,而不是一个单机。图1-1,描述了一个MongoDB集群的基本组成部分,包括若干shards,至少一个config server,至少一个routing servers(又称 mongos)。
" T" W- y8 t( R7 V2 U% g0 V8 b% H7 ~  c" f. l
Shards/ h3 O8 }+ R" @! ?
" [, a% n; T; ^9 c, r. Y0 Q
    MongoDB的最基本的数据单元,叫document,类似于关系式数据库中的行 row。一系列documents,组成了一个collection,相当于关系式数据库中的table。当一个 collection 数据量太大时,可以把该collection按documents切分,分成多个数据块,每个数据块叫做一个chunk,多个chunks聚集在一起,组成了一个shard。& \$ J1 f2 u- H, Z/ V7 W  Z

9 ^/ g! i" v- s, V. b# e    Sharding 的意义,不仅保障了数据库的扩容(scalability),同时也保障了系统的负载均衡(load balance)。
6 H) O" H; Q& J+ E
& a6 Q9 I) r; _    每一个shard存储在一个物理服务器(server)上。Server上运行着mongod进程,通过这个进程,对shard中的数据进行操作,主要是增删改查。
7 @, [9 U' T$ N: D4 A. I* p- e. r/ ?3 ]' L# V
    如果系统中的每个shard,只存储了一份数据,没有备份,那么当这个shard所在的server挂了,数据就丢失了。在生产环境中,为了保证数据不丢失,为了提高系统的可用性(availability),每一个shard被存储多份,每个备份所在的servers,组成了一个replica set。! w# L2 B& J& e. N

5 G$ @0 M5 I( R+ ?Shard keys9 w! G8 ^2 [! F4 C
        % F: `$ F# |/ y* l" d/ i: Y
    为了把collection切分成不同的chunks,从而存放到不同的shards中,我们需要制定一个切分的方式。9 A" ~2 M2 p* ]! i: L6 w' o. F

+ J. R7 c6 g8 t# B  I5 r    如前所述,在 MongoDB 数据库中,一个表collection由多个行 documents 组成,而每个 document,有多个属性 fields。同一个 collection 中的不同的 documents,可能会有不同的 fields。例如,有个 collection 叫 Media,包含两条 documents,# M  C- ^: C! G
2 E$ P1 S0 r9 z+ l, k
{
. [/ C# J7 z" ^) @" k- \; A2 F/ f  "ISBN": "987-30-3652-5130-82",
% m9 z5 m7 l6 S1 f+ e  "Type": "CD",
3 J$ W$ i5 N% k3 e- J1 X( w  "Author": "Nirvana",
; e% M3 t. |; ?2 s) h* R3 B! N8 @  "Title": "Nevermind",6 g8 b1 T7 I: K+ M4 w
  "Genre": "Grunge",8 h7 V+ U- e# O+ S5 i. d7 ]
   "Releasedate": "1991.09.24"," {  U! F0 v# f8 \3 u2 S
   "Tracklist": [* s3 C  N" t2 ]
     {* V% L- @7 D6 ]7 H* h3 R
        "Track" : "1",  Z8 t3 S! P- G) N, T$ `
        "Title" : "Smells like teen spirit",# M5 E& M2 @+ A
        "Length" : "5:02"
3 b% |- Z# c0 R6 }) V     },0 H. f+ F* [2 w. B! J7 n
     {
3 Y- b+ A# e* H/ X2 `# O! l/ W        "Track" : "2",
* T. n  ?. }8 |2 N+ r        "Title" : "In Bloom",
. H" f7 B  ?  f8 F5 \        "Length" : "4:15") C1 v: _' [' u+ t% w/ L# j& u
     }
) ]- B+ O) W1 `. {' U   ]. b1 d3 C0 Q) @' v. {$ z
}
; t( B* a* @/ k8 G! r0 J
; Z0 W' V6 q- @  e  A* x, {# G{
& k/ }; Y5 G6 M' M+ T$ k7 ~  "ISBN": "987-1-4302-3051-9",1 g1 _, Y, n: |; X  j8 f4 y6 u
  "Type": "Book",/ O5 v5 h( c5 D' N1 S
  "Title": "Definite Guide to MongoDB: The NoSQL Database",$ V, [! q0 s7 {6 n/ F9 [
  "Publisher": "Apress",
6 _' A8 e, O1 l( S6 r* g  "Author": " Eelco Plugge",# Z% }% G+ P, j5 q  n: Q
  "Releasedate": "2011.06.09"  y% B2 H/ ^, x. x+ c2 f, g
}
7 t9 [, ?% H* S5 d. _) Q. l6 l! d, o3 b+ o: s
    假如,在同一个 collection 中的所有 document,都包含某个共同的 field,例如前例中的“ISBN”,那么我们就可以按照这个 field 的值,来分割 collection。这个 field 的值,又称为 shard key。2 b5 C7 c2 J: v
" ~5 C2 T' b1 L+ c! V! U6 ^
    在选择shard key的时候,一定要确保这个key能够把collection均匀地切分成很多chunks。1 y7 T7 F# _& L. f5 A. n7 X& {
9 Y0 j! a4 o, X6 }$ R: x
    例如,如果我们选择“author”作为shard key,如果有大量的作者是重名的,那么就会有大量的数据聚集在同一个chunk中。当然,假设很少有作者同名同姓,那么“author”也可以作为一个shard key。换句话说,shard key 的选择,与使用场景密切相关。; P3 Q" v. L. b' n6 o# m1 m7 n0 ]
9 \, b4 u/ m% s
    很多情况下,无论选择哪一个单一的 field 作为shard key,都无法均匀分割 collection。在这种情况下,我们可以考虑,用多个 fields,构成一个复合的shard key。# g; Q3 T! P& w: M' n
% l' _3 s, _: T: t
    延续前例,假如有很多作者同名同姓,他们都叫“王二”。用 author 作为 shard key,显然无法均匀切割 collection。这时我们可以加上release-date,组成name-date的复合 shard key,例如“王二 2011”。
8 r7 _) e0 p, h! C% i
2 g2 p, ^$ @1 S5 I' J, n5 FChunks1 P& D& p: F# N- R
        
3 t& Z4 S+ k) E1 B$ T* N4 ^& T    MongoDB按 shard key,把 collection切割成若干 chunks。每个 chunk 的数据结构,是一个三元组,{collection,minKey,maxKey},如图1-2 所示。% R; }1 q# h$ N  b
+ y5 M) a& {  [. y; ?9 z
' Z! w: M3 J9 J6 @* ]( j  s
图1-2 chunk的三元组
  o- b  y' f. x5 Z& e' }* n7 Y
6 w: [$ d& J( J
    其中,collection 是数据库中某一个表的名称,而 minKey 和 maxKey 是 shard key的范围。每一个 document 的shard key 的值,决定了这条document应该存放在哪个chunk中。7 X) Q; a9 |0 j

% r8 E9 P- {2 \  C2 y. Q5 `) w/ l% V    如果两条 documents 的 shard keys 的值很接近,这两条 documents 很可能被存放在同一个 chunk 中。& B& D- W6 J  @

9 J% E. _1 @0 k* Y0 @% }    Shard key 的值的顺序,决定了 document 存放的 chunk。在 MongoDB 的文献中,这种切割 collection 的方式,称为order-preserving。
) s& Y3 D6 ^9 `2 M
4 {9 ?5 F' B8 d) P2 V$ ]    一个 chunk最多能够存储64MB的数据。 当某个chunk存储的 documents包含的数据量,接近这个阈值时,一个chunk会被切分成两个新的chunks。3 J9 n3 d% V& L# u
1 K) H7 ~6 b0 j- N4 V
    当一个shard存储了过多的chunks,这个shard中的某些chunks会被迁移到其它 shard中。
- q# V+ r4 `, [5 m0 i
9 \3 _# S% _2 R4 Q    这里有个问题,假如某一条 document 包含的数据量很大,超过 64MB,一个 chunk 存放不下,怎么办?在后续章节介绍 GridFS 时,我们会详细讨论。* |" B* X+ N5 i- m% y8 t: t
/ q; ], L2 p/ t
Replica set. J/ u- }2 ^& t+ g' D
        
8 h/ g9 J" U7 S7 W& q8 r$ j    在生产环境中,为了保证数据不丢失,为了提高系统的可用性(availability),每一个shard被存储多份,每个备份所在的servers,组成了一个replica set。: A/ e+ F0 H; S5 k' A1 ^
# A0 R3 ^7 u$ A6 W1 ~! X% f- B* \1 b
    这个replica set包括一个primary DB和多个secondary DBs。为了数据的一致性,所有的修改(insert / update / deletes) 请求都交给primary处理。处理结束之后,再异步地备份到其他secondary中。; O) K' c0 Q+ r0 V( C9 B/ V
; _+ u6 Z/ A. k/ A9 ^
    Primary DB由replica set中的所有servers,共同选举产生。当这个primaryDB server出错的时候,可以从replica set中重新选举一个新的primaryDB,从而避免了单点故障。
( T4 m* s- s" d
, p% P/ d! s! y    Replica set的选举策略和数据同步机制,确保了系统的数据的一致性。后文详述。0 c+ W! W# D; U8 j4 Q7 s. n
  y) y. o2 Y+ y* `7 [& H( g
Config Server- b/ a' j2 K% e% j3 B
        ' v5 h8 {, q8 o2 N1 u
    Config servers用于存储MongoDB集群的元数据 metadata,这些元数据包括如下两个部分,每一个shard server包括哪些chunks,每个chunk存储了哪些 collections 的哪些 documents。
$ {. c  i# i' ?# T5 A
3 Y' \9 y! J$ ^  P' _: c3 T0 M    每一个config server都包括了MongoDB中所有chunk的信息。
( K  o, H0 F! Q* \4 a4 E; M
0 r* T! x  B/ G- x* w    Config server也需要 replication。但是有趣的是,config server 采用了自己独特的replication模式,而没有沿用 replica set。
2 M& U# i, \, Z$ {, {- y* M* `  k" K: W) p* y9 H: a
    如果任何一台config server挂了,整个 config server 集群中,其它 config server变成只读状态。这样做的原因,是避免在系统不稳定的情况下,冒然对元数据做任何改动,导致在不同的 config servers 中,出现元数据不一致的情况。. _5 `% E3 O; g1 q7 H
* t9 Y# a: ?* a
    MongoDB的官方文档建议,配置3个config servers比较合适,既提供了足够的安全性,又避免了更多的config servers实例之间的数据同步,引起的元数据不一致的麻烦。5 J; F% n; x& T( \; d- t' o
; T* O2 h% O0 U6 y" ^* F# X! O$ M
Mongos' \5 ]1 `9 N, e# D0 g% W+ ]; e
2 t# q/ x* p$ T
    用户使用MongoDB 时,用户的操作请求,全部由mongos来转发。
& q& s4 f8 k  J( }" {9 q6 q8 _  i: h; |! m
    当 mongos 接收到用户请求时,它先查询 config server,找到存放相应数据的shard servers。然后把用户请求,转发到这些 shard servers。当这些 shard servers完成操作后,它们把结果分别返回给 mongos。而当 mongos 汇总了所有的结果后,它把结果返回给用户。" Q* I4 V) D1 a; p7 g. Q
+ z& ?* h1 Z( a! N0 J- C$ `+ D
    Mongos每次启动的时候,都要到config servers中读取元数据,并缓存在本地。每当 config server中的元数据有改动,它都会通知所有的mongos。0 X# M; \" a6 H: g3 D# g$ i( I

; E) x' S5 t6 V2 X( S    Mongos之间,不存在彼此协同工作的问题。因此,MongoDB所需要配置的mongos server的数量,没有限制。5 q! o5 b1 [; D+ H3 `

* q; e% _  W# i7 _- B( @+ Y5 m' o. x    通过以上的介绍,我们对每个组成部分都有了基本的了解,但是涉及到工作的细节,我们尚有诸多疑问,例如,一个chunk的数据太大,如何切分?一个shard数据太多,如何迁移?在replica set中,如何选择primary?server挂了,怎么进行故障恢复?接下来的章节,我们逐个回答这些问题。$ m  J, o& K7 ?1 _7 }7 A3 i
' i  Q4 K2 r" y1 n1 y- V2 ~
: F; ~! u1 m- _9 l& C
Reference,# w4 J: Q, |, G6 m* F9 h: d$ ~: t
2 }4 N+ t. f8 @. D5 H& W
[0] Architectural Overview( v$ f  v* a7 H: a6 b; l
http://www.mongodb.org/display/DOCS/Sharding+Introduction9 y7 B5 K  j& G6 A; L: D# W

评分

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

查看全部评分

该用户从未签到

沙发
发表于 2012-9-18 12:40:50 | 只看该作者
本帖最后由 PenPen 于 2012-9-18 12:44 编辑 % G: x3 l5 J* A" c

+ c8 g- U9 k* |$ K% X7 \. C% ~- F7 Y" G% H- E1 w
您是和邓侃一起写文章的盛楠么?

该用户从未签到

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

该用户从未签到

地板
 楼主| 发表于 2012-9-18 12:44:45 | 只看该作者
PenPen 发表于 2012-9-18 12:40 ' s! ~: u. I9 W" M1 @0 C
您是和邓侃一起写文章的盛楠么?
9 C7 e( E. z# p. S, f
是我啊。。。这都能被认出来。。。

该用户从未签到

5#
发表于 2012-9-18 12:47:20 | 只看该作者
shengnan007 发表于 2012-9-18 12:44
( V  c' Q" q3 j6 R是我啊。。。这都能被认出来。。。

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

该用户从未签到

6#
 楼主| 发表于 2012-9-18 12:49:50 | 只看该作者
PenPen 发表于 2012-9-18 12:47
8 Q  [+ {* w4 V+ R5 G这篇文章我读过。开始以为是转贴的,后来再一看id就发现真相了~

' \5 ~8 [" \. y; y; B# y. c多谢支持。还有两篇一会帖过来。后续的还在写。边看源码边写,比较慢,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 / ?" P& Q& ^1 ^1 H7 w% s2 T
    多谢支持。还有两篇一会帖过来。后续的还在写。边看源码边写,比较慢,hoho。这里是要推荐才能变成正式会 ...

    & ~( n9 |- ?( G欢迎,欢迎,已经给你变成正式会员了。

    该用户从未签到

    8#
     楼主| 发表于 2012-9-18 12:57:15 | 只看该作者
    不爱吱声 发表于 2012-9-18 12:51 * P: C7 t* R2 J- v  [0 c4 Y
    欢迎,欢迎,已经给你变成正式会员了。
    , [9 b: |$ S- H. B0 h
    多谢多谢啦~~
  • TA的每日心情
    慵懒
    2020-1-15 02:37
  • 签到天数: 1287 天

    [LV.10]大乘

    9#
    发表于 2012-9-19 03:38:34 | 只看该作者
    我们现在的 technology stack 就是 php + mongodb,涉及财务方面的东西用 postgres。
    & J% A: x* M% B4 F8 x% U. E2 N  V' z+ Q- j

    该用户从未签到

    10#
    发表于 2012-9-19 04:21:40 | 只看该作者
    谢谢。
    4 R; }. F# H$ L$ v$ L/ t/ h: a, V- H
    中文看得真累,大部分还是英文术语。
    ' Z* \1 W' C) ?
    7 ?$ U. ?4 S& c1 J& v这应该是一个系列吧,后面怎样寻找,执行指令等开始入门,还是说的太简单了。
    1 N" @8 |' D2 d" Z  q
    6 \/ j+ ?+ |% s% R1 O3 m# ~4 p3 g现在distributed DB在那些大网站很重要,现在开始有跟已有DB分庭抗礼的苗头,不过不是那里工作的话,其中的奥妙大概难说清楚。

    该用户从未签到

    11#
     楼主| 发表于 2012-9-19 08:40:52 | 只看该作者
    巴山 发表于 2012-9-19 03:38
    3 m, M- w% X9 Y" `: Z我们现在的 technology stack 就是 php + mongodb,涉及财务方面的东西用 postgres。
    6 l: i/ w  L, J7 [7 k2 T+ Y3 J6 o6 u3 w# l' f
    ...
    % r; s6 ~$ T1 T4 O3 \" Q$ p7 U
    mongoDB作为存储是没有问题的,财务这种核心数据,还是不建议使用mongoDB的

    点评

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

    该用户从未签到

    12#
     楼主| 发表于 2012-9-19 08:44:52 | 只看该作者
    梦晓半生 发表于 2012-9-19 04:21
    . r6 I+ s  U) T谢谢。
    ) m/ W  p% X/ X  P3 ?4 Y9 _" ~- U
      G5 f- m1 Z& C, X3 N中文看得真累,大部分还是英文术语。
    # Y, e, H6 y# I+ g, l6 s( \" G
    现在关于mongoDB的文章,大部分都是在告诉大家怎么用,涉及到内部运行机理的文章,数量不多,而且不成体系。这个系列文章的目的,是让大家了解mongoDB的基本的运行机理,这样以后使用的时候,可以知其所以然。但是由于这方面的资料很少,我也是到处找资料,写了这么几篇,再往后,就是边使用,边看源码,边写了。
  • TA的每日心情
    奋斗
    2018-1-6 00:24
  • 签到天数: 1 天

    [LV.1]炼气

    13#
    发表于 2012-9-19 14:16:01 | 只看该作者
    shengnan007 发表于 2012-9-18 12:44 4 a3 m8 {# }$ @& _
    是我啊。。。这都能被认出来。。。
    ! y) v* ~) f% R4 e- x
    是邓嫂么?

    该用户从未签到

    14#
     楼主| 发表于 2012-9-19 14:17:53 | 只看该作者
    profer 发表于 2012-9-19 14:16
    ; Y# e5 E6 J; t: F! X% Q7 ~是邓嫂么?

    ! x9 S  v6 G) n) |是邓的小兵
  • 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 - N& b: O) ^6 r6 F, G4 Q7 C
    现在关于mongoDB的文章,大部分都是在告诉大家怎么用,涉及到内部运行机理的文章,数量不多,而且不成体 ...
    0 v1 w, K$ T. F4 F; D- T
    太好了,期待中,希望都带上英文reference。
    ( t$ {  `6 i6 W3 P/ ^1 L; K& C( ]# ?2 w
    & ~& |. r, M, _2 \6 D' Y9 z2 f现在这种新技术很多,Mongo是比较流行的一个,我这里附带一下一堆NoSQL的新系统,到最后估计会有几个胜出。6 `( \1 T1 }1 k! a
      P! t" g0 I4 v* P- F
    http://en.wikipedia.org/wiki/NoSQL

    该用户从未签到

    17#
     楼主| 发表于 2012-9-20 08:53:41 | 只看该作者
    梦晓半生 发表于 2012-9-20 00:57
    ( C6 M/ Q% b+ Z9 v1 E太好了,期待中,希望都带上英文reference。! F( j  |, B* a; ]5 n' {+ t' K. `' h

    5 ^4 ^8 E$ L! H! L$ ?* c5 Z现在这种新技术很多,Mongo是比较流行的一个,我这里附带一 ...

    + E4 m9 @% o$ i: r* X7 Y现在写的也很纠结,资料太少了,哈哈

    该用户从未签到

    18#
    发表于 2012-9-21 11:52:33 | 只看该作者
    shengnan007 发表于 2012-9-20 08:53
    ! K: C  D  j' L现在写的也很纠结,资料太少了,哈哈

    6 }+ m5 Z1 p  [( w* D3 I% S建议从NoSQL写起,这是推动新数据库设计的需求关系,原始动力。
    % r& h7 ]+ X, V5 ~& r  K+ d
    * u1 ^6 n* G$ {( k- r- Rhttp://en.wikipedia.org/wiki/NoSQL! Q. l9 g, K/ K
    / i: T  @2 a. D% T
  • TA的每日心情
    郁闷
    2019-4-22 08:49
  • 签到天数: 38 天

    [LV.5]元婴

    19#
    发表于 2012-9-21 17:03:12 | 只看该作者
    恶魔吹笛来 发表于 2012-9-19 18:35 # D- P$ G# p# P2 M) Z
    有点惊讶 居然在这里看到这篇文章 呵呵 静待大作

    & J- u8 x( _, t4 x( r, W有什么可惊讶的邓侃在前一个爱坛版本是很早的注册用户呢,从开心网一块迁移的。。。

    该用户从未签到

    20#
     楼主| 发表于 2012-9-24 09:11:03 | 只看该作者
    梦晓半生 发表于 2012-9-21 11:52 ) P; F1 B& t9 u! s. P
    建议从NoSQL写起,这是推动新数据库设计的需求关系,原始动力。" Z3 k& S, Z5 Q: Y4 J9 ~
      ?$ `, {- x+ }5 q7 S' i' H0 J
    http://en.wikipedia.org/wiki/NoSQL

    2 D' Y8 ~: J  |9 V$ k- Z0 o3 p好的好的,现在这个写完,然后开始写nosql

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

    GMT+8, 2024-6-15 06:49 , Processed in 0.051097 second(s), 22 queries , Gzip On.

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

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