MongoDB设计要点

来自:

http://apan.me/index.php/2011/05/01/mongodb%E8%AE%BE%E8%AE%A1%E8%A6%81%E7%82%B9/

前阵子研究自动扩容(Auto-Scaling)时,特意了解了一下MongoDB,这里简单记录一下其设计要点。
官网的描述为:MongoDB是一个高性能、高扩展性的文档型开源数据库,用C++实现,其主要特性为:

  • 面向文档(document-oriented storage)
  • 支持索引
  • 高可用性(replica sets)
  • 平行扩容(auto-sharding)等
基本概念
  • document:基本数据单元,相当于关系型数据库中的一行记录(Row);
  • collection:相当于关系型数据库中的表(table),但是是schema-free的table;
  • namespace:每个collection有其对应的一个namespace。
存储引擎
  1. 使用内存映射文件mmap实现,而32位机器受地址空间限制,所以单个实例最大数据空间仅为2.5G左右,64位机器基本无限制(128T),故建议使用64位机器部署。
  2. 每个数据库由一个.ns元数据文件,以及多个数据文件组成(dbname.{0,1,2,……},以自增的数字为扩展名)。为了防止小数据库浪费空间,MongoDB的数据文件默认从16M开始,倍数级别增加,2G为单个数据文件的大小上限。示例如下:
  3.  

     

  4. 每个数据文件按extents(区段)组织。每个namespace可以包含多个extents,可以不连续。类似于数据文件的倍数增长机制,每个namespace的extent大小同样按倍数增长。每个数据文件里面包含一个名为$freelist的特殊namespace,主要用于extent的回收管理(当collection被删除后)。
  5. .ns文件主要存储该DB下所有collection的元数据信息,例如该collection由哪些区段组成,有哪些索引等。每个区段的位置用如下数据结构表示:struct DiskLoc 
    {
        int filenum; //the 0 in test.0
        int offset; //position in file
    }; //64bits
  6. 因为使用mmap实现,内存管理全部交给OS处理。
  7. 参考文献:http://www.10gen.com/video/mongosv2010/storageengine
容灾备份

Replica Sets基本原理

Replica Set在工作过程中,由一台唯一的master(a primary)和一台或多台slave(secondaries)组成。当当前master不可用时,该Replica Set通过选举,选出一个新的slave作为新的master。

Replica Set组成

  • Standard:标准节点,包含有所有数据备份,可以被选举为master
  • Passive:包含所有数据备份,但是不可以被选举为master
  • Arbiter:仅仅用于投票,不包含任何数据,一般是用于判断网络状态时使用的仲裁。

Oplog

Oplog是Operation Log的简写,相当于MySQL的bin-log,是MongoDB复制机制的核心。Oplog存在名为local的特殊DB中,其collection名为oplog.$main。该collection定长,可以通过启动时通过—oplogSize参数设定。
每一条oplog包含有如下信息:
    ts:8字节的时间戳,由4字节unix timestamp + 4字节自增计数表示。这个值很重要,在选举新primary时,会选择ts最大的那个secondary作为新primary。
    op:1字节的操作类型,例如i表示insert,d表示delete。
    ns:操作所在的namespace。
    o:操作所对应的document。
Oplog是幂等的,只要按指定的先后顺序,是可以被多次执行的。例如一个自增(inc)操作,在oplog里面记录是一条set操作。

同步

当一个新备机启动时,先从主机做一个全量文档同步,然后查询master的oplog,并执行

选举算法

  • query all others for their maxappliedoptime
  • try to elect self if we have the highest time and can see a majority of nodes
    • if a tie on highest time, delay a short random amount first
    • elect (selfid,maxoptime) msg -> others
  • if we get a msg and our time is higher, we send back NO
  • we must get back a majority of YES
  • if a YES is sent, we respond NO to all others for 1 minute. Electing ourself counts as a YES.
  • repeat as necessary after a random sleep
自动扩容

Auto-sharding机制

  • Config Servers:存储整个集群的元数据,包括每个Shard Server的基本信息,以及其存储的Chunk信息。每个Config Server拥有这些元数据的全量备份。多个Config Server数据一致性通过二段式提交保证。如果某一个Config Server不可用,则整个集群的元数据变为只读状态,不可修改。
  • Router:路由器主要负责接收Client的请求,并将请求转发到对应的Shards,如有需要,还需合并结果集再返回Client。
  • Shard Servers:数据服务器,每个Shard一般是一个Replica Set。

路由表

Collection

Minkey

Maxkey

location

Users

{name : 1}

{name : miller}

Shard0

Users

{name : miller }

{name : Ness}

Shard1

Users

{name : Ness }

{name : Ogden }

Shard2

Users

{name : Ogden }

{name : 1}

Shard3

Chunks

一个Chunks表示该collection下的一个连续分区,其分区范围为[minkey, maxkey)。当一个Chunks大小增长至200M时,会自动的分裂为2个Chunk,如有必要,其中Chunks还会被迁移至其他Shard。
在选择Shard Keys时,需考虑该key是否能将数据均衡打散。例如以name作为key,如果很多人具有相同的name,则很有可能导致无法分裂及迁移。

案例分享

Foursquare宕机事件

foursquare去年10月,曾发生了一次长达11个小时的宕机事件。其主要原因是MongoDB的Shard算法不均导致。其详细分析参考Fenng的文章:Foursquare长达11小时的宕机
这里补充一下,因为MongoDB存储引擎使用mmap,其内存管理全部由OS处理,而OS是按page(页)来处理的,如果一个page里面包含多个小documents,仅删除该page里的某一个document并不能释放该页内存,故在该事件的处理过程中,最终花费了近5个小时执行repairDatabase。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值