MongoDB的正确使用姿势

首先,MongoDB是文档型(Document store)的NoSQL数据库,数据以文档(对应关系型数据库的记录,本文有时候会混用)的形式在MongoDB中保存,文档实际上就是一个个JSON字符串,想必大家对JSON都比较熟悉,不赘述。使用JSON的好处是非常直观,通过一系列的Key-Value键值对来表示数据,符合我们的阅读习惯,下图所示是以JSON表示的用户信息文档。

在主流的计算机语言如Java、Python中对JSON都有很好的支持,数据从MongoDB中读取出来后,可无需转换直接使用;MongoDB文档另一个特点是Key-Value键值对支持丰富的数据结构,Value可以是普通的整型、字符串,可以是数组,也可以是嵌套的子文档,使用嵌套的好处是在MongoDB中仅需一次简单的查询就能够获取到你所需的数据。举电商领域为例,网易严选上卖的上衣和裤子两种商品,除了有共同属性,如产地、价格、材质、颜色等外,还有各自有不同的属性集,如上衣的独有属性是肩宽、胸围、袖长等,裤子的独有属性是臀围、脚口和裤长等。

这些独有属性可以直接以JSON子文档的方式嵌套在商品这个文档中,一次查询直接获取全部内容,不需要进行多表join;MongoDB文档的另一大特点是模式灵活:不同文档相同key的value类型可以是整形也可以是字符串等其他类型,不同文档可以有不同的key,比如有些商品有折扣字段,可以定义不同会员等级的不同折扣。在电商配套的物流领域,可以将一个快递的物流信息直接嵌套在以商品id为唯一索引的文档中,一次查询就可以获取完整的快递流向信息。MongoDB查询还提供了非常丰富的操作符,在查询中组合使用效率倍增。

基于文档的灵活的数据模式,是MongoDB的一大优势,对于数据模型多样或多变的业务场景,相比MySQL等数据库,无需使用DDL语句进行表结构的修改;相比其他Key-Value数据库,由于MongoDB的Value字段对于MongoDB是非透明的,可以对其建立索引,还可以进行全文检索,在查询效率上更具优势。该模式在游戏、电商、社交、视频直播、物流等领域非常适用,通过在用户或商品中嵌套不同用途的子文档来实现快速查询。对于监控、日志数据存储,第三方信息抓取等场景也同样适用,因为不同监控数据、日志记录、抓取的数据所包含的字段往往是不一样的,某种程度上说也是不可控的。同时,灵活的模式对于类似游戏市场活动、移动App等要求快速开发上线但需求变动(导致数据模型变大)比较大的产品或场景也比较适用。

其次,MongoDB还具有强大的索引能力,支持创建唯一索引、二级索引、TTL索引和地理位置索引等,这在NoSQL数据库中是数一数二的,在此基础上,MongoDB还提供了执行计划功能,通过explain()和hint()命令可以查看执行计划、强制查询走某个索引,这些特性相比关系型数据库也不成多让。MongoDB集合在创建时默认就基于_id字段创建了唯一索引,数据插入时会检查_id字段的唯一性,MongoDB可以在包括数组中字段或嵌套文档中的字段几乎任意字段上创建索引(一般为二级索引),大大提高了查询效率,在没有跨记录或跨表事务但对性能要求又非常高的某些场景下能够替代关系型数据库。在内存足够的情况下,索引会被加载到Cache中,如果执行的查询是索引覆盖的,其性能甚至可以媲美Redis等内存数据库等。TTL索引在保存日志或监控数据等场景下大有用武之地,通过创建TTL索引,实现自动删除过期记录的功能,(在使用MongoDB TTL索引需要注意,数据的过期时间无法精确控制,无法做到过期即删除,在大数据量的情况下会有一定的性能开销和删除延迟)。

地理位置索引是MongoDB早已被用户所熟知的特性,其球面(Spherical)和平面(Flat)两种模式,提供了丰富的地址位置的表示方式,如2d、2dsphere和GeoJSON等,对于移动App,如地图软件、打车软件、外卖软件,MongoDB强大的地理位置索引功能使其最佳选择;此外,对于物联网、智慧都市等领域,也需要大量的地理位置相关操作,这些都是MongoDB的竞技场。

再次,MongoDB的复制集是数据库领域领先的高可用和读写负载均衡解决方案,提供了数据自动(异步/同步)复制能力,一个新节点加入到复制集中会自动进行数据初始同步随后使用oplog进行增量复制,无需人工干预;如果复制集的Primary节点发生宕机,MongoDB会自动进行主从切换,在复制集大多数节点在线的情况下,能够基于Raft协议(MongoDB 3.2开始,之前版本不未使用Raft)自动地快速选出新的Primary并恢复读写服务(在选主期间,无法进行写操作),无需人工干预;MongoDB运维人员所需做的仅仅是将宕机节点重新启动,若宕机的是Primary,则重新启动后,会自动进行数据回滚并最终成为复制集的Secondary节点(正常情况下)。

在复制集机制下,还可以通过对节点进行滚动处理的方式进行在线维护升级。所以,相比目前的大多数关系型数据库,MongoDB复制集实现了自动复制和故障切换,大大减低了运维复杂度,解放了DBA。如果你对数据的持久化和可用性有较高的要求,MongoDB复制集是上佳的选择。此外,复制集还提供了Write Concern、Read Preference、Read Concern和Tag sets等读写行为控制功能,不同的业务应用类型可以参考官方手册根据对数据持久化、数据一致性和可用性的不同要求进行灵活地设置。

最后,MongoDB是为大数据而生的,提供sharding机制用于实现业务的水平扩展。每个shard都保存业务的一部分数据,shard可以配置为复制集,确保shard上数据的高可用性,shard内部由一系列连续的chunk组成,chunk是某一片键区间内的数据记录集合;mongos用于业务请求的路由,将业务负载分摊到不同的shard上,此外mongos还会对shard上超过一定大小的chunk进行分裂(split);根据不同shard中数据量的大小,在shard将进行chunk迁移(migrate),应该说sharding提供了完善的业务数据和负载水平扩展的机制,对于物联网、日志系统和监控系统这类包含TB级海量数据的应用场景,使用MongoDB sharding是个不错的选择。

在生产环境中,sharding并不是必须的,并不是新业务起来的时候就马上部署sharding集群,只有当业务的数据量达到单个复制集无法支撑、或者业务的负载超过了复制集的服务能力的时候,才考虑部署sharding,毕竟相比复制集,sharding在部署和管理上都复杂很多。

介绍了MongoDB的优势,也不得不提MongoDB的不足,MongoDB仅支持文档内的事务,所以对于需要跨文档或跨集合事务的应用,请谨慎使用MongoDB;另外,对于需要多表复杂Join的业务,还是使用关系型数据库为好,MongoDB还在改善的路上;最后,对于PB级大数据量,且需要进行大规模计算的场景,使用MongoDB时需要配套使用Spark、Hadoop等大数据套件,让MongoDB做正确的事情。总结起来,如果你的业务满足一个或多个特点,那么选择MongoDB是个正确的决定:

1、无需要跨文档或跨表的事务及复杂的join查询支持

2、敏捷迭代的业务,需求变动频繁,数据模型无法确定

3、存储的数据格式灵活,不固定,或属于半结构化数据

4、业务并发访问量大,需数千的QPS

5、TB级以上的海量数据存储,且数据量不断增加

6、要求存储的数据持久化、不丢失

7、需要99.999%的数据高可用性

8、需要大量的地理位置查询、文本查询

9、推荐一个交流学习群:478030634 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多:

目前开源数据库众多,大家可选的余地很大,就会出现这样的问题:MySQL、MongoDB、Redis、Hbase等这些数据库哪个更好?其实这是一个伪命题,脱离了具体的业务场景来讨论好坏是纸上谈兵,没有最好的,只有最合适的,谁也无法保证完全取代谁,上面的每种数据库都在变得更好,都在不停地完善自身。比如MySQL在不断提升其JSON和地理位置处理能力、组复制(group replication)已在开发等;而MongoDB在增强join类型支持,提供更为复杂的多集合查询能力,计划支持事务等;Redis也加入了地理位置处理能力。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容