zoukankan      html  css  js  c++  java
  • MongoDB的江湖传说

         MongoDB之父:MongoDB胜过BigTable

    Dwight Merriman和他的团队,包括ShopWiki的创始人Eliot Horowitz参加了在纽约10gen启动MongoDB的仪式。现在该公司除了担任该开源项目的主要运营者之外,还提供支持、培训和咨询服务。10gen在旧金山举办了第二届开发者大会,Merriman在上午的大会做了主题演讲,主要介绍了MongoDB的起源,并解释了为何要建立这样的数据库。

    “在2007年底,当时的想法是构建一个用于开发、托管并具有自动缩放Web应用程序的在线服务”,谈到MongoDB诞生之目的时,Merriman介绍道。“但是不同于Google App Engine的是,这项服务完全建立在一个开放源代码的软件平台之上。”因此,在关注了Google Bigtable架构很长一段时间后,Merriman和他的团队注意到,尚没有一个开源的数据库平台适合这种服务,这兴许是个机会。

    “我们意识到很多现有的数据库并不真正具备‘云计算’的特性。例如弹性、可扩展性以及易管理性。这些特性能够为开发者和运营者带来便利,而MySQL还不完全具备这些特点。

    因此,Dwight Merriman以及他的团队的目标是构建一个全新的数据库。新的数据库将会放弃大家所熟悉的关系数据库模型,且是适合现代网络应用并基于分布式的平台。高度事务性的系统可以帮助解决一些棘手的问题,同时还支持云计算架构的伸缩性。Merriman解释到。经过一年的不断努力,这个数据库已经比较完善。他们将它设计为具有为“云计算服务”潜力的数据库。而且还会不断的完善,因为MongoDB本身就是一个开源数据库。

    在开源的、面向文档的数据库中,MongoDB经常被誉为具有RDBMS功能的NoSQL数据库。MongoDB还带有交互式shell,这使得访问其数据存储变得简单,且其对于分块的即装即用的支持能够使高可伸缩性跨多个节点。

    据悉,MongoDB的API是JSON对象和JavaScript函数的本地混合物。通过shell程序开发人员可与MongoDB进行交互,即允许命令行参数,或通过使用语言驱动程序来访问数据存储实例。这里不存在类JDBC驱动程序,这意味着开发人员不必处理ResultSet或PreparedStatement。

    而速度是 MongoDB 的另外一个优势,主要是由于它处理写入的方式:它们存储在内存中,然后通过后台线程写入磁盘。

    “由于用户不容易在大规模环境下作分布式的链接,并且在分布式环境下很难做快速的大规模部署,因此,用户需要一些辅助的东西”,Memmiman解释道。

    最后他表示同样重要的是为了限制数据库的事务语义你可以使用分布式事务。但当你在1000台机器上运行时它不会那么快。例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。(李智/译)

         MongoDB与CouchDB全方位对比

    本文见于MongoDB官方网站,MongoDB与CouchDB很相似,他们都是文档型存储,数据存储格式都是JSON型的,都使用Javascript进行操作,都支持Map/Reduce。但是其实二者有着很多本质的区别,本文透过现象追寻本质,让你更好的理解MongoDB与CouchDB。

    1.MVCC(Multiversionconcurrency control)

    MongoDB与CouchDB的一大区别就是CouchDB是一个MVCC的系统,而MongoDB是一个update-in-place的系统。这二者的区别就是,MongoDB进行写操作时都是即时完成写操作,写操作成功则数据就写成功了,而CouchDB一个支持多版本控制的系统,此类系统通常支持多个结点写,而系统会检测到多个系统的写操作之间的冲突并以一定的算法规则予以解决。

    2.水平扩展性

    在扩展性方面,CouchDB使用replication去做,而MongoDB的replication仅仅用来增强数据的可靠性,MongoDB在实现水平扩展性方面使用的是Sharding。(据说CouchDB也有开发分片功能的计划)

    3.数据查询操作

    这个区别在用户接口上了,MongoDB与传统的数据库系统类似,支持动态查询,即使在没有建立索引的行上,也能进行任意的查询。而CouchDB不同,CouchDB不支持动态查询,你必须为你的每一个查询模式建立相应的view,并在此view的基础上进行查询。

    4.原子性

    这一点上两者比较一致,都支持针对行的原子性修改(concurrentmodifications of single documents),但不支持更多的复杂事务操作。

    5.数据可靠性

    CouchDB是一个”crash-only”的系统,你可以在任何时候停掉CouchDB并能保证数据的一致性。而MongoDB在不正常的停掉后需要运repairDatabase()命令来修复数据文件,在1.7.5版本后支持单机可靠的–dur命令。

    6.Map/Reduce

    MongoDB和CouchDB都支持Map/Reduce,不同的是MongoDB只有在数据统计操作中会用到,而CouchDB在变通查询时也是使用Map/Reduce。

    7.使用 javascript

    MongoDB和CouchDB都支持javascript,CouchDb用javascript来创建view。MongoDB使用JSON作为普通数据库操作的表达式。当然你也可以在操作中包含javascript语句。MongoDB还支持服务端的javascript脚本(running arbitrary javascript functions server-side),当然,MongoDB的Map/Reduce函数也是javascript格式的。

    8.REST

    CouchDB是一个RESTFul的数据库,其操作完全走HTTP协议,而MongoDB是走的自己的二进制协议。MongoDB Server在启动时可以开放一个HTTP的接口供状态监控。

    9.性能

    此处主要列举了MongoDB自己具有高性能的原因

    采用二进制协议,而非CouchDB REST的HTTP协议

    使用Momary Map内存映射的做法

    collection-oriented,面向集合的存储,同一个collection的数据是连续存储的

    update-in-place直接修改,而非使用MVCC的机制

    使用C++编写

    10.适用场景

    如果你在构建一个 Lotus Notes型的应用,我们推荐使用CouchDB,主要是由于它的MVCC机制。另外如果我们需要master-master的架构,需要基于地理位置的数据分布,或者在数据结点可能不在线的情况下,我们推荐使用CouchDB。

    如果你需要高性能的存储服务,那我们推荐MongoDB,比如用于存储大型网站的用户个人信息,比如用于构建在其它存储层之上的Cache层。

    如果你的需求中有大量update操作,那么使用MongoDB吧。就像我们在例子updating real time analytics counters中的一样,对于那种经常变化的数据,比如浏览量,访问数之类的数据存储。

         Mongodb GridFS 介绍

    MongoDB GridFS 是MongoDB用于文件存储的模块,本文简单介绍了期用法。

    mongodb GridFS 性能

    性能, 网评还不错.

    不过在生产环境中,国外有用于存储视频流的.

    GridFS的一个优点是可以存储上百万的文件而无需担心扩容性.

    通过同步复制,可以解决分布式文件的备份问题.

    通过ARP-ping可以实现一个双机热备切换,类mysql的mysql master master replic

    使用Nginx module

    http://github.com/mdirolf/nginx-gridfs

    这是gridfs的nginx module. 可以通过nginx直接访问读取mongo gridfs中的文件.

    和nginx对应的mogilefs module类似.

    优点: 由于直接通过nginx,速度是最快的.

    缺点: 只能通过file_path来查找,目前不支持_id来查找.因此必须在file_path上

    建立索引.

    其他一些信息:

    1.通过runcommand可以直接在mongodb端运行处理脚本. 比如像mapreduce,或者一

    些需要读取数据然后进行处理的.

    这些command则是使用javascript方式来编写的,很容易. 好处就是避免了数据在服

    务端和客户端之间的读取和传输,

    提高效率.

    2. sharding

    sharding在目前开发版中已经具备,但还不成熟. 但是可以自己实现sharding比较

    好.因为目前的sharding还是比较硬性的.

    3.灵活使用magic操作符和upsert,比如$inc,$all,$in 等等

         MongoDB:下一代MySQL?

    MongoDB的特性
    简单的查询语句,没有Join操作
    文档型存储,其数据是用二进制的Json格式Bson存储的。其数据就像Ruby的hashes,或者Python的字典,或者PHP的数组
    Sharding,MongoDB提供auto-sharding实现数据的扩展性
    GridFS,MongoDB的提供的文件存储API
    数组索引,你可以对文档中的某个数组属性建立索引
    MapReduce,可以用于进行复杂的统计和并行计算
    高性能,通过使用mmap和定时fsync的方法,避免了频繁IO,使其性能更高
    MongoDB的优点
    高性能,速度非常快(如果你的内存足够的话)
    没有固定的表结构,不用为了修改表结构而进行数据迁移
    查询语言简单,容易上手
    使用Sharding实现水平扩展
    部署方便
    使用MongoDB,你得记住以下几点:
    MongoDB 假设你有大磁盘空间
    MongoDB 假设你的内存也足够大于放下你的热数据
    MongoDB 假设你是部署在64位系统上的(32位有2G的限制,试用还可以)
    MongoDB 假设你的系统是little-endian的
    MongoDB 假设你有多台机器(并不专注于单机可靠性)
    MongoDB 假设你希望用安全换性能,同时允许你用性能换安全
    MongoDB在下面领域不太擅长
    不太稳定,特别是auto-sharding目前还有很多问题
    不支持SQL,这意味着你很多通过SQL接口的工具不再适用
    持久化,MongoDB单机可靠性不太好,宕机可能丢失一段时间的数据
    相关文档比较少,新功能都有这个问题
    相关人才比较难找,这也是新功能的问题之一

         MongoDB安全性初探

    本文是一篇转载文章,文章主要介绍了MongoDB 安全性方面的知识,包括 MongoDB 安全配制、认证机制及认证的网络流程,也简单介绍了可能利用JavaScript引擎执行脚本攻击的可能。

    MongoDB,这么火的玩意其实早就想好好研究一下了。之前一直没空仔细学学新的东西,总是感觉精力不足。这次趁着买了一本书,就零零散散地在VPS上搭建、测试、看实现代码。感觉也蛮有意思的一个数据库。虽然感觉它非常简单,尤其是看代码的时候更是感觉如此。但这不也是另一个KISS的典范么,还是简单但是实用的东西最能流行。

    既然都看了其实现,也不能不产出点什么。正好多年没更新博文,就简单分析一下 MongoDB 的安全性,凑个数先。

    默认配置的安全情况
    在默认情况下,mongod是监听在0.0.0.0之上的。而任何客户端都可以直接连接27017,且没有认证。好处是,开发人员或dba可以即时上手,不用担心被一堆配置弄的心烦意乱。坏处是,显而易见,如果你直接在公网服务器上如此搭建MongoDB,那么所有人都可以直接访问并修改你的数据库数据了。

    默认情况下,mongod也是没有管理员账户的。因此除非你在admin数据库中使用db.addUser()命令添加了管理员帐号,且使用–auth参数启动mongod,否则在数据库中任何人都可以无需认证执行所有命令。包括delete和shutdown。

    此外,mongod还会默认监听28017端口,同样是绑定所有ip。这是一个mongod自带的web监控界面。从中可以获取到数据库当前连接、log、状态、运行系统等信息。如果你开启了–rest参数,甚至可以直接通过web界面查询数据,执行mongod命令。

    我试着花了一个晚上扫描了国内一个B段,国外一个B段。结果是国外开了78个MongoDB,而国内有60台。其中我随意挑选了10台尝试连接,而只有一台机器加了管理员账户做了认证,其他则全都是不设防的城市。可见其问题还是比较严重的。

    其实MongoDB本身有非常详细的安全配置准则,显然他也是想到了,然而他是将安全的任务推给用户去解决,这本身的策略就是偏向易用性的,对于安全性,则得靠边站了。

    用户信息保存及认证过程
    类似MySQL将系统用户信息保存在mysql.user表。MongoDB也将系统用户的username、pwd保存在admin.system.users集合中。其中pwd =md5(username + “:mongo:” + real_password)。这本身并没有什么问题。username和:mongo:相当于对原密码加了一个salt值,即使攻击者获取了数据库中保存的md5 hash,也没法简单的从彩虹表中查出原始密码。

    我们再来看看MongoDB对客户端的认证交互是如何实现的。mongo client和server交互都是基于明文的,因此很容易被网络嗅探等方式抓取。这里我们使用数据库自带的mongosniff,可以直接dump出客户端和服务端的所有交互数据包:

    [root@localhost bin]# ./mongosniff --source NET lo
    sniffing 27017

    ...//省略开头的数据包,直接看看认证流程。以下就是当用户输入db.auth(username, real_passwd)后发生的交互。

    127.0.0.1:34142 -->> 127.0.0.1:27017 admin. 62 bytes id:8 8
    query: { getnonce: 1.0 } ntoreturn: -1 ntoskip: 0
    127.0.0.1:27017 <<-- 127.0.0.1:34142 81 bytes id:7 7 - 8
    reply n:1 cursorId: 0
    { nonce: "df97182fb47bd6d0", ok: 1.0 }
    127.0.0.1:34142 -->> 127.0.0.1:27017 admin. 152 bytes id:9 9
    query: { authenticate: 1.0, user: "admin", nonce: "df97182fb47bd6d0", key: "3d839522b547931057284b6e1cd3a567" } ntoreturn: -1 ntoskip: 0
    127.0.0.1:27017 <<-- 127.0.0.1:34142 53 bytes id:8 8 - 9
    reply n:1 cursorId: 0
    { ok: 1.0 }
    第一步,client向server发送一个命令getnonce,向server申请一个随机值nonce,server返回一个16位的nonce。这里每次返回的值都不相同。
    第二步,client将用户输入的明文密码通过算法生成一个key,即 key = md5(nonce + username + md5(username + “:mongo:” + real_passwd)),并将之连同用户名、nonce一起返回给server,server收到数据,首先比对nonce是否为上次生成的nonce,然后比对 key == md5(nonce + username + pwd)。如果相同,则验证通过。
    由于至始至终没有密码hash在网络上传输,而是使用了类似挑战的机制,且每一次nonce的值都不同,因此即使攻击者截取到key的值,也没用办法通过重放攻击通过认证。

    然而当攻击者获取了数据库中保存的pwd hash,则认证机制就不会起到作用了。即使攻击者没有破解出pwd hash对应的密码原文。但是仍然可以通过发送md5(nonce + username + pwd)的方式直接通过server认证。这里实际上server是将用户的pwd hash当作了真正的密码去验证,并没有基于原文密码验证。在这点上和我之前分析的mysql的认证机制其实没什么本质区别。当然或许这个也不算是认证机制的弱点,但是毕竟要获取MongoDB的username和pwd的可能性会更大一些。

    然而在Web的监控界面的认证中则有一些不同。当client来源不是localhost,这里的用户认证过程是基于HTTP 401的。其过程与mongo认证大同小异。但是一个主要区别是:这里的nonce并没有随机化,而是每次都是默认为”abc”。

    利用这个特点,如果攻击者抓取了管理员一次成功的登录,那么他就可以重放这个数据包,直接进入Web监控页面。

    同样,攻击者还可以通过此接口直接暴力破解 mongo 的用户名密码。实际上27017和28017都没有对密码猜解做限制,但Web由于无需每次获取nonce,因此将会更为简便。

    JavaScript的执行与保护
    MongoDB 本身最大的特点之一,就是他是使用 JavaScript 语言作为命令驱动的。黑客会比较关注这一点,因为其命令的支持程度,就是获取 MongoDB 权限之后是否能进一步渗透的关键。

    JavaScript 本身的标准库其实相当弱。无论是 spidermonkey 或者是 v8 引擎,其实都没有系统操作、文件操作相关的支持。对此,MongoDB做了一定的扩展。可以看到,ls/cat/cd/hostname 甚至 runProgram 都已经在 JavaScript 的上下文中有实现。看到这里是不是已经迫不及待了?mongoshell 中试一下输入ls(“./”),看看返回。

    等等?结果怎么这么熟悉?哈哈,没错,其实这些 api 都是在 client 的上下文中实现的。一个小小玩笑。

    那么在server端是否可以执行js呢?答案是肯定的。利用 db.eval(code) ——实际上底层执行的是db.$cmd.findOne({$eval: code}) —— 可以在server端执行我们的js代码。

    当然在server端也有js的上下文扩展。显然 mongod 考虑到了安全问题(也可能是其他原因),因此在这里并没有提供client中这么强大的功能。当然 MongoDB 还在不断更新,长期关注这个list,说不定以后就有类似 load_file/exec 之类的实现。

    一劳永逸解决服务端js执行带来的问题可以使用noscripting参数。直接禁止server-side的js代码执行功能。

         白话MongoDB(一)

    按照官方的说法,MongoDB是一种可扩展的高性能的开源的面向文档(document-oriented )的数据库,采用C++开发。注意mongo不是mango(芒果),这个词是从humongous中截取出来的,其野心不言而明,直指海量数据存储。和其他很多NoSQL不太一样,MongoDB背后有一个专门的商业公司在提供支持和推广,有点类似MySQL AB的模式。这一系列文章,是为入门者写的,已经对NoSQL和MongoDB有一定研究和经验的,可以略过,或者看看如有疏漏,请留言指出。

    面向文档,那么什么是文档呢?很明显这不是我们常见的word文档。这里说的文档,是一种可以嵌套的数据集合。从关系数据库的范式的概念来说,嵌套是明显的反范式设计。范式设计的好处是消除了依赖,但是增加了关联,查询需要通过关联两张或者多张表来获得所需要的全部数据,但是更改操作是原子的,只需要修改一个地方即可。反范式则是增加了数据冗余来提升查询性能,但更新操作可能需要更新冗余的多处数据,需要注意一致性的问题。

    一个典型的例子,如blog,关系数据库中一般可以把文章设计为一张表,评论设计为一张表,那么在页面需要展示一篇文章和其对应的评论的时候,就需要关联查询文章表和评论表。但是面向文档的设计,可以将评论作为文章的一个嵌套文档存放在一起,这不但省去了关联查询,由于存储在一起,查询的性能也可以做到更好。

    MongoDB的面向文档采用的是BSON,一种类似JSON的格式,但是是二进制序列化的。如上面提到的blog的文章和评论,可以做如下设计:

    { 'id':1, 'author':'NinGoo', 'title':'白话MongoDB(一)', 'content':'按照官方的说法,此处省略一万字',

    comment:[ {'comment-author':'宋兵甲', 'comment-content':'有木有' } ,

    {'comment-author':'尼玛','comment-content':'伤不起啊' }]}

    1. 相关数据存放在一起,针对性的查询可以消除join,性能比分散存储要高且方便。
    2. 整个结构清晰自解析。所有字段名和值都存储,所以不需要提前设计结构,key的名字和数目可以任意指定,也就是所谓的schema-free。
    3. 由于字段名在每一行每一列都需要重复存在,会带来一些额外的存储消耗,这在海量数据及字段较多的时候也需要考虑。
    4. 一个document的长度有限,1.7.2之前是4MB,目前是8MB,以后可能增长到32MB。如果有更大的数据,可以使用MongoDB底层的GridFS直接作为文件存储。
    5. 如果需要查找某个评论者的所有评论,则相对困难。当然,MongoDB支持任意key的索引,这也不是什么大问题。

    像上面的一个结构,为一个文档(document),相当于关系数据库中的一行记录,多个文档组成一个集合(collection),相当于关系数据库的表。多个集合(collection),逻辑上组织在一起,就是数据库(database),一个MongoDB实例支持多个数据库(database)。

    大部分的NoSQL产品,为追求性能,一致性等,一般只能支持简单的基于row-key的单条或者范围查询,但是MongoDB可以针对任意列的key创建索引,甚至是内嵌文档里的key,从支持的查询的灵活性上来看,更接近传统的关系数据库,同时还能在性能上向NoSQL看齐,加上支持复制,自动分片和Map/Reduce等功能,非常的吸引眼球,正在成为一款热门的海量存储产品。其背后的商业支持公司10gen,也正在不遗余力的推广,前不久还在北京专门组织了一场技术交流会。在其首页列举的典型客户里,包括foursquare,sourceforge,github等知名互联网公司和应用,当然,也包括淘宝网。

         MongoDB调查总结

    与关系型数据库相比,MongoDB的优点:
    ①弱一致性(最终一致),更能保证用户的访问速度:
    举例来说,在传统的关系型数据库中,一个COUNT类型的操作会锁定数据集,这样可以保证得到“当前”情况下的精确值。这在某些情况下,例如通过ATM查看账户信息的时候很重要,但对于Wordnik来说,数据是不断更新和增长的,这种“精确”的保证几乎没有任何意义,反而会产生很大的延迟。他们需要的是一个“大约”的数字以及更快的处理速度。

    但某些情况下MongoDB会锁住数据库。如果此时正有数百个请求,则它们会堆积起来,造成许多问题。我们使用了下面的优化方式来避免锁定:
    每次更新前,我们会先查询记录。查询操作会将对象放入内存,于是更新则会尽可能的迅速。在主/从部署方案中,从节点可以使用“-pretouch”参数运行,这也可以得到相同的效果。
    使用多个mongod进程。我们根据访问模式将数据库拆分成多个进程。
    ②文档结构的存储方式,能够更便捷的获取数据。
    对于一个层级式的数据结构来说,如果要将这样的数据使用扁平式的,表状的结构来保存数据,这无论是在查询还是获取数据时都十分困难。
    举例1:
    就拿一个“字典项”来说,虽然并不十分复杂,但还是会关系到“定义”、“词性”、“发音”或是“引用”等内容。大部分工程师会将这种模型使用关系型数据库中的主键和外键表现出来,但把它看作一个“文档”而不是“一系列有关系的表”岂不更好?使用“dictionary.definition.partOfSpeech='noun'”来查询也比表之间一系列复杂(往往代价也很高)的连接查询方便且快速。

    举例2:在一个关系型数据库中,一篇博客(包含文章内容、评论、评论的投票)会被打散在多张数据表中。在MongoDB中,能用一个文档来表示一篇博客,评论与投票作为文档数组,放在正文主文档中。这样数据更易于管理,消除了传统关系型数据库中影响性能和水平扩展性的“JOIN”操作。

    CODE↓
    > db.blogposts.save({ title : "My First Post", author: {name :"Jane", id :1},
    comments : [{ by: "Abe", text: "First" },
    { by : "Ada", text : "Good post" }]
    })

    >db.blogposts.find( { "author.name" : "Jane" } )

    >db.blogposts.findOne({ title : "My First Post","author.name": "Jane",
    comments : [{ by: "Abe", text: "First" },
    { by : "Ada", text : "Good post" } ]
    })
    > db.blogposts.find( { "comments.by" : "Ada" } )

    >db.blogposts.ensureIndex( { "comments.by" : 1 } );
    举例③:
    MongoDB是一个面向文档的数据库,目前由10gen开发并维护,它的功能丰富,齐全,完全可以替代MySQL。在使用MongoDB做产品原型的过程中,我们总结了MonogDB的一些亮点:
      使用JSON风格语法,易于掌握和理解:MongoDB使用JSON的变种BSON作为内部存储的格式和语法。针对MongoDB的操作都使用JSON风格语法,客户端提交或接收的数据都使用JSON形式来展现。相对于SQL来说,更加直观,容易理解和掌握。
      Schema-less,支持嵌入子文档:MongoDB是一个Schema-free的文档数据库。一个数据库可以有多个Collection,每个Collection是Documents的集合。Collection和Document和传统数据库的Table和Row并不对等。无需事先定义Collection,随时可以创建。
      Collection中可以包含具有不同schema的文档记录。 这意味着,你上一条记录中的文档有3个属性,而下一条记录的文档可以有10个属性,属性的类型既可以是基本的数据类型(如数字、字符串、日期等),也可以是数组或者散列,甚至还可以是一个子文档(embeddocument)。这样,可以实现逆规范化(denormalizing)的数据模型,提高查询的速度。

    ③内置GridFS,支持大容量的存储。
    GridFS是一个出色的分布式文件系统,可以支持海量的数据存储。
    内置了GridFS了MongoDB,能够满足对大数据集的快速范围查询。
    ④内置Sharding。
    提供基于Range的Auto Sharding机制:一个collection可按照记录的范围,分成若干个段,切分到不同的Shard上。
    Shards可以和复制结合,配合Replica sets能够实现Sharding+fail-over,不同的Shard之间可以负载均衡。查询是对客户端是透明的。客户端执行查询,统计,MapReduce等操作,这些会被MongoDB自动路由到后端的数据节点。这让我们关注于自己的业务,适当的时候可以无痛的升级。MongoDB的Sharding设计能力最大可支持约20 petabytes,足以支撑一般应用。
    这可以保证MongoDB运行在便宜的PC服务器集群上。PC集群扩充起来非常方便并且成本很低,避免了“sharding”操作的复杂性和成本。

    ⑤第三方支持丰富。(这是与其他的NoSQL相比,MongoDB也具有的优势)
    现在网络上的很多NoSQL开源数据库完全属于社区型的,没有官方支持,给使用者带来了很大的风险。
    而开源文档数据库MongoDB背后有商业公司10gen为其提供供商业培训和支持。
    而且MongoDB社区非常活跃,很多开发框架都迅速提供了对MongDB的支持。不少知名大公司和网站也在生产环境中使用MongoDB,越来越多的创新型企业转而使用MongoDB作为和Django,RoR来搭配的技术方案。
    ⑥性能优越:
    在使用场合下,千万级别的文档对象,近10G的数据,对有索引的ID的查询不会比mysql慢,而对非索引字段的查询,则是全面胜出。mysql实际无法胜任大数据量下任意字段的查询,而mongodb的查询性能实在让我惊讶。写入性能同样很令人满意,同样写入百万级别的数据,mongodb比我以前试用过的couchdb要快得多,基本10分钟以下可以解决。补上一句,观察过程中mongodb都远算不上是CPU杀手。

    与关系型数据库相比,MongoDB的缺点:
    ①mongodb不支持事务操作。
    所以事务要求严格的系统(如果银行系统)肯定不能用它。(这点和优点①是对应的)
    ②mongodb占用空间过大。
    关于其原因,在官方的FAQ中,提到有如下几个方面:
    1、空间的预分配:为避免形成过多的硬盘碎片,mongodb每次空间不足时都会申请生成一大块的硬盘空间,而且申请的量从64M、128M、256M那样的指数递增,直到2G为单个文件的最大体积。随着数据量的增加,你可以在其数据目录里看到这些整块生成容量不断递增的文件。

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

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

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

    ③MongoDB没有如MySQL那样成熟的维护工具,这对于开发和IT运营都是个值得注意的地方。

    ################################

    Wordnik的MongoDB使用经验
    http://news.cnblogs.com/n/80856/

    视觉中国的NoSQL之路:从MySQL到MongoDB
    http://news.cnblogs.com/n/77959/

         本文为转载别人的转载。原始种子出处不详。

  • 相关阅读:
    C++ template —— 模板中的名称(三)
    关于烂代码的那些事(下)
    关于烂代码的那些事(中)
    关于烂代码的那些事(上)
    比尔的村庄:创业是选择做赚钱的事,还是值钱的事?
    C++ template —— 深入模板基础(二)
    依赖倒置,控制反转,依赖注入
    JAVA中限制接口流量、并发的方法
    SVN同步时忽略特定文件或文件夹
    MySQL中查询表及索引大小的方法
  • 原文地址:https://www.cnblogs.com/mcmurphy/p/2870425.html
Copyright © 2011-2022 走看看