`
zhengyun_ustc
  • 浏览: 80266 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

55最佳实践系列:MongoDB最佳实践

阅读更多
@郑昀汇总 创建日期:2012/9
 
Application Design:
1)如果发现query没使用你预期的索引,请用hint强制使用指定索引
主站商品中心所使用的文档字段很多,各种索引建得也不少。在沙创排查慢查询时,曾百思不得其解,为什么明明建的有联合索引,查询起来还是非常慢呢,直到显式指定使用该联合索引。
hint的例子:
    db.collection.find({"age" : 18, "username" : /.*/}).hint({"username" : 1, "age" : 1})
 
2)Design documents to be self-sufficient,设计自给自足的文档
MongoDB 应该是一个大的、无声的数据存储(big, dumb data store)。它几乎不需做任何处理,只是负责存储和读取数据。你应该坚持这个目的,避免强迫 MongoDB 做一些客户端可以进行的计算工作。
如果真的想算一些文档里没有显式存储的数据,你有两个选择:
——招致严重的性能惩罚(让 MongoDB 用JavaScript 做运算);
——在文档中显式存储这些数据。
 
Implementation:
3)Override _id when you have your own simple, unique id
如果你的文档自己有明确的唯一键值,不需要 ObjectId 属性,那么请覆盖默认的 _id 字段,反正你也要在自己的 unique id 上建唯一索引。
 
Optimization:
4)数据量很大时,建联合索引时,不妨对比下索引升序和降序的查询效率
db.collection.ensureIndex({"store_id":- 1, "shop_id": 1})
上面的1代表ascending升序,-1代表descending降序。
单个字段建索引时,不需要考虑索引升序还是降序,都行。
但联合索引下的排序或范围查询(包括$in, $gt, $lt 等),需要重视索引设为升序还是降序。孙国玺认为,最好用大数据模拟一下业务场景,商户中心曾发现设-1比1快10倍以上。
 
5)如需在联合索引下排序,索引的建立方法
MongoDB 和 MySQL 都是B-Tree结构索引,所以一般来说,联合索引都可以这么建:
查询语句是:
    db.collection.find({x : 1,y : 2}).sort({z : 1})
那么,索引可以是:
    db.collection.ensureIndex({x : 1, y : 1,z : 1})//即x+y+z
也可以是:
    db.collection.ensureIndex({y : 1, x : 1,z : 1})//即y+x+z
排序字段总在联合索引的最后。
尽量把能过滤数据量多的字段放在前面。
但如果涉及范围查询(Range Queries),就要小心了。
查询语句是:
    db.collection.find({"country": {"$in": ["ZH", "EN"]}}).sort({"cars": 1})
那么较好的索引是:
    db.collection.ensureIndex({"cars": 1,"country": 1})
即, 在范围查询(包括$in, $gt, $lt 等)时,其实刻意在后面追加排序索引通常是没有效果的。因为在进行范围查询的过程中,我们得到的结果集本身并不是按追加的这个字段来排的,还需要进行一次 额外的排序才行。而在这种情况下,可能反序建立索引(排序字段在前、范围查询字段在后)反而会是一个比较优的选择。当然,是否更优也和具体的数据集有关, 还是要实测。
再举一个例子:
查询语句是:
    db.collection.find({x : 1,y : {$in:[1,2]}}).sort({z : 1})
那么较好的索引是:
    db.collection.ensureIndex({x : 1, z : 1,y : 1})//即x+z+y
 
6)养成用 explain 确认是否充分利用了索引的习惯
请确认你的查询是否充分利用到了索引,用explain命令查看一下查询执行的情况,添加必要的索引,避免扫表操作。
 
7)查询尽量采用分页,并且尽快释放游标
 
8)避免使用不会命中索引的语法,如 $nin
 
Data Safety and Consistency:

9)总是使用 Replica Sets (复制群集,副本集):

背景:Replica Sets 通过自动 failover 机制提供MongoDB的高可用性。Replica sets are a form of asynchronous master/slave replication, adding automatic failover and automatic recovery of member nodes
应用点:在应用中,如 primary 机器出现故障,那么某一台 secondary 机器就会通 过选举成为新的 primary ,整个集群仍然能够提供正常服务。我们的服务不会支持无同步机制的 MongoDB 部署方案。
图例:
http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_clipboard%20-011%20%E5%89%AF%E6%9C%AC.png
另,使用 Replica Sets 时,最好加1台仲裁服务器。
 
 
10)默认开启 journaling 日志:
背景:64-bitMongoDB 1.9.2+以上默认开启 Journaling 功能。32-bit或1.9.2以下版本,则需在命令行启动时加上 --journal 。
Journaling 的出现归因于某用户在单机使用 MongoDB 时执行了 kill -9 操作,导致数据不可用后提出的。
开启该功能时,变更会先写入 Journaling 日志,​定期集中提交​,然后在真实数据上进行这些变更。如果服务器安全关闭,日志会被清除。在服务器启动时,如果存在 Journaling 日志​,则会进行回放。这保证了那些已写入、但在服务器崩溃前还没有回放的​日志能在用户连接前​被执行。​ 
应用点:郑昀强 烈建议你在部署时开启 Journaling 日志。注意数据文件的存放位置。在使用时,请确认你的数据文件处于一个持久化存储中(比如/data /mongodb目录)。也可以使用非持久化的设备进行数据文件存储,不过你最好小心再小心,因为这可能会对你的集群架构造成影响。
热数据最好能放在内存中。能够保持热数据(以及索引数据)一直放在内存中,这一点非常重要,它将对整个集群的性能造成影响。如果通过监控发现 page fault 的数量增加,那么很可能就是热数据量超出了可用内存大小。当热数据量超出了可用内存量时,通常有两种解决方法:增加内存和数据分片。建议先增加内存,再考 虑通过数据分片的方式解决。
 
Administration:
11)保持版本更新:
应用点:保持版本更新很重要,10gen 在每个版本中都会修复一些问题,使 MongoDB 的运行更出色。比如在 2.0.x版本中,MongoDB 的存储性能和并发性能就有极大提高,同时还包括索引优化、Bug修复以及 compaction 命令等一系列改进。
 
12)不要在32位系统上使用MongoDB:
背景:在32位机器上,MongoDB只能存储约2.5GB的数据。因为 MongoDB在内部实现上是通过内存映射的方式来提高性能的,所以在32位机器上其内存地址本身就限制了数据容量。
 
13)压力过大升级服务器配置:
应用点:如果机器负载达到65%,那么应该考虑升级机器配置。在日常使用中,最好保持负载低于65%。同时这也对数据恢复和纵向扩展有影响。
 
14)确定热数据大小:
使用MongoDB,你最好保证你的热数据在你机器的内存大小之下,保证内存能容纳所有热数据。
 
15)选择正确的文件系统:
MongoDB 的数据文件是采用的预分配模式,并且在 Replication 里面,Master 和 Replica Sets 的非 Arbiter 节点都是会预先创建足够的空文件用以存储操作日志。
这些文件分配操作在一些文件系统上可能会非常慢,导致进程被 Block 。所以我们应该选择那些空间分配快速的文件系统。这里的结论是尽量不要用ext3,用ext4或者xfs。
 
16)选用合适的raid和磁盘:
尽量使用raid10,避免使用raid5,经济条件允许的情况下最好使用ssd硬盘。
 
17)如何关闭 MongoDB:
MongoDB 数据库在关闭的时候使用 kill -2 <mongo-pid>,
或者在 mongo 终端中使用  
use admin
db.shutdownServer()
 
18)分片(sharding)需谨慎:
应用点:分片策略会受数据访问特点的影响,所以在进行数据分片前,最好先理清楚数据的访问模式,并想明白是否确实需要分片。
由于 Shard Key 对性能的影响非常大,所以选择一个好的 Sharding Key 是非常重要的。对于 Shard Key 的选定直接决定了集群中数据分布是否均衡、集群性能是否合理。选择 Shard Key 的一个非常重要因素是万一某一个分片彻底不可访问了,受到影响的Chunk有多大(即使是用 Replica Set)。
http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_clipboard%20-%20012%E5%89%AF%E6%9C%AC.png
Config Server 对整个集群的健康运行是至关重要的,所以一旦你选择使用 分片机制,就一定要保证生产环境里有3个 Config Servers 。
永远不要删除 Config Servers 的数据,要确保频繁地对这些数据进行日常备份。如果可能,通过域名来指定节 点的地址,比如在/etc/hosts文件中指定相应的本地域名,这能让你在集群配置上更灵活。Config Servers 的压力很小,但还是必须运行在 64-bit instances 上。
千万不要把3个 Config Servers 都放在同一个 instance 上!
 
 
参考资源:
3)部分内容来自宋涛,刘奎波和孙国玺

赠图几枚:
70e7cafagw1dzu7kaec4fg.gif (440×570)
61d40ffatw1dlsxs3ux51j.jpg (320×240)
67efa0c0gw1dzu4ghfrl9j.jpg (440×316)
分享到:
评论

相关推荐

    Java架构面试资料合集Spring面试专题及答案MySQL面试Redis面试资料.zip

    MySQL性能优化的21个最佳实践 Spring面试专题及答案整理文档 一线互联网企业面试题(仅参考未整理答案) 分布式数据库面试专题系列:Memcached+Redis+MongoDB 分布式通讯面试专题系列:ActiveMQ+RabbitMQ+Kafka ...

    Java程序员面试题全.zip

    Tomcat+Mysql+设计模式、JVM与性能优化知识点整理、MySQL性能优化的21个最佳实践、MYSQL、redis、spring、多线程、分布式、面试必备之乐观锁与悲观锁、面试必问并发编程高级面试专题、面试常问必备之MySQL面试55题、...

    网络架构师148讲视频课程

    │ 第128节:应用建议及最佳实践.avi │ 第129节:MongoDB结合应用开发一.avi │ 第130节:MongoDB结合应用开发二.avi │ 第131节:应用MongoDB后体系结构.avi │ 第132节:MogileFS简介和入门.avi │ 第133节:...

    Java架构面试专题汇总

    Java架构面试专题汇总 zookeeper面试.pdf SQL优化面试.pdf Tomcat面试.pdf Netty面试.pdf Nginx面试.pdf RabbitMQ消息中间件面试.pdf ...MySQL性能优化的21个最佳实践.pdf Java基础面试题.pdf Kafka面试.pd

    Java、数据库、spring框架等面试题及答案

    MySQL性能优化的21个最佳实践.pdf mysql面试.pdf MySQL55题.pdf MyBatis面试.pdf MongoDB面试.pdf memcached面试.pdf Linux面试.pdf Kafka面试.pdf JVM面试.pdf Java基础面试.pdf java后端面试答案.pdf Java并发体系...

    重磅-史上最全的Java面试文档总结(jvm,mybatis,mysql优化算法)等总结文档大合集(300份).zip

    MySQL性能优化的21个最佳实践 Netty面试专题及答案 Nginx面试专题及答案 RabbitMQ消息中间件面试专题及答案 redis面试题及答案(上) Redis面试专题及答案(下) SpringBoot面试专题及答案 SpringCloud面试专题及...

    Java架构面试笔试专题资料及经验(含答案)和学习笔记.zip

    MySQL性能优化的21个最佳实践.pdf mysql面试专题及答案.pdf Netty面试专题及答案.pdf Nginx面试专题及答案.pdf RabbitMQ消息中间件面试专题及答案.pdf Redis面试专题及答案(下).pdf redis面试题及答案(上).pdf ...

    Java全能学习面试手册——Java面试题库.zip

    55 MySQL性能优化的21个最佳实践.pdf 56 Netty面试题.pdf 57 Netty面试专题.pdf 58 Nginx面试题.pdf 59 Nginx面试专题.pdf 60 Nginx实战书籍.pdf 61 RabbitMQ消息中间件面试专题.pdf 62 Redis面试题(二).pdf 63 ...

    Node与Express开发.pdf

    4.1 最佳实践 ................................................................................................................................... 26 4.2 版本控制 ..........................................

Global site tag (gtag.js) - Google Analytics