mongo 支持不断写入 不断读取吗

原文地址:等平台的驱动程序(

SQL or NoSQL?That’s a question!SQL 与 NoSQL 的争论从来没有停息过但其实任何一种技术都不会是适合一切应用场景的,重要的是你要充分了解自己的需求再充分了解你要選择的技术的优劣。

下面是一个关于 MongoDB 优缺点的列表希望对打算使用 MongoDB 的同学,能有一些作用:

快速!(当然这和具体的应用方式有关,通常来说它比一般的关系型数据库快5位左右。)

很高的可扩展性 – 轻轻松松就可实现PB级的存储(但是可能我们并不需要PB级的存储10TB可能僦够了)

他的存储格式是Json的,这对Java来说非常好处理对javascirpt亦然。

运维起来非常方便你不用专门为它安排一个管理员。

它有一个非常活跃的社区(我提出的一个bug在20分钟内就能得到修复多谢Elliot)

MongoDB 背后的公司(10gen)已经准备好了明天在 MongoDB 上面的投入的资金了。

应用经验缺乏我们都没囿相关NoSQL 产品的使用经验。

项目相对来说还比较新

和以往的存储相比,数据的关系性操作不再存在

本文详细讲下Memcached和Mongodb一些看法,以及结合應用有什么好处希望看到大家的意见和补充。

  Memcached的优势我觉得总结下来主要体现在:

  1) 分布式可以由10台拥有4G内存的机器,构成┅个40G的内存池如果觉得还不够大可以增加机器,这样一个大的内存池完全可以把大部分热点业务数据保存进去,由内存来阻挡大部分對数据库读的请求对数据库释放可观的压力。

  2) 单点如果Web服务器或App服务器做负载均衡的话,在各自内存中保存的缓存可能各不相哃如果数据需要同步的话,比较麻烦(各自自己过期还是分发数据同步?)即使数据并不需要同步,用户也可能因为数据的不一致洏产生用户体验上的不友好

  3) 性能强。不用怀疑和数据库相比确实是根源上还是内存的读写和磁盘读写效率上几个数量级的差距。有的时候我们在抱怨数据库读写太差的情况下可以看看磁盘的IO如果确实是瓶颈的话装啥强劲的数据库估计也档不了,强不强无非是这個数据库多少充分的利用了内存

  但是也不太建议在任何情况下使用Memcached替代任何缓存:

  1) 如果Value特别大,不太适合因为在默认编译丅Memcached只支持1M的Value(Key的限制到不是最大的问题)。其实从实践的角度来说也 不建议把非常大的数据保存在Memcached中因为有序列化反序列化的过程,别尛看它消耗的CPU说到这个就要提一下,我一直觉得 Memcached适合面向输出的内容缓存而不是面向处理的数据缓存,也就是不太适合把大块数据放進去拿出来处理之后再放进去而是适合拿出来就直接给输出了,或是拿出来不需要处理直接用

  2) 如果不允许过期,不太适合Memcached在默认情况下最大30天过期,而且在内存达到使用限制后它也会回收最少使用的数据因此,如果我们要把它当 作static变量的话就要考虑到这个问題必须有重新初始化数据的过程。其实应该这么想既然是缓存就是拿到了存起来,如果没有必定有一个重新获取重新缓存的过程而鈈是想着它永远存在。

  在使用Memcached的过程中当然也会有一些问题或者说最佳实践:

  1) 清除部分数据的问题Memcached只是一个Key/Value的池,一个公共汽车谁都可以上我觉得对于类似的公共资源,如果用的人都按照自己的规 则来的话很容易出现问题因此,最好在Key值的规范上上使用类姒命名空间的概念 每一个用户都能很明确的知道某一块功能的Key的范围,或者说前缀带来的好处是我们如果需要清空的话可以根据这个規范找到我们自己的一批Key然后再去 清空,而不是清空所有的当然有人是采用版本升级的概念,老的Key就让它过去吧到时候自然会清空,這也是一种办法不过Key有规范总是有好处的,在 统计上也方便一点

  2) Value的组织问题。也就是说我们存的数据的粒度比如要保存一个列表,是一个保存在一个键值还是统一保存为一个键值这取决于业务。如果粒度很小的话最好是在获取的时候能批量获取在保存的时候也能批量保存。对于跨网络的调用次数越少越好可以想一下,如果一个页面需要输出100行数据每一个数据都需要获取一次,一个页面進行上百次连接这个性能会不会成问题

  那么Memcached主要用在哪些功能上呢?

  其实我觉得平时能想到在内存中做缓存的地方我们都可以栲虑下是不是可以去适用分布式缓存但是主要的用途还是用来在前端或中部挡一下读的需求来释放Web服务器App服务器以及DB的压力。

  Mongodb是一款比较优良的非关系型数据库的文档型的数据库它的优势主要体现在:

  1) 开源。意味着即使我们不去改也可以充分挖掘它MS SQL除了看那些文档,谁又知道它内部如何实现

  2) 免费。意味着我们可以在大量垃圾服务器上装大量的实例即使它性能不怎么高,也架不住非常多的点啊

  3) 性能高。其它没比较过和MS SQL相比,同样的应用(主要是写操作)一个撑500用户就挂了一个可以撑到2000。在数据量上到百万之后即使没索引,MS SQL的插入性能下降的也一塌糊涂其实任何事物都有相对性的,在变得复杂变得完善了之后会牺牲一部分的性能MS SQL體现的是非常强的安全性数据完整性,这点是Mongodb办不到的

  4) 配置简单并且灵活。在生产环境中对数据库配置故障转移群集和读写分离嘚数据库复制是很常见的需求MS SQL的配置繁琐的步骤还是很恐怖的,而Mongodb可以在五分钟之内配置自己所需要的故障转移组读写分离更是只需偠一分钟。灵活性体现在我们可以配置一个M一个S,两个M一个S(两个M写入的数据会合并到S上供读取)一个M两个S(一个M写入的数据在两个S仩有镜像),甚至是多个M多个S(理论上可以创建10个M10个S,我们只需要通过轮询方式随便往哪个M上写需要读的时候也可以轮训任意一个S,當然我们要知道不可能保证在同一时间所有的 S都有一致的数据)那么也可以配置两个M的对作为一套故障转移群集,然后这样的群集配置兩套再对应两个S,也就是4个M对应2个S保证M点具有故障 转移。

  5) 使用灵活在之前的文章中我提到甚至可以通过SQL到JS表达式的转换让Mongodb支歭SQL语句的查询,不管怎么说Mongodb在查询上还是很方便的

  之前也说过了,并不是所有数据库应用都使用采用Mongodb来替代的它的主要缺点是:

  1) 开源软件的特点:更新快,应用工具不完善由于更新快,我们的客户端需要随着它的更新来升级才能享受到一些新功能更新快吔意味着很可能在某一阶段会缺乏某个重要功能。另外我们知道MS SQL在DEV/DBA/ADM多个维度都提供了非常好的GUI工具对数据库进行维护而Mongodb虽然提供了一些程序,但是并不是非常友好我们的 DBA可能会很郁闷,去优化Mongodb的查询

  2) 操作事务。Mongodb不支持内建的事务(没有内建事务不意味着完全不能有事务的功能)对于某些应用也就不适合。不过对于大部分的互联网应用来说并不存在这个问题

  在使用Mongodb的过程中主要遇到下面嘚问题:

  1) 真正的横向扩展?在使用Memcached的过程中我们已经体会到这种爽了基本可以无限的增加机器来横向扩展,因为什么因为我们昰通过客户端来决定键值保存在那个实例上,在获取的时候也很明确它在哪个实例上即使是一次性获取多个键值,也是同样而对于数據库来说,我们通过各种各样的方式进行了 Sharding不说其它的,在查询的时候我们根据一定的条件获取批量的数据怎么样去处理?比如我们按照用户ID去分片而查询根本不在乎用户ID, 在乎的是用户的年龄和教育程度最后按照姓名排序,到哪里去取这些数据不管是基于客户端还是基于服务端的Sharding都是非常难做的,并且即使有了 自动化的Sharding性能不一定能有保障最简单的是尽量按照功能来分,再下去就是历史数据嘚概念真正要做到实时数据分散在各个节点,还是很困难

  2) 多线程,多进程在写入速度达不到预期的情况下我们多开几个线程哃时写,或者多开几个Mongodb进程(同一机器)也就是多个数据库实例,然后向不同 的实例去写这样是否能提高性能?很遗憾非常有限,甚至可以说根本不能提高为什么使用Memcached的时候多开线程可以提高写入速度?那是因为内 存数据交换的瓶颈我们没达到而对于磁盘来说,IO嘚瓶颈每秒那么几十兆的是很容易达到的一旦达到这个瓶颈了,无论是开多少个进程都无法提高性能了还 好Mongodb使用内存映射,看到内存使用的多了其实我对它的信心又多了一点(内存占用多了我觉得CPU更容易让它不闲着),怕就怕某个DB不使用什 么内存看着IO瓶颈到了,内存和CPU还是吃不饱

  其实有了Memcached和Mongodb我们甚至可以让80%以上的应用摆脱传统关系型数据库。我能想到它们其实可以互相配合弥补对方的不足:

  Memcached适合根据Key保存Value那么有的时候我们并不知道需要读取哪些Key怎么办呢?我在想是不是可以把Mongodb或 说数据库当作一个原始数据这份原始数據中分为需要查询的字段(索引字段)和普通的数据字段两部分,把大量的非查询字段保存在Memcached中小粒 度保存,在查询的时候我们查询数據库知道要获取哪些数据一般查询页面也就显示20-100条吧,然后一次性从Memcached中获取这些数据也就是 说,Mongodb的读的压力主要是索引字段而数据芓段只是在缓存失效的时候才有用,使用Memcached挡住大部分实质数据的查询反过来说,如果我们要清空Memcached中的数据也知道要清空哪些Key

NoSQL 数据库在仩年炒得很热,于是我也萌生了使用 NoSQL 数据库写一个应用的想法首先来认识一下 NoSQL。NoSQL 是一个缩写含义从最初的 No-SQL 到现在已经成为了 Not-Only-SQL。确实后媔一种解释比较符合 NoSQL 的使用场景

现在网络上被人所知的 NoSQL 数据库可以在这个网页()看到。这个列表林林总总一大堆要选择哪个数据库叺手呢?

在我关注的 Web 领域特别是 Ruby on Rails 社区,比较多提到的是这几个数据库:

另一个apache基金会下的非关系数据库。

特点是运行在内存中,速喥很快相比于用来持久化数据,也许更接近于 memcached 这样的缓存系统或者用来实现任务队列。(比如)

在这些候选名单中我选择了MongoDB因为它朂近在 RoR 社区中的露脸率比较高,网页文档完善并且项目主页的设计也不错

在陈述 MongoDB 的特性之前,还是给第一次接触 NoSQL 的人提个醒:不要意图鼡 NoSQL 全盘取代 SQL 数据库非关系数据库的出现不是为了取代关系数据库。具体的说MongoDB 并不支持复杂的事务,只支持少量的原子操作所以不适鼡于“转帐”等对事务和一致性要求很高的场合。而 MongoDB 适合什么场合请继续阅读。

关系数据库比如 MySQL通常将不同的数据划分为一个个“表”,表的数据是按照“行”来储存的而关系数据库的“关系”是指通过“外键”将表间或者表内的数据关联起来。比如文章-评论 的一对哆关系可以用这样的表来实现:

实现关联的关键就是 comments 表的最后一个 post_id 字段将 comment 数据的 post_id 字段设为评论目标文章的 id 值,就可以用 SQL 语句进行相关查詢(假设要查的文章 id 是 1):
相对于关系数据库的行式储存和查询MongoDB 作为一个文档型数据库,可以支持更具层次感的数据上面举的 文章-评論 结构,在 MongoDB 里面可以这样设计

可以看到,文档性数据库从储存的数据项上就跟 SQL 数据库不同在 MongoDB 中,文档是以  格式(类似 JSON)储存的可以支持丰富的层次的结构。由于数据结构的表达能力更强用 MongoDB 储存文档型数据可以比 SQL 数据库更直观和高效。

在 SQL 数据库中为表达数据的从属關系,通常要将表间关系分为 one-to-oneone-to-many,many-to-many 等模式进行设计这通常会需要很多链接表的辅助。在MongoDB 中如果关联文档体积较小,固定不变并且与叧一文档是主从关系,那么通常可以嵌入(Embed)主文档

常见情景:评论、投票点击数据、Tag。

这类场景的有时单个数据项体积很小但是数量巨大,与之相应的是查询成本也会上升如果将这些小数据嵌入所属文档,在查询主文档时一并提取查询效率要比 SQL 高,后者通常需要開支较大的 JOIN 查询并且根据文档介绍,每个文档包括 Embed 部分在物理硬盘上都是储存在同一区域的IO 部分也会比 SQL 数据库快。(注MongoDB 有单文档大尛限制)

MongoDB 中的文档其实是没有模式的,不像 SQL 数据库那样在使用前强制定义一个表的每个字段这样可以避免对空字段的无谓开销。

例如两個用户的联系信息A 用户带有email 不带 url,B 用户带有 url 不带 email在 SQL 数据库中需要为两个数据项都提供 email 段和 url 段,而在MongoDB 中可以这样保存:

在关系数据库中如果这些不确定的字段很多而且数量很大,为了优化考虑可能又要划分成两个表了比如users 和 profiles 两个表。在 MongoDB 中如果这一类不确定信息确实昰属于同一文档的,那么可以轻松的放在一起因为并不需要预先定义模式,也不会有空字段的开销

不过因为要支持这样的动态性,并苴为了性能考虑进行预先分配硬盘空间数据外的开销也会带来磁盘占用。我还未实测实际中开销有多大也许未来不久我会写一个应用測试。

推出的各种新事物但这似乎还不够,“社区”(包含所有开发人员无论他们是否每天都使用.NET)也开始行动,创造出更多的新事粅来填补Microsoft 未覆盖到的空白对您而言这可能是制造混乱和干扰。

在 Microsoft 的支持 范围之外该社区所酝酿出的“新”事物之一就是 NoSQL 运动,一组开發人员公开质疑将所有数据存储于某种形式的关系数据库系统的这种观念表、行、列、主键、外键约束、关于null 的争论以及有关主键是否應该为自然键或非自然键的辩论……还有什么是神圣不可侵犯的?

在本文及其后续文章中我将探讨NoSQL 运动所倡导的主要工具之一:MongoDB,根据 MongoDB 網站的陈述该工具的名称源自于“humongous”(并不是我杜撰的)。我基本上会讨论到与 MongoDB 相关的方方面面:安装、浏览以及在.NET Framework 中使用 MongoDB其中包括其提供的 LINQ 支持;在其他环境(桌面应用程序和Web 应用程序及服务)中使用MongoDB;以及如何设置MongoDB,以免 Windows 生产管理员向您提出严重抗议

问题(或者,为何我要再次关注)

在深入了解MongoDB 之前,读者自然要问为什么.NET Framework 开发人员应该牺牲接下来宝贵的大约半小时时间继续待在电脑前阅读本文毕竟,SQLServer 有免费、可再发行的Express Edition提供比企业或数据中心绑定的传统关系数据库更精简的数据存储方案,而且毫无疑问还可以使用大量工具和库来轻松访问SQL Server 数据库,其中包括Microsoft 自己的 LINQ 和实体框架

但问题在于,关系模型(指关系模型本身)的优点也是其最大的缺点大多数开發人员(无论是.NET、Java 还是其他开发人员都在此列)在经历短短几年的开发工作之后,就会一一痛诉这种表/行/列的“方正”模型如何不能令其滿意尝试对分层数据进行建模的举动甚至能让最有经验的开发人员完全精神崩溃,类似情况不甚枚举因此Joe Celko 还写过一本书《SQLfor Smarties, Third Edition》(Morgan-Kaufmann,2005)其中完全是关于在关系模型中对分层数据建模的概念。如果在此基础之上再增加一个基本前提:关系数据库认为数据的结构(数据库架构)不灵活则尝试支持数据的临时“添加”功能将变得十分困难。(快速回答下面的问题:你们之中有多少人处理过包含一个Notes 列(乃至 Note1、Note2、Note3……)的数据库)

NoSQL 运动中没有任何人会说关系模型没有优点,也没有人会说关系数据库将会消失但过去二十年开发人员生涯的一个朂基本的事实是,开发人员经常将数据存储到本质上并非关系模型(有时甚至与这种模型相去甚远)的关系数据库中

面向文档的数据库便是用于存储“文档”(这是一些紧密结合的数据集合,通常并未关联到系统中的其他数据元素)而非“关系”。例如博客系统中的博客条目彼此毫无关联,即使出现某一篇博客确实引用到另一篇博客的情况最常用的关联方法也是通过超链接(旨在由用户浏览器解除引用),而非内部关联对本博客条目的评论完全局限于本博客条目的内部范围,不管评论的是什么博客条目极少有用户想查看包含所囿评论的内容集合。

此外面向文档的数据库往往在高性能或高并发性环境中表现突出:MongoDB专门迎合高性能需求,而它的近亲CouchDB 则更多的是针對高并发性的情况两者都放弃了对多对象事务的支持,也就是说尽管它们支持在数据库中对单个对象进行的并发修改,但若尝试一次性对多个对象进行修改将会在一小段时间内看到这些修改正依序进行。文档以“原子方式”更新但不存在涉及多文档更新的事务概念。这并不意味着MongoDB 没有任何稳定性只是说MongoDB 实例与 SQL Server 实例一样不能经受电源故障。需要原子性、一致性、隔离性和持久性(ACID) 完整要素的系统更适匼采用传统的关系数据库系统因此关键任务数据很可能不会太快出现在MongoDB 实例内,但Web 服务器上的复制数据或缓存数据可能要除外

一般来說,若应用程序及组件需要存储可快速访问且常用的数据则采用MongoDB 可以取得较好效果。网站分析、用户首选项和设置(以及包含非完全结構化数据或需采用结构灵活的数据的任何系统类型)都是采用MongoDB 的自然之选这并不意味着MongoDB 不能作为操作型数据的主要数据存储库;只是说MongoDB 能在传统 RDBMS 所不擅长的领域内如鱼得水,另外它也能在大量其他适合的领域内大展拳脚

前面提到过,MongoDB是一款开源软件包可通过 MongoDB 网站  轻松丅载。在浏览器中打开该网站应该就能找到Windows 可下载二进制包的链接请在页面右侧查找“Downloads”链接。另外如果更愿意使用直接链接,请访問 截至本文撰写之时,其稳定版本为发行版 Framework 驱动程序此类驱动程序知道如何通过打开的套接字进行连接以向服务器输送命令和数据。MongoDB 程序包中并未绑定 .NET Framework 驱动程序但有幸的是,社区提供了一个此处的“社区”指的是名叫 Sam Corder 的开发人员,他构建了一个 .NET Framework 驱动程序以及 LINQ 支持来訪问 MongoDB他的作品同时以源代码形式和二进制形式提供,位于可以从该页面下载二进制文件(查找页面右上角),也可以下载源代码然後自行编译。无论采取哪种方式都会产生两个程序集: Framework 了。

从根本上来说打开与正在运行的MongoDB 服务器的连接,同打开与任何其他数据库嘚连接没有太大差别如图 4 所示。

using Framework 开发人员使用过的方法有所不同而已(请参阅图 5
using Framework 值类型,如DateTime如前所述,从技术角度上讲MongoDB用于存儲 BSON 数据,其中包括传统 JSON 类型(字符串、整数、布尔值、双精度和null不过 null
 仅允许用于对象,不允许用于集合)的某些扩展例如上文提到的ObjectId、二进制数据、正则表达式以及JavaScript
 代码。我们暂时先不管后面两种类型BSON能存储二进制数据的这种说法是指能存储任何可简化为字节数组的內容,这实际上表示MongoDB 能存储任何内容但可能无法在该二进制BLOB 中进行查询。
 
 


Ted Neward 是 Neward & Associates 的负责人这是一家专门研究 .NET Framework 企业系统和 Java 平台系统的独立公司。他曾写作 100 多篇文章是 C# 领域最优秀的专家之一并且是 INETA 发言人,著作或合著过十几本书包括即将出版的《Professional F# 与他联系,或通过 访问其博愙
在,主要介绍了 MongoDB 的基本知识:安装、运行以及插入和查找数据。不过这篇文章只介绍了基本知识,所用的数据对象是简单的名称/徝对这是有道理的,因为 MongoDB 的最大优势就包括可使用相对简单的非结构化数据结构可以肯定地说,这种数据库能存储的不只是简单的名稱/值对
在本文中,我们将通过一种略微不同的方法来研究MongoDB(或任何技术)这个称为探索测试的过程可帮助我们发现服务器中可能存在嘚错误,同时可以凸显面向对象开发人员在使用MongoDB 时会遇到的常见问题之一
 
首先,我们要确保讨论同样的问题还要涉及一些略微不同的噺领域。让我们以一种与前一文章()相比更加结构化的方式来探讨MongoDB我们不只是创建简单的应用程序,然后进行调试我们将采取一举两得嘚做法,创建探索测试探索测试的代码段看起来像单元测试,但它们探索功能而不是尝试验证功能
在研究一项新技术时,编写探索测試可实现几种不同的目的其一,它们有助于发现所研究的技术在本质上是不是可以测试的(假设如下:如果难于进行探索测试则难于進行单元测试,而这是一个很严重的问题)其二,在所研究的技术出现新的版本时它们可作为一种回归测试,因为它们可在旧功能不洅正常工作的情况下发出警告其三,测试应是相对小型精细的因此,在本质上探索测试通过基于以前用例创建新“what-if”用例,使得新技术的学习更为容易
不过,与单元测试不同探索测试不是随应用程序连续开发的,因此一旦考虑所学习的技术,请将这些测试放在┅旁但不要将它们丢弃,它们还可帮助分离应用程序代码中的错误与库或框架中的错误这些测试通过提供一种与应用程序无关的轻型環境来进行实验,从而完成这种分离不会产生应用程序开销。
明确了这一点后我们来创建Visual C# 测试项目MongoDB-Explore。将驱动程序提供了 DBRef后者可通过畧微更丰富的方式来引用/解除引用其他文档,但仍无法实现对象图友好的系统)因此,尽管肯定可以获得一个丰富的对象模型并将其存儲到MongoDB 数据库中仍不建议这样做。请坚持使用Word 或 Excel 这样的文档来存储紧密群集的数据组如果某些内容可视为大型文档或电子表格,则可能非常适合MongoDB 或其他某种面向文档的数据库
上一次,我使用探索测试继续对MongoDB 进行探讨我介绍了如何在测试期间启动和停止服务器,然后介紹了如何获取跨文档引用并探讨了导致如此麻烦举动的原因。现在我们需要探索更多中间的 MongoDB 功能:谓词查询、聚合函数以及 Framework 企业系统和 Java 岼台系统的独立公司他曾写作 100 多篇文章,是 C# 领域最优秀的专家之一并且是 INETA 发言人著作或合著过十几本书,包括即将出版的《Professional F# 与他联系或通过 访问其博客。
Dwight Merriman和他的团队包括ShopWiki的创始人Eliot Horowitz参加了在纽约10gen启动MongoDB的仪式。现在该公司除了担任该开源项目的主要运营者之外还提供支持、培训和咨询服务。10gen在旧金山举办了第二届开发者大会Merriman在上午的大会做了主题演讲,主要介绍了MongoDB的起源并解释了为何要建立这样嘚数据库。
“在2007年底当时的想法是构建一个用于开发、托管并具有自动缩放Web应用程序的在线服务”,谈到MongoDB诞生之目的时Merriman介绍道。“但昰不同于Google App Engine的是这项服务完全建立在一个开放源代码的软件平台之上。”因此在关注了Google Bigtable架构很长一段时间后,Merriman和他的团队注意到尚没囿一个开源的数据库平台适合这种服务,这兴许是个机会
“我们意识到很多现有的数据库并不真正具备‘’的特性。例如弹性、可扩展性以及易管理性这些特性能够为开发者和运营者带来便利,而MySQL还不完全具备这些特点
Merriman以及他的团队的目标是构建一个全新的数据库。噺的数据库将会放弃大家所熟悉的关系数据库模型且是适合现代网络应用并基于分布式的平台。高度事务性的系统可以帮助解决一些棘掱的问题同时还支持云计算架构的伸缩性。Merriman解释到经过一年的不断努力,这个数据库已经比较完善他们将它设计为具有为“云计算垺务”潜力的数据库。而且还会不断的完善因为MongoDB本身就是一个开源数据库。
在开源的、面向文档的数据库中MongoDB经常被誉为具有RDBMS功能的NoSQL数據库。MongoDB还带有交互式shell这使得访问其数据存储变得简单,且其对于分块的即装即用的支持能够使高可伸缩性跨多个节点
据悉,MongoDB的API是JSON对象囷JavaScript函数的本地混合物通过shell程序开发人员可与MongoDB进行交互,即允许命令行参数或通过使用语言驱动程序来访问数据存储实例。这里不存在類JDBC驱动程序这意味着开发人员不必处理ResultSet或PreparedStatement。
而速度是 MongoDB 的另外一个优势主要是由于它处理写入的方式:它们存储在内存中,然后通过后囼线程写入磁盘
“由于用户不容易在大规模环境下作分布式的链接,并且在分布式环境下很难做快速的大规模部署因此,用户需要一些辅助的东西”Memmiman解释道。
最后他表示同样重要的是为了限制数据库的事务语义你可以使用分布式事务但当你在1000台机器上运行时它不会那么快。例如银行或会计系统传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。(李智/译)
本文见于MongoDB官方网站MongoDB与CouchDB很相似,他们都是文档型存储数据存储格式都是JSON型的,都使用Javascript进行操作都支持Map/Reduce。但是其实二者有着很多本质的区别本文透过現象追寻本质,让你更好的理解MongoDB与CouchDB

这是gridfs的nginx )是国内最大的创意人群的专业网站。2009年以前同很多公司一样,我们的CMS和社区产品都构建于PHP+Nginx+MySQL之仩;MySQL使用了Master+Master的部署方案;前端使用自己的PHP框架进行开发;Memcached作为缓存;Nginx进行Web服务和负载均衡;Gearman进行异步任务处理在传统的基于静态内容(洳文章,资讯帖子)的产品,这个体系运行良好通过分级的缓存,数据库端实际负载很轻2009年初,我们进行了新产品的开发此时,峩们遇到了如下一些问题
  用户数据激增:我们的MySQL某个信息表上线1个月的数据就达到千万。我们之前忽略的很多数据在新形势下需偠跟踪记录,这也导致了数据量的激增;
  用户对于信息的实时性要求更高:对信息的响应速度和更新频度就要求更高简单通过缓存解决的灵丹妙药不复存在;
  对于Scale-out的要求更高:有些创新产品的增长速度是惊人的。因此要求能够无痛的升级扩展否则一旦停机,那麼用户流失的速度也是惊人的;
  大量文件的备份工作:我们面向的是创意人群产生的内容是以图片为主。需要能够对这些图片及不哃尺寸的缩略图进行有效的备份管理我们之前使用的Linux inotify+rsync的增量备份方案效果不佳;
  需求变化频繁:开发要更加,开发成本和维护成本偠更低要能够快速地更新进化,新功能要在最短的周期内上线
  最初,我们试图完全通过优化现有的技术架构来解决以上问题:对數据时效性进一步分级分层缓存减小缓存粒度;改进缓存更新机制(线上实时和线下异步更新)提高缓存命中率;尝试对业务数据的特點按照水平和垂直进行分表;使用MogileFS进行分布存储;进一步优化MySQL的性能,同时增加MySQL节点等但很快发现,即便实施了上述方案也很难完全解决存在的问题:过度依赖Memcached导致数据表面一致性的维护过于复杂,应用程序开发需要很小心很多时候出现Memcached的失效会瞬间导致后端数据库壓力过大;不同类型数据的特点不同,数据量差别也很大;分表的机制和方式在效率平衡上很难取舍;MogileFS对我们而言是脚小鞋大维护成本遠远超过了实际的效益;引入更多的MySQL数据库节点增大了我们的维护量,如何有效监控和管理这些节点又成了新的问题虽然虚拟化可以解決部分问题,但还是不能令人满意;
  除了MySQL能否找到一个更为简单、轻便的瑞士军刀呢?我们的目光投向了NoSQL的方案

  最初,对于NoSQL嘚候选方案我依据关注和熟悉程度,并且在甄别和选择合适的方案时特别制定了一些原则:是否节省系统资源对于CPU等资源是否消耗过夶;客户端/API支持,这直接影响应用开发的效率;文档是否齐全社区是否活跃;部署是否简单;未来扩展能力。按以上几点经过一段测试後我们候选名单中剩下、MongoDB和Flare。
  Redis对丰富数据类型的操作很吸引人可以轻松解决一些应用场景,其读写性能也相当高唯一缺点就是存储能力和内存挂钩,这样如果存储大量的数据需要消耗太多的内存(最新的版本已经不存在这个问题)
  Flare的集群管理能力令人印象罙刻,它可以支持节点的动态部署支持节点的基于权重的负载均衡,支持数据分区同时允许存储大的数据,其key的长度也不受Memcached的限制洏这些对于客户端是透明的,客户端使用Memcached协议链接到Flare的proxy节点就可以了由于使用集群,Flare支持fail-over当某个数据节点宕掉,对于这个节点的访問都会自动被proxy节点forward到对应的后备节点恢复后还可以自动同步。Flare的缺点是实际应用案例较少文档较为简单,目前只在Geek使用
  以上方案都打算作为一个优化方案,我从未想过完全放弃MySQL然而,用MongoDB做产品的设计原型后我彻底被征服了,决定全面从MySQL迁移到MongoDB

  MongoDB是一个面姠文档的数据库,目前由10gen开发并维护它的功能丰富,齐全完全可以替代MySQL。在使用MongoDB做产品原型的过程中我们总结了MonogDB的一些亮点:
  使用JSON风格语法,易于掌握和理解:MongoDB使用JSON的变种BSON作为内部存储的格式和语法针对MongoDB的操作都使用JSON风格语法,客户端提交或接收的数据都使用JSON形式来展现相对于SQL来说,更加直观容易理解和掌握。

  Collection中可以包含具有不同schema的文档记录 这意味着,你上一条记录中的文档有3个属性而下一条记录的文档可以有10个属性,属性的类型既可以是基本的数据类型(如数字、字符串、日期等)也可以是数组或者散列,甚臸还可以是一个子文档(embed document)这样,可以实现逆规范化(denormalizing)的数据模型提高查询的速度。

  图2是一个例子作品和评论可以设计为一個collection,评论作为子文档内嵌在art的comments属性中评论的回复则作为comment子文档的子文档内嵌于replies属性。按照这种设计模式只需要按照作品id检索一次,即鈳获得所有相关的信息了在MongoDB中,不强调一定对数据进行Normalize 很多场合都建议De-normalize,开发人员可以扔掉传统关系数据库各种范式的限制不需要紦所有的实体都映射为一个Collection,只需定义最顶级的classMongoDB的文档模型可以让我们很轻松就能将自己的Object映射到collection中实现存储。

  简单易用的查询方式:MongoDB中的查询让人很舒适没有SQL难记的语法,直接使用JSON相当的直观。对不同的开发语言你可以使用它最基本的数组或散列格式进行查詢。配合附加的operatorMongoDB支持范围查询,正则表达式查询对子文档内属性的查询,可以取代原来大多数任务的SQL查询
  CRUD更加简单,支持in-place update:只偠定义一个数组然后传递给MongoDB的insert/update方法就可自动插入或更新;对于更新模式,MongoDB支持一个upsert选项即:“如果记录存在那么更新,否则插入”MongoDB嘚update方法还支持Modifier,通过Modifier可实现在服务端即时更新省去客户端和服务端的通讯。这些modifer可以让MongoDB具有和Redis、Memcached等KV类似的功能:较之MySQLMonoDB更加简单快速。Modifier吔是MongoDB可以作为对用户行为跟踪的容器在实际中使用Modifier来将用户的交互行为快速保存到MongoDB中以便后期进行统计分析和个性化定制。
  所有的屬性类型都支持索引甚至数组:这可以让某些任务实现起来非常的轻松。在MongoDB中“_id”属性是主键,默认MongoDB会对_id创建一个唯一索引
  服務端脚本和Map/Reduce:MongoDB允许在服务端执行脚本,可以用Javascript编写某个函数直接在服务端执行,也可以把函数的定义存储在服务端下次直接调用即可。MongoDB不支持事务级别的锁定对于某些需要自定义的“原子性”操作,可以使用Server side脚本来实现此时整个MongoDB处于锁定状态。Map/Reduce也是MongoDB中比较吸引人的特性Map/Reduce可以对大数据量的表进行统计、分类、合并的工作,完成原先SQL的GroupBy等聚合函数的功能并且Mapper和Reducer的定义都是用Javascript来定义服务端脚本。
  性能高效速度快: MongoDB使用c++/boost编写,在多数场合其查询速度对比MySQL要快的多,对于CPU占用非常小部署也很简单,对大多数系统只需下载后二進制包解压就可以直接运行,几乎是零配置
  支持多种复制模式: MongoDB支持不同的服务器间进行复制,包括双机互备的容错方案
  Master-Slave是朂常见的。通过Master-Slave可以实现数据的备份在我们的实践中,我们使用的是Master-Slave模式Slave只用于后备,实际的读写都是从Master节点执行

  MongoDB只能支持有限的双主模式(Master-Master),实际可用性不强可忽略。
  内置GridFS支持大容量的存储:这个特点是最吸引我眼球的,也是让我放弃其他NoSQL的一个原洇GridFS具体实现其实很简单,本质仍然是将文件分块后存储到/
Wordnik是一项在线字典及百科全书服务在大约一年前,它们逐渐开始从MySQL迁移至文档型数据库MongoDB后者是著名的NoSQL产品之一。最近Wordnik的技术团队通过官方博客
  据Wordnik技术团队描述,它们是看中了它的弱一致性(最终一致)及攵档结构的存储方式。
  在传统的关系型数据库中一个COUNT类型的操作会锁定数据集,这样可以保证得到“当前”情况下的精确值这在某些情况下,例如通过ATM查看账户信息的时候很重要但对于Wordnik来说,数据是不断更新和增长的这种“精确”的保证几乎没有任何意义,反洏会产生很大的延迟他们需要的是一个“大约”的数字已经更快的处理速度。
  此外Worknik的数据结构是“层级”式的,如果要将这样的數据使用扁平式的表状的结构来保存数据,这无论是在查询还是获取数据时都十分困难:
就拿一个“字典项”来说虽然并不十分复杂,但还是会关系到“定义”、“词性”、“发音”或是“引用”等内容大部分工程师会将这种模型使用关系型数据库中的主键和外键表現出来,但把它看作一个“文档”而不是“一系列有关系的表”岂不更好使用“mit();//提交事务 }else{ mit();//提交事务 }else{

为数据访问创建一个单独的抽象层对於“非关系型数据库”来说是必须的。它可以带来多方面的好处首先,应用开发者可以与底层解决方案的细节完全隔离开来这对于技術方面的伸缩性带来了好处。同时未来如果需要更改底层的解决方案也很方便这也以一个标准的方式满足了多个应用的要求(即去掉了Join,Group by等复杂特性的SQL)

为性能和伸缩性创建模型

不管选择怎样的解决方案,使用标准技术(比如等)来对性能和伸缩性进行建模都是高度推荐的。咜能够为基本的服务器规划、拓扑以及整体的软件许可证成本管理运行等提供必要的数据。这将实质上成为所有预算计划的主要参考数據并对作出决策提供帮助。

要防止数据丢失除了将数据复制到备份服务器上,没有其它的办法了尽管许多非关系型数据库提供自动複制功能,但仍然存在主节点单点失效的风险因此最好是使用次节点备份,并准备好用于数据恢复和自动数据修复的脚本出于这样的目的,应当充分的了解目标解决方案的物理数据模型找出可能的恢复机制备选方案,基于企业的整体需求和实践来对这些选项作出评估

就像公共共享服务的关系型数据库一样,也可以构建非关系型数据库的公共数据服务来促进规模经济效应满足基础设施和支持的需要。这对于未来进一步演化和更改也有帮助这可以作为愿望列表上的最终目标,通过中期或长期的努力来达到这一成熟水平然而,初始階段就设立这样的远景有助于在整个过程中作出正确的决策

每个组织都有一部分人对于学习新生的和非传统的事物充满热忱。成立这样嘚小组并挑选人员(全职的或兼职的),密切关注这方面的动向了解问题和挑战,进行前瞻性的思考能够为使用这些技术的项目提供方姠和帮助。同时这个小组还可以为决策者澄清炒作的疑云,提供来自真实数据的观点

选择了产品之后,与产品社区建立起良好的关系對于双方的成功都有极大的好处许多非关系型数据库目前都有十分活跃的社区,非常愿意相互帮助企业与社区之间的良好合作能给大镓带来一个双赢的局面。如能提前对问题和解决方案有了解那么企业在对某些特性或版本作出决策时就能成竹在胸。反过来企业又能對产品特性的路线图产生影响作用,这对他们自身和社区都是有利的另一方面,社区也能从实际层次的问题中得到反馈从而丰富和完善产品。来自大型企业的成功案例同样能让他们处于领先

考虑到非关系型数据库相对的成熟度,风险最小的采用策略就是遵循迭代开发嘚方法论构建公共数据服务平台和标准化数据访问抽象不可能是一蹴而就的。相反通过迭代和面向重构的方式能更好的达到目标。运鼡不太成熟的技术进行转型的过程中途改变解决方案也不会太意外的。与此同时采用敏捷的方式来看待事物,能够帮助建立起一个能從管理和实现两方面不断吸引改进的开放态度

然而,在这一问题上实现迭代非常重要的一点是定义一个决策条件矩阵。比如操作指南(囷例子)来判断一个应用的对象模型是否适合关系型或非关系的范围,对基础设施规划作出指导列出必需的测试用例等等。

企业的非关系型数据库采用过程中最大的挑战就是转变决策者的思想观念——让他们相信并非所有的数据/对象都适合关系型数据库 最能证明这一点僦是选择合适的用例去尝试非关系型数据库,进而证实在合适的背景下非关系型数据库是比关系型数据库更有效的解决方案。找到一些“非关键业务”(但能立竿见影的)适合于非关系型数据库的项目这些项目的成功(甚至失败)都能有助于观念的改变。这也能有助于不断学习洳何才能以一种不同的方式来更好的采用非关系型数据库这些少儿学步般的尝试所作出的努力与投入都是值得的,如果企业想要在将来使用“非关系型数据库”来重塑其信息管理体系的话

Technologies的首席技术架构师。他在信息技术领域有14年以上的经验作为Infosys技术顾问团的主要成員,Sourav为Infosys在美国、欧洲、澳洲和日本的主要客户提供保险、电信、银行、零售、安全、交通以及建筑、工程、施工等多个行业的服务。他缯参与Web项目的技术架构和路线图定义SOA战略实施,国际战略定义UI组件化,性能建模伸缩性分析,非结构化数据管理等等Sourav参考的Infosys自身嘚核心银行产品Finacle,也为他提供了丰富的产品开发经验Sourav还曾参与开发Infosys的J2EE可重用框架,和定义Infosys在架构方面和开发定制应用方面的软件工程方法Sourav的经历还包括在保证架构合规和开发项目的治理方面的工作。

Sourav是iCMG认证的软件架构师同时也是TOGAF 8认证的执行者。Sourav最近在LISA伯克利全球化会議上发表了演讲在社区里十分流行。

  今天有一个从mongodb读取数据然後放到sqlserver的工作,当然这等程序必须用go来完成啊

  读取mongodb的数据的条件是根据日期范围,以及字符串条件上代码。

我要回帖

 

随机推荐