`

【转】MongoDB 小结

阅读更多

用了一阵子mongodb,作一些小结,作为将来的参考。按照以往的习惯,先作一个总览,然后再挑出一些自己比较关注的几个点,作为珠玑,加以串联阐述。

 

mongodb由C++写就,其名字来自humongo us这个单词的中间部分,从名字可见其野心所在就是海量 数据的处理。关于它的一个最简洁描述为:scalable, high-performance, open source, schema-free, document-oriented database。我对于文档型数据库有一些个人的偏好,这种偏好是从半年前研究couchdb而来的,因为我觉得用它来描述一个具有个性化特征的实体对 象正合适,比如网站上的用户或商品书籍之类的条目。

 

一些概念:

跟mysqld一样,一个mongod服务可以有建立多个数据库,每个数据库可以有多张表,这里的表名叫collection,每个 collection可以存放多个文档(document),每个文档都以BSON(binary json)的形式存放于硬盘中。跟关系型数据库不一样的地方是,它是的以单文档为单位存储的,你可以任意给一个或一批文档新增或删除字段,而不会对其它文 档造成影响,这就是所谓的schema-free,这也是文档型数据库最主要的优点。跟一般的key-value数据库不一样的是,它的value中存储 了结构信息,所以你又可以像关系型数据库那样对某些域进行读写、统计等操作。可以说是兼备了key-value数据库的方便高效与关系型数据库的强大功 能。

 

索引

跟关系型数据库类似,mongodb可以对某个字段建立索引,可以建立组合索引、唯一索引,也可以删除索引。当然建立索引就意味着增加空间开销,我 的建议是,如果你能把一个文档作为一个对象的来考虑,在线上应用中,你通常只要对对象ID建立一个索引即可,根据ID取出对象某些数据放在 memcache即可。如果是后台的分析需要,响应要求不高,查询非索引的字段即便直接扫表也费不了太多时间。如果还受不了,就再建一个索引得了。

默认情况下每个表都会有一个唯一索引:_id,如果插入数据时没有指定_id,服务会自动生成一个_id,为了充分利用已有索引,减少空间开销,最好是自己指定一个unique的key为_id,通常用对象的ID比较合适,比如商品的ID。

 

capped collection

capped collection是一种特殊的表,它的建表命令为:

db.createCollection("mycoll", {capped:true, size:100000})

允许在建表之初就指定一定的空间大小,接下来的插入操作会不断地按顺序APPEND数据在这个预分配好空间的文件中,如果已经超出空间大小,则回到 文件头覆盖原来的数据继续插入。这种结构保证了插入和查询的高效性,它不允许删除单个记录,更新的也有限制:不能超过原有记录的大小。这种表效率很高,它 适用于一些暂时保存数据的场合,比如网站中登录用户的session信息,又比如一些程序的监控日志,都是属于过了一定的时间就可以被覆盖的数据。

 

复制与分片

mongodb的复制架构跟mysql也很类似,除了包括master-slave构型和master-master构型之外,还有一个 Replica pairs构型,这种构型在平常可以像master-slave那样工作,一但master出现问题,应用会自动了连接slave。要做复制也很简单,我 自己使用过master-slave构型,只要在某一个服务启动时加上–master参数,而另一个服务加上–slave与–source参数,即可实现 同步。

分片是个很头疼的问题,数据量大了肯定要分片,mysql下的分片正是成为无数DBA的噩梦。在mongodb下,文档数据库类似key- value数据库那样的易分布特性就显现出来了,无论构造分片服务,新增节点还是删除节点都非常容易实现。但mongodb在这方面做还不足够成熟,现在 分片的工作还只做到alpha2版本(mongodb v1.1),估计还有很多问题要解决,所以只能期待,就不多说了。

 

性能

 

在我的使用场合下,千万级别的文档对象,近10G的数据,对有索引的ID的查询不会比mysql慢,而对非索引字段的查询,则是全面胜出。 mysql实际无法胜任大数据量下任意字段的查询,而mongodb的查询性能实在让我惊讶。写入性能同样很令人满意,同样写入百万级别的数 据,mongodb比我以前试用过的couchdb要快得多,基本10分钟以下可以解决。补上一句,观察过程中mongodb都远算不上是CPU杀手。

 

GridFS

gridfs是mongodb一个很有趣的类似文件系统的东西,它可以用一大块文件空间来存放大量的小文件,这个对于存储web2.0网站中常见的大量小文件(如大量的用户头像)特别有效。使用起来也很方便,基本上跟一般的文件系统类似。

 

用合适的数据库做适合的事情

mongodb的文档里提到的user case包括实时分析、logging、全文搜索,国内也有人使用mongodb来存储分析网站日志,但我认为mongodb用来处理有一定规模的网站日 志其实并不合适,最主要的就是它占空间过于虚高,原来1G的日志数据它可以存成几个G,如此下去,一个硬盘也存不了几天的日志。另一方面,数据量大了肯定 要考虑sharding,而mongodb的sharding到现在为止仍不太成熟。由于日志的不可更新性的,往往只需APPEND即可,又因为对日志的 操作往往只集中于一两列,所以最合适作为日志分析的还是列存储型的数据库,特别是像infobright那样的为数据仓库而设计的列存储数据库。

由于mongodb不支持事务操作,所以事务要求严格的系统(如果银行系统)肯定不能用它。

 

mongodb占用空间过大的原因,在官方的FAQ中,提到有如下几个方面:

1、空间的预分配:为避免形成过多的硬盘碎片,mongodb每次空间不足时都会申请生成一大块的硬盘空间,而且申请的量从64M、128M、 256M那样的指数递增,直到2G为单个文件的最大体积。随着数据量的增加,你可以在其数据目录里看到这些整块生成容量不断递增的文件。

 

2、字段名所占用的空间:为了保持每个记录内的结构信息用于查询,mongodb需要把每个字段的key-value都以BSON的形式存储,如果 value域相对于key域并不大,比如存放数值型的数据,则数据的overhead是最大的。一种减少空间占用的方法是把字段名尽量取短一些,这样占用 空间就小了,但这就要求在易读性与空间占用上作为权衡了。我曾建议作者把字段名作个index,每个字段名用一个字节表示,这样就不用担心字段名取多长 了。但作者的担忧也不无道理,这种索引方式需要每次查询得到结果后把索引值跟原值作一个替换,再发送到客户端,这个替换也是挺耗费时间的。现在的实现算是 拿空间来换取时间吧。

 

3、删除记录不释放空间:这很容易理解,为避免记录删除后的数据的大规模挪动,原记录空间不删除,只标记“已删除”即可,以后还可以重复利用。

 

4、可以定期运行db.repairDatabase()来整理记录,但这个过程会比较缓慢。

因为官方文档 中对各方面的内容已经有很详细的叙述,所以我并没有再过多的引用原文与代码,只是结合自己的使用归纳一些心得,有兴趣的朋友不妨直接去翻文档中自己感兴趣的问题,超群的博客 上有一个很好的入门介绍。

最后总结一句,文档型数据库有点像波粒二象性,总能在适当的时候表现出它作为关系型数据库或key-value数据库的优势来。

 

 

实战案例:

昨天我访问mongodb的python程序开始出错,经常抛出AssertionError异常,经查证只是master查询异常,slave正常,可判断为master的数据出了问题。

修复过程:

1、在master做db.repairDatabase(),不起作用;

2、停止slave的同步;

3、对slave作mongodump,备份数据;

4、对master作mongostore,把备份数据恢复,使用–drop参数可以先把原表删除。

5、恢复slave的同步。

分享到:
评论

相关推荐

    MongoDB 语法使用小结

    MongoDB 是一种流行的NoSQL数据库系统,它结合了关系数据库和非关系数据库的优点,提供了一种灵活且高性能的数据存储解决方案。MongoDB 使用BSON(Binary JSON)格式存储数据,这种格式与JSON相似,但支持二进制数据...

    nosql实验六- MongoDB的安装与基本操作.docx

    MongoDB 安装与基本操作 MongoDB 是一款流行的 NoSQL 数据库,广泛应用于大数据和实时 Web 应用程序。在本实验中,我们将学习如何在 Windows 和 Linux 环境下安装 MongoDB,并了解 MongoDB 的基本操作。 一、...

    MongoDB集群安装配置

    #### 七、小结 通过上述步骤,我们成功在Ubuntu 16环境下配置了一个包含四台服务器的MongoDB集群,并进行了基本的功能测试。此配置适用于初步了解MongoDB集群的工作原理及其基本使用方法,为更复杂的应用场景打下了...

    深入云计算 MongoDB管理与开发实战详解pdf.part1

    作为基于分布式文件存储的数据库,在目前的云计算实践中,MongoDB炙手可热。《深入云计算(MongoDB管理与开发实战详解)》系统全面的介绍了MongoDB开发、管理、维护和性能优化等方方面面。...16.6 本章小结

    Mongodb聚合

    #### 小结 聚合框架是 MongoDB 中一项重要的功能,它提供了一种灵活的方式来处理复杂的数据分析任务。通过组合不同的管道阶段,可以构建出满足各种需求的查询逻辑。掌握这些基本的管道阶段及其使用方法对于高效地...

    MongoDB北京2014 - MongoDB性能扩展 - 唐建法

    **小结**:根据数据访问的方式合理设计数据模型,必要时可以采用数据冗余来提高读取性能。 #### 索引优化 **背景**:索引是提高查询性能的重要手段之一。合适的索引设计能够显著减少查询时间。 **案例**:电话簿...

    Matlab连接MongoDB操作指引

    #### 七、小结 通过以上步骤,我们不仅能够成功地在Matlab环境中连接MongoDB数据库,还能执行一些基本的数据操作。这对于需要在数据分析过程中集成数据库应用的开发者来说,是非常有用的技能。当然,对于更复杂的...

    node.js操作mongodb学习小结

    1、在mongodb创建将要读取的表 创建数据库mongotest 代码如下: use mongotest; 向user表中插入数据 代码如下: db.user.insert({ name:’flyoung’, age:’18’, sex:true }); 2、安装node-mongodb-native 代码...

    Python操作Mongodb数据库的方法小结

    本文实例讲述了Python操作Mongodb数据库的方法。分享给大家供大家参考,具体如下: 一 导入 pymongo from pymongo import MongoClient 二 连接服务器 端口号 27017 连接MongoDB 连接MongoDB我们需要使用PyMongo库...

    mongodb基本命令实例小结

    MongoDB是一种流行的开源文档型数据库,它以JSON格式存储数据,提供高性能、高可用性和可扩展性。在本文中,我们将深入探讨MongoDB的基本命令,包括数据库切换、查看、删除和查询,以及备份和恢复策略。 1. **切换...

    MongoDB常用命令小结

    MongoDB是一款流行的开源文档型数据库,以其灵活性、高性能和易用性而备受开发者喜爱。本文将详述MongoDB的一些常用命令,帮助读者更好地理解和操作MongoDB数据库。 首先,我们来看几个与用户管理相关的命令。`use ...

    深入云计算 MongoDB管理与开发实战详解pdf.part2

    作为基于分布式文件存储的数据库,在目前的云计算实践中,MongoDB炙手可热。《深入云计算(MongoDB管理与开发实战详解)》系统全面的介绍了MongoDB开发、管理、维护和性能优化等方方面面。...16.6 本章小结

    MongoDB实战开发 - 零基础学习

    #### 小结 本文通过实战演练,介绍了如何在零基础的情况下,运用C#语言访问和操作MongoDB数据库。从MongoDB的安装配置,到C#驱动的集成使用,再到具体的业务场景代码示例,每个环节都紧密相连,旨在帮助读者快速...

Global site tag (gtag.js) - Google Analytics