设为首页收藏本站

爱吱声

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

[信息技术] MongoDB架构概览

[复制链接]

该用户从未签到

跳转到指定楼层
楼主
发表于 2012-9-18 12:31:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    关于MongoDB,我们能看到的资料,基本都是在指导大家如何使用MongoDB,但是,MongoDB内部是如何运作的,资料不是很多。/ C0 K" j/ s3 L" z. ~

& c) K3 \3 j/ M& S: I( A0 w. U    阅读使用手册,会有很多疑惑之处。例如,有人说,MongoDB 等同于分布式的 MySQL。它把一个Table ,按 row,分割成多个Shards,分别存放在不同的 Servers 上。这种说法是否正确?' |* `' ~- i1 j& Q) T; E1 K8 E
1 s( B) A- j  m+ r
    不深入了解 MongoDB 的内部结构,就无法透彻地回答类似问题。这个系列文章,就来和大家探讨MongoDB的内部的工作方式。
* }# X3 Q9 n+ X
. k1 ?7 }- q6 \
/ E: J8 c! M( A  }

% F8 w$ ?" O  P! d/ X2 z0 j/ d图1-1 MongoDB架构图

1 n+ {3 ?; o! F4 M7 [0 o
" u/ W. O/ C% o* K  N; K# j    MongoDB 通常运行在一个服务器集群上,而不是一个单机。图1-1,描述了一个MongoDB集群的基本组成部分,包括若干shards,至少一个config server,至少一个routing servers(又称 mongos)。' M+ t$ V% E2 h5 \. g% s
" u& j, R7 I3 k5 ?" c& B" M
Shards4 P* N6 ?# U8 f
1 z' D+ i' [0 v' e
    MongoDB的最基本的数据单元,叫document,类似于关系式数据库中的行 row。一系列documents,组成了一个collection,相当于关系式数据库中的table。当一个 collection 数据量太大时,可以把该collection按documents切分,分成多个数据块,每个数据块叫做一个chunk,多个chunks聚集在一起,组成了一个shard。$ {# y" h4 c. E0 ~3 S: X
6 L% x; u( C" L! b5 L7 T" v2 z
    Sharding 的意义,不仅保障了数据库的扩容(scalability),同时也保障了系统的负载均衡(load balance)。" f4 d* B! e5 l5 T5 b6 R' p
+ g. K9 r- y4 u3 B+ u) N
    每一个shard存储在一个物理服务器(server)上。Server上运行着mongod进程,通过这个进程,对shard中的数据进行操作,主要是增删改查。
3 A: p: a& m2 _, {" F) _) B% ]) h, ~" v& m; s$ D3 U" S
    如果系统中的每个shard,只存储了一份数据,没有备份,那么当这个shard所在的server挂了,数据就丢失了。在生产环境中,为了保证数据不丢失,为了提高系统的可用性(availability),每一个shard被存储多份,每个备份所在的servers,组成了一个replica set。0 c+ h7 ~  D+ g  r4 K
" U( O! w7 r8 U5 n) g4 l
Shard keys2 X9 c0 v2 m. x* M1 w% A0 _# s
        
! u: V8 E0 g% [3 q: b2 n    为了把collection切分成不同的chunks,从而存放到不同的shards中,我们需要制定一个切分的方式。8 G5 R3 \( n3 b

7 `& J" B* Q. q) z    如前所述,在 MongoDB 数据库中,一个表collection由多个行 documents 组成,而每个 document,有多个属性 fields。同一个 collection 中的不同的 documents,可能会有不同的 fields。例如,有个 collection 叫 Media,包含两条 documents,
3 m, D$ z' W# C# ~$ d
* v. `  f5 A& r$ Y3 r- W& \, V{/ }, ], E1 C5 q
  "ISBN": "987-30-3652-5130-82",6 c) f' M0 q( M$ N* y# l" }
  "Type": "CD",5 P2 T& ]  ?) u$ k1 t: A- b
  "Author": "Nirvana",
6 ?, a" b0 N' @7 Q9 \  M* C  "Title": "Nevermind",& v/ e! n2 T6 K" w/ s2 f
  "Genre": "Grunge"," _1 s; b' X- r; r) j) b5 L$ w# V
   "Releasedate": "1991.09.24",6 d# a, z" c3 Q; T2 V
   "Tracklist": [
/ |' t& @7 ?/ i2 U  D% F     {
6 ^/ B  v1 p" Z$ U        "Track" : "1",
7 @( Q! N5 R" k- U: c3 F        "Title" : "Smells like teen spirit",
, ~# {" t0 s% f/ o        "Length" : "5:02"
! y, \2 G9 c- `! X) S) G0 g8 V: f     },8 f% C7 @0 o& r" W
     {" }3 E, @( z" |! B5 c
        "Track" : "2",
: S; `' j, p3 h7 z# ~; o2 u1 ?  Z        "Title" : "In Bloom",
. Y% d6 ~% W* ?        "Length" : "4:15"
; H2 P. N! r3 }9 J' N' A     }
% U9 F: e. r* I0 s   ]) C' \4 n! J' j. j% a8 W2 e* S" V/ A
}; X3 l0 S8 c& {/ n7 x

4 ?5 |7 T" A" q" ^& J" o% ^{
: H3 ?9 a9 |" C( l6 @  "ISBN": "987-1-4302-3051-9",8 c- e7 C8 W3 F& E! @/ r
  "Type": "Book",
0 J3 T& d4 j- m0 V  "Title": "Definite Guide to MongoDB: The NoSQL Database",! k6 t( b' Y# `
  "Publisher": "Apress",
; j4 J2 c. ]7 |+ B3 G/ {  "Author": " Eelco Plugge",9 J* A8 K% h8 j5 g/ W
  "Releasedate": "2011.06.09"
: O5 X! i+ o$ Y+ P: R- z' p/ ~9 O}  w1 B6 B- i! D% @

4 M$ c7 c) N' v0 j9 F  \6 D    假如,在同一个 collection 中的所有 document,都包含某个共同的 field,例如前例中的“ISBN”,那么我们就可以按照这个 field 的值,来分割 collection。这个 field 的值,又称为 shard key。
( r& j' t# a1 A0 P+ M, q+ ?1 b8 B0 \- A
    在选择shard key的时候,一定要确保这个key能够把collection均匀地切分成很多chunks。9 ^3 p6 l: x) [3 H

- P( ?' y0 o# P- X# ]0 f    例如,如果我们选择“author”作为shard key,如果有大量的作者是重名的,那么就会有大量的数据聚集在同一个chunk中。当然,假设很少有作者同名同姓,那么“author”也可以作为一个shard key。换句话说,shard key 的选择,与使用场景密切相关。
+ \/ _! p1 U* y8 T3 [5 Y7 k3 s7 X" z, j  U+ H) }' h6 M
    很多情况下,无论选择哪一个单一的 field 作为shard key,都无法均匀分割 collection。在这种情况下,我们可以考虑,用多个 fields,构成一个复合的shard key。9 p3 h# Q# b. n8 V0 X# E3 W
! @0 m" a$ R/ z# C! U5 w3 l& s
    延续前例,假如有很多作者同名同姓,他们都叫“王二”。用 author 作为 shard key,显然无法均匀切割 collection。这时我们可以加上release-date,组成name-date的复合 shard key,例如“王二 2011”。3 C/ n: m" j- W
. c* F" t# q& F  O0 P
Chunks
" B  R: ^3 T) e- O1 d2 G        # Y7 i/ p, _3 U
    MongoDB按 shard key,把 collection切割成若干 chunks。每个 chunk 的数据结构,是一个三元组,{collection,minKey,maxKey},如图1-2 所示。
) K# E  V; j( @* @0 ?  j& I% _3 b5 x; z' W+ V; N
3 k8 x8 F8 X$ E5 W. F: g: B" j" r
图1-2 chunk的三元组

2 C  ^! S7 e1 H6 v7 D( E' J1 F
% Q4 a9 J9 n& f5 ?1 N4 G; u    其中,collection 是数据库中某一个表的名称,而 minKey 和 maxKey 是 shard key的范围。每一个 document 的shard key 的值,决定了这条document应该存放在哪个chunk中。  x, w& C  m5 Z9 J2 M% l

0 T0 E" T# ~+ b% R+ C    如果两条 documents 的 shard keys 的值很接近,这两条 documents 很可能被存放在同一个 chunk 中。
' ?2 S" m+ X: s
9 L8 h5 _7 _& J( O( _' F4 Y* d    Shard key 的值的顺序,决定了 document 存放的 chunk。在 MongoDB 的文献中,这种切割 collection 的方式,称为order-preserving。) q  k2 _8 Z5 C& x  Z
! w2 o+ e$ S( K
    一个 chunk最多能够存储64MB的数据。 当某个chunk存储的 documents包含的数据量,接近这个阈值时,一个chunk会被切分成两个新的chunks。0 m+ X* L& g( a4 M" V) p
) {2 f3 F, _* x/ D4 @* p
    当一个shard存储了过多的chunks,这个shard中的某些chunks会被迁移到其它 shard中。
1 F% j* p* B9 H5 m, r3 d& b- g4 }+ L. N* ^: z9 o8 @
    这里有个问题,假如某一条 document 包含的数据量很大,超过 64MB,一个 chunk 存放不下,怎么办?在后续章节介绍 GridFS 时,我们会详细讨论。/ y/ D2 E2 E5 {& W; J4 }! U
, ]& o- k3 V9 `' x
Replica set
! d; p: X% N! {5 L( N6 _+ O! _        
, o+ @/ S9 `; Q: S. f    在生产环境中,为了保证数据不丢失,为了提高系统的可用性(availability),每一个shard被存储多份,每个备份所在的servers,组成了一个replica set。
  e! z9 _  e7 @* ]' `2 b
: U/ `5 V4 G( B2 Z: _5 P    这个replica set包括一个primary DB和多个secondary DBs。为了数据的一致性,所有的修改(insert / update / deletes) 请求都交给primary处理。处理结束之后,再异步地备份到其他secondary中。( I& [- x, I' e

& R# }: c# r  u    Primary DB由replica set中的所有servers,共同选举产生。当这个primaryDB server出错的时候,可以从replica set中重新选举一个新的primaryDB,从而避免了单点故障。# p8 g3 e. T5 R( e; z5 o
! T  b) D( N; ]2 o7 _7 o- ]' j
    Replica set的选举策略和数据同步机制,确保了系统的数据的一致性。后文详述。* a0 Z( F( K$ p! _( h7 E

. r! z- v& ~# G1 \5 ^Config Server. ]3 a+ S' ]# |6 \) x7 z
        # w3 _1 V  @/ r& O: v) c
    Config servers用于存储MongoDB集群的元数据 metadata,这些元数据包括如下两个部分,每一个shard server包括哪些chunks,每个chunk存储了哪些 collections 的哪些 documents。$ t; D* m  r7 G! v9 l

% c* U+ r; F4 e" M    每一个config server都包括了MongoDB中所有chunk的信息。, n( k2 p. W  w! [* e
3 Y3 v+ ]0 Y4 R% ?* ]4 l( V
    Config server也需要 replication。但是有趣的是,config server 采用了自己独特的replication模式,而没有沿用 replica set。
3 d! J+ {* Z  k
- F, f, [. \9 ?    如果任何一台config server挂了,整个 config server 集群中,其它 config server变成只读状态。这样做的原因,是避免在系统不稳定的情况下,冒然对元数据做任何改动,导致在不同的 config servers 中,出现元数据不一致的情况。. K. a* y# D0 O% t) I" T4 n

0 K! m1 m. k/ Q$ {9 g! t3 s    MongoDB的官方文档建议,配置3个config servers比较合适,既提供了足够的安全性,又避免了更多的config servers实例之间的数据同步,引起的元数据不一致的麻烦。
; x5 d7 e/ _2 r: ?1 t  {3 C1 o) |7 q2 g9 |5 m6 i
Mongos
4 k+ E% U6 B! t$ w
8 J% {6 E" O5 S0 U1 [4 ?9 ?    用户使用MongoDB 时,用户的操作请求,全部由mongos来转发。. u. ~) }" v& d; E! i

; b4 {7 M5 _7 o- @- q' L) B: z    当 mongos 接收到用户请求时,它先查询 config server,找到存放相应数据的shard servers。然后把用户请求,转发到这些 shard servers。当这些 shard servers完成操作后,它们把结果分别返回给 mongos。而当 mongos 汇总了所有的结果后,它把结果返回给用户。; C! A. q. f) B% i% z3 i: t7 k

4 l! f( L2 @4 t  u8 u- Y    Mongos每次启动的时候,都要到config servers中读取元数据,并缓存在本地。每当 config server中的元数据有改动,它都会通知所有的mongos。) R) r3 [/ q2 C- s

2 u% j- |! v* o7 n* ]) ]    Mongos之间,不存在彼此协同工作的问题。因此,MongoDB所需要配置的mongos server的数量,没有限制。, B* S; y5 g) ]& ]  ^
# v5 n8 ^$ l/ ?+ q' B2 }
    通过以上的介绍,我们对每个组成部分都有了基本的了解,但是涉及到工作的细节,我们尚有诸多疑问,例如,一个chunk的数据太大,如何切分?一个shard数据太多,如何迁移?在replica set中,如何选择primary?server挂了,怎么进行故障恢复?接下来的章节,我们逐个回答这些问题。5 }8 q4 j6 Q+ {; m0 u9 z) j" q

0 P* ~7 C% r: `) [. S3 r: r! k/ X: f
$ U1 s1 X7 |* {, H/ Z5 C/ l" b9 tReference,  A4 x$ Q; I1 n: f1 e7 U

- \8 E; i; i9 F/ v6 M[0] Architectural Overview) p# u& I4 a* L5 E4 a- T& u
http://www.mongodb.org/display/DOCS/Sharding+Introduction
6 _/ w9 M. j# C- N! V" k- Z5 L

评分

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

查看全部评分

该用户从未签到

沙发
发表于 2012-9-18 12:40:50 | 只看该作者
本帖最后由 PenPen 于 2012-9-18 12:44 编辑
# Q% Z* U1 _9 ?  m( K* X8 b& f6 ]
2 L+ m  C, T# X9 ?5 l6 ?
* _. i/ a7 S' t/ }- ^您是和邓侃一起写文章的盛楠么?

该用户从未签到

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

该用户从未签到

地板
 楼主| 发表于 2012-9-18 12:44:45 | 只看该作者
PenPen 发表于 2012-9-18 12:40 / u! F! b& P8 p) A( A
您是和邓侃一起写文章的盛楠么?
2 `6 V" d# t, }+ k/ M, L) t" ^* r
是我啊。。。这都能被认出来。。。

该用户从未签到

5#
发表于 2012-9-18 12:47:20 | 只看该作者
shengnan007 发表于 2012-9-18 12:44
1 B3 s/ J" Q+ F是我啊。。。这都能被认出来。。。

$ s0 T) g6 W, O+ h% f这篇文章我读过。开始以为是转贴的,后来再一看id就发现真相了~

该用户从未签到

6#
 楼主| 发表于 2012-9-18 12:49:50 | 只看该作者
PenPen 发表于 2012-9-18 12:47 / r" z6 o7 L$ h4 G- r
这篇文章我读过。开始以为是转贴的,后来再一看id就发现真相了~
. `2 U( |. m, L/ X8 O% [
多谢支持。还有两篇一会帖过来。后续的还在写。边看源码边写,比较慢,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
    - E" _1 ~; P; f4 B, Z! t多谢支持。还有两篇一会帖过来。后续的还在写。边看源码边写,比较慢,hoho。这里是要推荐才能变成正式会 ...
    $ R& k0 z* M  W# k4 |- [4 v
    欢迎,欢迎,已经给你变成正式会员了。

    该用户从未签到

    8#
     楼主| 发表于 2012-9-18 12:57:15 | 只看该作者
    不爱吱声 发表于 2012-9-18 12:51 9 y. p2 m* \# m0 O+ G$ F( O
    欢迎,欢迎,已经给你变成正式会员了。
    # w; X, `0 _( Z' Z
    多谢多谢啦~~
  • TA的每日心情
    慵懒
    2020-1-15 02:37
  • 签到天数: 1287 天

    [LV.10]大乘

    9#
    发表于 2012-9-19 03:38:34 | 只看该作者
    我们现在的 technology stack 就是 php + mongodb,涉及财务方面的东西用 postgres。
    ' j% q: f" j/ F" O7 c. D0 r- O3 N6 Q8 o

    该用户从未签到

    10#
    发表于 2012-9-19 04:21:40 | 只看该作者
    谢谢。( n2 a5 X; F/ Z  O5 v+ K1 E

    7 \# e1 O" z/ u6 c3 c. o中文看得真累,大部分还是英文术语。
    4 H& |+ N4 c: T/ i% I" F5 d( b6 I3 {6 [; F  v& c. O( @
    这应该是一个系列吧,后面怎样寻找,执行指令等开始入门,还是说的太简单了。' m& ~2 O6 }" L

    " v; ?! o& u- p: u. k现在distributed DB在那些大网站很重要,现在开始有跟已有DB分庭抗礼的苗头,不过不是那里工作的话,其中的奥妙大概难说清楚。

    该用户从未签到

    11#
     楼主| 发表于 2012-9-19 08:40:52 | 只看该作者
    巴山 发表于 2012-9-19 03:38 - _7 B5 V1 Z! |) }( G
    我们现在的 technology stack 就是 php + mongodb,涉及财务方面的东西用 postgres。/ P% z2 R% L/ w
    / f$ O7 ~; v! Q
    ...
    6 d% ~; B2 c! ?8 R" e; b3 o
    mongoDB作为存储是没有问题的,财务这种核心数据,还是不建议使用mongoDB的

    点评

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

    该用户从未签到

    12#
     楼主| 发表于 2012-9-19 08:44:52 | 只看该作者
    梦晓半生 发表于 2012-9-19 04:21
    ; l7 s  d( Z/ Q- }1 u; q% C9 S谢谢。# a  d6 C  ?% T( F

    2 R2 N: _* q+ y6 _中文看得真累,大部分还是英文术语。

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

    [LV.1]炼气

    13#
    发表于 2012-9-19 14:16:01 | 只看该作者
    shengnan007 发表于 2012-9-18 12:44 # T: Y9 e, c/ d  x/ j: ?% v
    是我啊。。。这都能被认出来。。。

    ! O4 `5 v: B) W; x* e是邓嫂么?

    该用户从未签到

    14#
     楼主| 发表于 2012-9-19 14:17:53 | 只看该作者
    profer 发表于 2012-9-19 14:16 - g. z; S# R# o
    是邓嫂么?

    8 J1 V8 x5 ~1 `' w2 G0 M9 S是邓的小兵
  • 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 : v3 g5 u4 Y- V0 {2 h$ y- p- ?* V+ k
    现在关于mongoDB的文章,大部分都是在告诉大家怎么用,涉及到内部运行机理的文章,数量不多,而且不成体 ...

    * ]2 D  [; z- q# a2 j  L3 @$ z太好了,期待中,希望都带上英文reference。
    : C6 j" \0 z# i
      D1 B8 h% ~: h: I% }$ ]- v现在这种新技术很多,Mongo是比较流行的一个,我这里附带一下一堆NoSQL的新系统,到最后估计会有几个胜出。
    ' L# L6 [( _+ \+ L. Q
      M0 a0 d# s8 s3 X& |http://en.wikipedia.org/wiki/NoSQL

    该用户从未签到

    17#
     楼主| 发表于 2012-9-20 08:53:41 | 只看该作者
    梦晓半生 发表于 2012-9-20 00:57
    1 S. {8 P8 g7 D太好了,期待中,希望都带上英文reference。- K7 t+ c9 I) ]% [
      C' r. v8 D+ O) H
    现在这种新技术很多,Mongo是比较流行的一个,我这里附带一 ...
    - A9 P* d  y" w( ~5 o
    现在写的也很纠结,资料太少了,哈哈

    该用户从未签到

    18#
    发表于 2012-9-21 11:52:33 | 只看该作者
    shengnan007 发表于 2012-9-20 08:53 7 n! E, e6 D. t/ H; u  r% Z
    现在写的也很纠结,资料太少了,哈哈
    1 B8 C  ?: G9 q9 {
    建议从NoSQL写起,这是推动新数据库设计的需求关系,原始动力。
    / o: ?8 q; ~" @) t, p/ v0 Q7 d" p) j
    % O- y  N# @8 q  s; q. fhttp://en.wikipedia.org/wiki/NoSQL8 E  U: F4 f' r1 f
    / \6 J+ L8 v9 @+ f8 Y) q% A
  • TA的每日心情
    郁闷
    2019-4-22 08:49
  • 签到天数: 38 天

    [LV.5]元婴

    19#
    发表于 2012-9-21 17:03:12 | 只看该作者
    恶魔吹笛来 发表于 2012-9-19 18:35
    + d- @; s, Q# O7 r/ U有点惊讶 居然在这里看到这篇文章 呵呵 静待大作
    9 B  ?. i3 t. _6 |  U& C
    有什么可惊讶的邓侃在前一个爱坛版本是很早的注册用户呢,从开心网一块迁移的。。。

    该用户从未签到

    20#
     楼主| 发表于 2012-9-24 09:11:03 | 只看该作者
    梦晓半生 发表于 2012-9-21 11:52   B! e9 S; I8 C' [3 Z# ~- V
    建议从NoSQL写起,这是推动新数据库设计的需求关系,原始动力。+ f# [" c$ Q" \5 N  u

    ( Z/ w( f2 [# j- y+ h7 W; Dhttp://en.wikipedia.org/wiki/NoSQL
      K9 ^7 v/ y+ k, _: G+ \1 Q
    好的好的,现在这个写完,然后开始写nosql

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

    GMT+8, 2026-9-10 21:54 , Processed in 0.084392 second(s), 21 queries , Gzip On.

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

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