`
zhengyun_ustc
  • 浏览: 83054 次
  • 性别: 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节:...

    2020最新BAT面试题.rar

    3. **MySQL性能优化的21个最佳实践.pdf**:MySQL性能优化包括了索引策略、查询优化、存储配置等多个方面。21个最佳实践可能涵盖如避免全表扫描、合理使用索引、优化JOIN操作等内容。 4. **Java基础面试题.pdf**:...

    JAVA进阶资料 进阶资料

    4. **MySQL性能优化的21个最佳实践.pdf**:这是一份实用的MySQL性能调优指南,包含了如索引优化、查询重构、连接池配置等21个关键实践,可以帮助开发者提升数据库性能并降低延迟。 5. **JVM执行子系统.pdf**:JVM的...

    1.联接数据库55 1.联接数据库55

    此外,为了确保数据的安全性和性能,应考虑以下最佳实践: - **使用预编译的SQL语句**:防止SQL注入攻击。 - **连接池**:管理多个数据库连接,提高效率,减少资源消耗。 - **事务处理**:确保数据一致性,尤其是在...

    Java架构面试专题汇总

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

    Java架构面试笔试专题资料及经验(含答案)SpringBoot面试Linux面试专题及答案 合集.zip

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

    数据库设计指南-60个设计技巧

    50. 遵循最佳实践:如遵循SQL编码规范,避免SQL注入等常见安全问题。 51. 数据库反模式识别:了解并避免常见的数据库设计反模式,如数据冗余、过度规范化等。 52. 确保可移植性:设计时考虑到将来可能的系统迁移或...

    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面试专题及...

    UniDAC 5.5.12

    对于开发者来说,查看源代码可以帮助深入理解内部工作机制,学习数据库访问的最佳实践,甚至定制自己的数据库组件。 总结,UniDAC 5.5.12作为一款强大的数据库开发工具,为Delphi和C++Builder开发者提供了高效、...

    数据库设计60个技巧

    41. **设计模式与最佳实践**:如贫血模型、富模型等,遵循业界最佳实践。 42. **数据加密**:敏感数据加密存储,保障信息安全。 43. **数据库设计的可维护性**:设计易于理解和修改的结构,便于后期维护。 44. **...

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

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

    选择判断.docx

    - 高度规范化并不总是最佳实践,有时反规范化可以提升性能(F58)。 9. **数据库理论与规范化**: - 第三范式(3NF)和博科斯范式(BCNF)是数据库规范化设计的重要概念,T54 和 T57 提及了这些范式。 - 最小...

    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