设为首页收藏本站

爱吱声

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

[信息技术] MongoDB架构概览

[复制链接]

该用户从未签到

跳转到指定楼层
楼主
发表于 2012-9-18 12:31:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    关于MongoDB,我们能看到的资料,基本都是在指导大家如何使用MongoDB,但是,MongoDB内部是如何运作的,资料不是很多。
  J* V; ^! R6 E# |' T# G  z2 W% s& Z7 f1 ^2 C
    阅读使用手册,会有很多疑惑之处。例如,有人说,MongoDB 等同于分布式的 MySQL。它把一个Table ,按 row,分割成多个Shards,分别存放在不同的 Servers 上。这种说法是否正确?
& ~+ H: x1 @, d
! ~4 h; s$ W- P  J5 l) `5 {    不深入了解 MongoDB 的内部结构,就无法透彻地回答类似问题。这个系列文章,就来和大家探讨MongoDB的内部的工作方式。& C+ Z& N9 M7 a6 r

* H# u# h1 g. L9 H6 o  ~8 ~" c% `$ B
; G& @3 m2 K1 R6 B- ]5 d& {

4 p# q5 F2 o6 Z6 c: O8 U图1-1 MongoDB架构图

; S: V( w; m2 @5 _5 }" v6 L6 _* E) P9 n- m' ^# ^/ F
    MongoDB 通常运行在一个服务器集群上,而不是一个单机。图1-1,描述了一个MongoDB集群的基本组成部分,包括若干shards,至少一个config server,至少一个routing servers(又称 mongos)。
* {! w- W' r( ]3 u6 j# i, ~- i5 j. `5 Q' i; t+ a& P  l8 x
Shards2 a- g) ]3 W/ H

6 Y' p6 l( e$ Z8 a* N    MongoDB的最基本的数据单元,叫document,类似于关系式数据库中的行 row。一系列documents,组成了一个collection,相当于关系式数据库中的table。当一个 collection 数据量太大时,可以把该collection按documents切分,分成多个数据块,每个数据块叫做一个chunk,多个chunks聚集在一起,组成了一个shard。
1 [5 O. y* H& z" J7 u  v: P
8 o/ @7 u, Y* x    Sharding 的意义,不仅保障了数据库的扩容(scalability),同时也保障了系统的负载均衡(load balance)。( q* p- v( S" L% I5 @* k

3 E, z2 V5 |. Z+ L( J; C0 n    每一个shard存储在一个物理服务器(server)上。Server上运行着mongod进程,通过这个进程,对shard中的数据进行操作,主要是增删改查。- G' Z, Z  Q. A% W+ G% h

( V8 {9 S( _- j    如果系统中的每个shard,只存储了一份数据,没有备份,那么当这个shard所在的server挂了,数据就丢失了。在生产环境中,为了保证数据不丢失,为了提高系统的可用性(availability),每一个shard被存储多份,每个备份所在的servers,组成了一个replica set。# G% h: O; l% n
& W+ @8 E$ x8 ], x" S0 |
Shard keys$ A- ]9 |; |6 n/ ~' A7 }  n
        8 }# N' [: s7 g7 j; B
    为了把collection切分成不同的chunks,从而存放到不同的shards中,我们需要制定一个切分的方式。
  C1 Z/ C( a/ b# A( [& K( G6 \: C- F% {4 O" W! q' [1 J, y3 N
    如前所述,在 MongoDB 数据库中,一个表collection由多个行 documents 组成,而每个 document,有多个属性 fields。同一个 collection 中的不同的 documents,可能会有不同的 fields。例如,有个 collection 叫 Media,包含两条 documents,& p  p/ m" r" W7 Q$ a6 E/ Z4 ^* k

2 S. N# G. C2 S{& E; P; x6 T- G/ C4 ~
  "ISBN": "987-30-3652-5130-82",
/ o' Y0 N+ T8 P2 C% r& X$ _  "Type": "CD"," P! ]& A/ L. |9 n+ ]
  "Author": "Nirvana",1 B, i  Y" A7 X
  "Title": "Nevermind",
! a4 P9 z  t- ?; ?% c  "Genre": "Grunge",1 }% U" m) Z3 p8 S. n. Z
   "Releasedate": "1991.09.24",5 a) x: G9 g$ _- k0 a0 P+ |% Z
   "Tracklist": [
, G7 b5 h8 d+ u     {9 B! @: P" t' b# k) M" T
        "Track" : "1",
7 h/ L/ \6 {- q( q  A7 o        "Title" : "Smells like teen spirit",8 v% r" M5 j4 F2 [
        "Length" : "5:02"6 T( _- f* J. s- {  K+ i1 G
     },
; M" t1 }0 v: }# A( ]* P) ?     {) B4 k4 }' a; W  J2 J$ y, B
        "Track" : "2",
8 T  @( ?- y5 u' Z" M        "Title" : "In Bloom",9 T: ^) K/ ]9 F- Y  a
        "Length" : "4:15"8 @$ v+ Y" v7 Z
     }+ h; H- N. P( n  C$ P, e  ^8 s* p
   ]
+ ]- Z+ y$ d- K3 E1 D6 z0 U& E2 l! w}
4 w6 }# r) f, }4 f9 R2 ~- k
2 M0 n! R! c; g4 U- E3 U/ B{& u+ o- n: ]. D3 @) U0 t6 h
  "ISBN": "987-1-4302-3051-9",
* \3 Y* ?1 ^# g) S8 }  "Type": "Book",8 x' }! l4 M- a) V1 ^5 F
  "Title": "Definite Guide to MongoDB: The NoSQL Database",  G/ l1 ]  x* e" Q8 g. S
  "Publisher": "Apress",; H& S- X; ]- b8 l2 |, C" o
  "Author": " Eelco Plugge",
& b4 Z1 W& Q- E' C. Z) z' H  "Releasedate": "2011.06.09"! c9 n4 p! K% Y6 v
}
/ C  x$ m$ G2 {5 d( e: [, ~
2 O! \/ ?& Q( i, X" }1 u. v    假如,在同一个 collection 中的所有 document,都包含某个共同的 field,例如前例中的“ISBN”,那么我们就可以按照这个 field 的值,来分割 collection。这个 field 的值,又称为 shard key。! ~1 R$ Q2 t2 X( ?

- }) E- v' W6 w/ o  |- o& [& ]    在选择shard key的时候,一定要确保这个key能够把collection均匀地切分成很多chunks。
5 u% s* p1 p& S4 ~
- A/ j4 F* t6 u$ P8 Z3 g8 m) C    例如,如果我们选择“author”作为shard key,如果有大量的作者是重名的,那么就会有大量的数据聚集在同一个chunk中。当然,假设很少有作者同名同姓,那么“author”也可以作为一个shard key。换句话说,shard key 的选择,与使用场景密切相关。
5 I  T" [6 V, b& u! m8 N+ M0 f
  p1 `6 T$ Z+ q  M4 S9 o5 x    很多情况下,无论选择哪一个单一的 field 作为shard key,都无法均匀分割 collection。在这种情况下,我们可以考虑,用多个 fields,构成一个复合的shard key。
2 [- M0 S% U* C1 P; g
4 j& g3 X' v0 a1 p5 O  k    延续前例,假如有很多作者同名同姓,他们都叫“王二”。用 author 作为 shard key,显然无法均匀切割 collection。这时我们可以加上release-date,组成name-date的复合 shard key,例如“王二 2011”。' e4 |8 I4 W+ i( t

: P7 }* ^: H0 I# |3 o2 x7 sChunks
& b6 j9 O# N7 a+ ?/ w3 b        
) J  K" q( e( A    MongoDB按 shard key,把 collection切割成若干 chunks。每个 chunk 的数据结构,是一个三元组,{collection,minKey,maxKey},如图1-2 所示。# t, ?  F% j0 Y! F7 O4 C* u& |8 ?* a
' Y4 _; m: h5 y" }

% U8 D5 a  j* \/ i图1-2 chunk的三元组

  B' }: N& A0 V% r* X
/ D9 o/ h9 z# u+ P0 U    其中,collection 是数据库中某一个表的名称,而 minKey 和 maxKey 是 shard key的范围。每一个 document 的shard key 的值,决定了这条document应该存放在哪个chunk中。
$ k4 G9 r$ ~8 K  H) ^: o# o; K: s8 _: ~# A; G; J5 c. l
    如果两条 documents 的 shard keys 的值很接近,这两条 documents 很可能被存放在同一个 chunk 中。
* w. e. L* P1 L: |: |2 ?8 k; i! E
" ^) s5 N" p* N& \! ^    Shard key 的值的顺序,决定了 document 存放的 chunk。在 MongoDB 的文献中,这种切割 collection 的方式,称为order-preserving。& X) c: K3 y+ C# k! Q4 B( K3 O

# N3 F6 ]& p3 h    一个 chunk最多能够存储64MB的数据。 当某个chunk存储的 documents包含的数据量,接近这个阈值时,一个chunk会被切分成两个新的chunks。; s" r/ h$ d8 Q; X. O4 O
" s- h4 Y3 K% u/ H- H: q
    当一个shard存储了过多的chunks,这个shard中的某些chunks会被迁移到其它 shard中。! ]: U- a- y. A- V
/ ^8 y5 O/ C3 |; {+ G
    这里有个问题,假如某一条 document 包含的数据量很大,超过 64MB,一个 chunk 存放不下,怎么办?在后续章节介绍 GridFS 时,我们会详细讨论。+ j( _" Q% D. b
0 ?& w' p: X0 ^0 ^4 g7 U
Replica set
  r0 ^, o, `, Y) I+ S        / Q' _0 H7 f9 M3 l) d
    在生产环境中,为了保证数据不丢失,为了提高系统的可用性(availability),每一个shard被存储多份,每个备份所在的servers,组成了一个replica set。% S# V, f" r; j8 D. \7 B0 L$ r

) i3 K! V7 Z* m' B! r& N' o    这个replica set包括一个primary DB和多个secondary DBs。为了数据的一致性,所有的修改(insert / update / deletes) 请求都交给primary处理。处理结束之后,再异步地备份到其他secondary中。
! _$ R) `( s7 |! \  @( {5 r: G5 i# E; T" y, @, f  q1 r
    Primary DB由replica set中的所有servers,共同选举产生。当这个primaryDB server出错的时候,可以从replica set中重新选举一个新的primaryDB,从而避免了单点故障。# t, U) ^0 @! T$ w) w! K
3 z0 X. g  @6 n8 {3 L& s5 r
    Replica set的选举策略和数据同步机制,确保了系统的数据的一致性。后文详述。
& p1 Z+ [1 c2 |5 \
& O% V! D8 ]% vConfig Server
2 @) d! Q4 J! L        
' @  M2 y: ~, z9 b    Config servers用于存储MongoDB集群的元数据 metadata,这些元数据包括如下两个部分,每一个shard server包括哪些chunks,每个chunk存储了哪些 collections 的哪些 documents。
2 R9 N* U6 n/ S1 n! j/ F9 f
! L1 k4 t" @+ Y% S1 L    每一个config server都包括了MongoDB中所有chunk的信息。
3 x5 f8 J) `6 e7 ~% f/ K8 B# q) o4 P* S# L) T4 U( s) C
    Config server也需要 replication。但是有趣的是,config server 采用了自己独特的replication模式,而没有沿用 replica set。
3 w' d; K9 q& a: F- U2 z- `" _# u) Y
    如果任何一台config server挂了,整个 config server 集群中,其它 config server变成只读状态。这样做的原因,是避免在系统不稳定的情况下,冒然对元数据做任何改动,导致在不同的 config servers 中,出现元数据不一致的情况。
2 U7 q$ a" H4 J& X
/ T2 ~1 V3 S- |    MongoDB的官方文档建议,配置3个config servers比较合适,既提供了足够的安全性,又避免了更多的config servers实例之间的数据同步,引起的元数据不一致的麻烦。
. Z+ R$ u0 w$ g4 s7 q4 @3 l% }
% ]# u2 Q! W6 b4 r. kMongos/ K( g  [# G( b  X/ Q9 {8 i

" [0 c3 c6 W' T- L  l* \5 x    用户使用MongoDB 时,用户的操作请求,全部由mongos来转发。
1 @, b! \0 ^) @
9 C: f4 P) k/ Q3 D, E    当 mongos 接收到用户请求时,它先查询 config server,找到存放相应数据的shard servers。然后把用户请求,转发到这些 shard servers。当这些 shard servers完成操作后,它们把结果分别返回给 mongos。而当 mongos 汇总了所有的结果后,它把结果返回给用户。: |+ O1 `6 w$ d
# l1 Z! K( N  r( z: B
    Mongos每次启动的时候,都要到config servers中读取元数据,并缓存在本地。每当 config server中的元数据有改动,它都会通知所有的mongos。
1 b$ y* S4 G2 U  a6 T* l' u' d. y, ]) [. S- q
    Mongos之间,不存在彼此协同工作的问题。因此,MongoDB所需要配置的mongos server的数量,没有限制。) Z# E" H7 D" l8 ~" L6 ^" \) @% M
/ q) t5 {% V& z; f5 w
    通过以上的介绍,我们对每个组成部分都有了基本的了解,但是涉及到工作的细节,我们尚有诸多疑问,例如,一个chunk的数据太大,如何切分?一个shard数据太多,如何迁移?在replica set中,如何选择primary?server挂了,怎么进行故障恢复?接下来的章节,我们逐个回答这些问题。' z9 @6 q: ~) t/ ^

' h9 x& @/ P3 F6 O
( ?/ A  r$ R# s# d0 d2 {Reference,
- q0 d1 ?( m* S' a0 Q! E6 v- l9 y4 ]5 d6 q% l) g6 B$ q6 e5 Q
[0] Architectural Overview; O8 n- y: O- n2 b
http://www.mongodb.org/display/DOCS/Sharding+Introduction
+ p9 k$ n$ Y2 ?  S+ x

评分

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

查看全部评分

该用户从未签到

沙发
发表于 2012-9-18 12:40:50 | 只看该作者
本帖最后由 PenPen 于 2012-9-18 12:44 编辑
, F. e0 v, V' n+ s. Z4 w$ n; y) P9 V' _- j9 ~( @; E4 ?

+ T2 f" H2 ~5 W您是和邓侃一起写文章的盛楠么?

该用户从未签到

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

该用户从未签到

地板
 楼主| 发表于 2012-9-18 12:44:45 | 只看该作者
PenPen 发表于 2012-9-18 12:40
) V# s0 K8 R  ^" o# i2 d# X8 [您是和邓侃一起写文章的盛楠么?

$ B. e! l+ C) M! g$ O$ j是我啊。。。这都能被认出来。。。

该用户从未签到

5#
发表于 2012-9-18 12:47:20 | 只看该作者
shengnan007 发表于 2012-9-18 12:44 ! c7 T$ W  _& O2 _- n1 m+ p% }
是我啊。。。这都能被认出来。。。
& F" K. _$ G" `: n  ^' {! {
这篇文章我读过。开始以为是转贴的,后来再一看id就发现真相了~

该用户从未签到

6#
 楼主| 发表于 2012-9-18 12:49:50 | 只看该作者
PenPen 发表于 2012-9-18 12:47
8 J1 ?8 q9 w! e, t7 }这篇文章我读过。开始以为是转贴的,后来再一看id就发现真相了~

4 t# N, b0 W: E9 A( _/ x多谢支持。还有两篇一会帖过来。后续的还在写。边看源码边写,比较慢,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 9 s0 e2 p6 K" E  ?, v2 ^
    多谢支持。还有两篇一会帖过来。后续的还在写。边看源码边写,比较慢,hoho。这里是要推荐才能变成正式会 ...

    0 @+ q& A  u4 T5 o欢迎,欢迎,已经给你变成正式会员了。

    该用户从未签到

    8#
     楼主| 发表于 2012-9-18 12:57:15 | 只看该作者
    不爱吱声 发表于 2012-9-18 12:51 6 R/ A4 k3 Y( d' i1 R+ W
    欢迎,欢迎,已经给你变成正式会员了。
    1 x2 b. q: H) o
    多谢多谢啦~~
  • TA的每日心情
    慵懒
    2020-1-15 02:37
  • 签到天数: 1287 天

    [LV.10]大乘

    9#
    发表于 2012-9-19 03:38:34 | 只看该作者
    我们现在的 technology stack 就是 php + mongodb,涉及财务方面的东西用 postgres。& A- J' b9 Q! k4 W: f' F! @4 Q
    + w- Z7 L6 z5 K

    该用户从未签到

    10#
    发表于 2012-9-19 04:21:40 | 只看该作者
    谢谢。7 b& k3 I6 {6 H
    4 d: N1 D9 Z- m: A8 n% N
    中文看得真累,大部分还是英文术语。
    1 z  _2 O/ P$ w& A+ z, U1 G4 r, ~- A* f2 k
    这应该是一个系列吧,后面怎样寻找,执行指令等开始入门,还是说的太简单了。" p: ~5 L* @2 `% k! M0 `

    / z" y7 m, H8 s% b4 Q' W5 E现在distributed DB在那些大网站很重要,现在开始有跟已有DB分庭抗礼的苗头,不过不是那里工作的话,其中的奥妙大概难说清楚。

    该用户从未签到

    11#
     楼主| 发表于 2012-9-19 08:40:52 | 只看该作者
    巴山 发表于 2012-9-19 03:38 $ z# R- ?! B3 a! F
    我们现在的 technology stack 就是 php + mongodb,涉及财务方面的东西用 postgres。4 k* p8 Y7 D; l( K! R" `8 {
    1 O- o, {& a( e: i
    ...

    ! {2 F" D9 W) F' U" kmongoDB作为存储是没有问题的,财务这种核心数据,还是不建议使用mongoDB的

    点评

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

    该用户从未签到

    12#
     楼主| 发表于 2012-9-19 08:44:52 | 只看该作者
    梦晓半生 发表于 2012-9-19 04:21
    ) E9 T' G! ]; E  k: G谢谢。
      N' b, R6 ~, l) y: Z- O5 O/ M  q. L4 b
    中文看得真累,大部分还是英文术语。
    1 n. A" \7 S0 [6 D2 g$ b
    现在关于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 W! b# G/ ?. b% }4 W4 E/ t
    是我啊。。。这都能被认出来。。。
    % o3 }& l! ]0 @7 o+ @6 U
    是邓嫂么?

    该用户从未签到

    14#
     楼主| 发表于 2012-9-19 14:17:53 | 只看该作者
    profer 发表于 2012-9-19 14:16 6 b" v" P% ^" j9 `6 @, A
    是邓嫂么?

    4 u; f! A' v- j. q% g0 |是邓的小兵
  • 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
    / P5 s3 k8 }  _* N& G现在关于mongoDB的文章,大部分都是在告诉大家怎么用,涉及到内部运行机理的文章,数量不多,而且不成体 ...

    " k) L1 g# B5 z1 b! w# G+ s" @/ i9 w太好了,期待中,希望都带上英文reference。3 h# i2 r: x" N" p: L
    ( q% I- F$ \+ {
    现在这种新技术很多,Mongo是比较流行的一个,我这里附带一下一堆NoSQL的新系统,到最后估计会有几个胜出。: }9 W  G( k  D' w

    5 X! V0 n, K: l! g4 Uhttp://en.wikipedia.org/wiki/NoSQL

    该用户从未签到

    17#
     楼主| 发表于 2012-9-20 08:53:41 | 只看该作者
    梦晓半生 发表于 2012-9-20 00:57 . B; g" r$ [1 w" n0 V
    太好了,期待中,希望都带上英文reference。
    " ?) c# M1 {: G5 A$ R5 l! q' ?+ q% K- p4 q
    现在这种新技术很多,Mongo是比较流行的一个,我这里附带一 ...

    6 p+ N4 }, i9 j5 |2 U2 s: P现在写的也很纠结,资料太少了,哈哈

    该用户从未签到

    18#
    发表于 2012-9-21 11:52:33 | 只看该作者
    shengnan007 发表于 2012-9-20 08:53
    % z& [0 w; j& ?4 {2 |# f现在写的也很纠结,资料太少了,哈哈
    2 t* G9 |6 V  Q0 F' g
    建议从NoSQL写起,这是推动新数据库设计的需求关系,原始动力。
    3 X5 B: [+ l2 W" D+ p+ m7 c3 N4 W! B
    http://en.wikipedia.org/wiki/NoSQL
    ) Z8 i7 `1 a) H0 c1 Y& `- [) m9 q" C& |* c
  • TA的每日心情
    郁闷
    2019-4-22 08:49
  • 签到天数: 38 天

    [LV.5]元婴

    19#
    发表于 2012-9-21 17:03:12 | 只看该作者
    恶魔吹笛来 发表于 2012-9-19 18:35
    7 l) K( ]! W& I. b& y2 ~; k有点惊讶 居然在这里看到这篇文章 呵呵 静待大作
    5 C$ b4 S1 h1 f7 \
    有什么可惊讶的邓侃在前一个爱坛版本是很早的注册用户呢,从开心网一块迁移的。。。

    该用户从未签到

    20#
     楼主| 发表于 2012-9-24 09:11:03 | 只看该作者
    梦晓半生 发表于 2012-9-21 11:52
    9 h9 W8 J$ M4 |建议从NoSQL写起,这是推动新数据库设计的需求关系,原始动力。. {0 p* I7 k! d- T2 i, B/ M
    / {! Q# i, @4 f+ F  E/ Q
    http://en.wikipedia.org/wiki/NoSQL
    0 c: c5 e8 o! g& H3 l2 K
    好的好的,现在这个写完,然后开始写nosql

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

    GMT+8, 2025-12-25 23:59 , Processed in 0.041718 second(s), 21 queries , Gzip On.

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

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