从 mongodb 阶段性技术总结 中抽取并整理了对大家有帮助的十个要点:
 
1.mongodb 表名和字段名统一用小写字母
mongodb 是默认区分大小写的,为了避免以前在 mysql 下遇到的大小写敏感导致程序访问频频出错,
建立规范,mongodb 的表名和字段名都用小写字母命名。
 
2.尽可能的缩短字段名的长度
mongodb 的 schema free 导致了每笔数据都要存储它的 key 以及属性,这导致了这些数据的大量冗余。
开发人员也许考虑到,从易读性出发设计的 key 名,基本都是按照字面意思去设计的,这导致 key 很长,对应的数据存储占用了很大的空间。
所以,在你的程序里维护一套字典即可,尽可能降低 key 的长度。
譬如:
static final String CONTENT = "content";
static final String CONTENT_TYPE = "ctype";
static final String CONTENT_LENGTH = "clen";
 
3.记住,mongodb 的查询每次只能用到一个索引
对于较复杂的表结构,可能会导致你频频使用联合索引。
但记住:
1)mongodb 单表最大索引数为 64 。
2)索引越多,插入或修改记录就会导致 mongodb 越慢。写锁会阻塞读请求,写得越慢,阻塞读请求越多、阻塞时间越长。
所以,索引越加越多的时候,你可能需要审视一下表结构设计的合理性
 
4.客户端连接数大小的设置
mongodb-java-driver 的连接池,目前从观察到的情况是应用一开启便根据 connectionsPerHost 变量的设置,建立全部连接,然后提供给程序使用,并且一旦其中某个连接到数据库的访问失败,则会清空整个连接池到这台数据库的连接,并重新建立连接。
而 mongodb 对中断连接的垃圾清理工作则是懒惰的被动清理方式,如果驱动程序端配置的连接数过大,一旦发生重连,则会导致 mongo 服务器端堆积大量的垃圾连接以及对应数据,导致主机资源耗尽。
建议: mongodb 驱动的连接池大小的设置一般应该控制 100 左右。
 
5.实例分离
mongodb 对数据库的访问全部加锁。
如是查询请求则设置共享锁。
数据修改请求则设置全局排他锁,且是实例级别的排他锁。
写锁会阻塞读请求,如果长时间持有写锁,会阻塞整个实例的读请求。
建议:
1)不同应用不应该共用同一个实例,防止互相阻塞
2)如服务器资源不足,共用同一个实例,要保证读写特性相同,如都是读多写少,防止一台写多应用阻塞读请求。
(评语:旧版本的MongoDB (pre 2.0)拥有一个全局的写入锁,这个问题在2.0版本中的得到了显著的改善,并且在当前2.2版本中得到了进一步的加强。MongoDB 2.2使用数据库级别的锁在这个问题上迈进了一大步。所以用 MongoDB 2.2的人可以忽略此条目。
 
6.需要重点关注的 mongodb 性能指标
关注主要性能指标:
1)Faults:显示 mongodb 每秒页面故障的数量,这个是 mongodb 映射到虚拟地址空间,而不是物理内存。这个值如果飙高的话,可能意味着机器没有足够的内存来存储数据和索引。
2)Flushes:每秒做了多少次 fsync,显示多少次数据被刷新进了磁盘。
3)locked:写锁。
4)idx miss:索引未命中比例。
5)qr | qw:读写锁的请求队列长度。
6)conn: 当前已经建立的连接数。
 
7.严重的空间碎片问题
mongodb 如果数据修改很频繁,会出现比较严重的空间碎片问题,表现在磁盘文件扩张与实际数据量不相符,内存不够用,索引命中率低,查询效率降低。
碎片整理,目前我们采用的版本没有太有效的方法。
可以用 db.repaireDatabase() 来整理数据库,这个过程非常的慢。
如果是 master/slave 模式,则相当于执行一次主从切换,然后从新建立从库。
如果是 replSet 架构,可以停掉数据库,然后删除数据目录,从新从复制组中全同步数据,这个时候要考虑 oplog 的尺寸。
一个大体的步骤:
1)先调用rs.freeze(1200),将每个不想让它成为 primary 的机器让它在 1200 秒内无法成为 primary(这步也可以不做);
2)将 primary stepDown,不出意外新的 primary 会起来;
3)将原 primary kill 掉;
4)删掉所有 data 数据(调用 repair 很慢,真不如干掉重新来);
5)再重启动原 primary 的进程;
6)以此循环完成整个复制组的全部重建。
 
8.连接池 WriterConcern 模式选择
有些应用配置了 WriterConcern.FSYNC_SAFE 模式;这种配置意味着客户端在插入数据或更新数据的时候,要求 mongodb 必须将所更新的数据写入磁盘并返回更新成功的信息给程序。
如果碰上应用程序访问压力大,mongodb 就会反应迟钝,并可能会假死。
针对此情况,需要评估数据的一致性需求,做出合适调整。
我们一般建议关闭此选项。
(评语:刘奎波的业务中心优化时就关闭了这个 WriterConcern.FSYNC_SAFE 模式)
 
9.开发时注意的细节
1)更新某条数据的时候,先查出来再更新会减小锁的时间
2)只有真正需要的字段才select出来;
3)只有返回很少结果的查询才用索引,否则会加载太多数据,比没有用索引还慢
4)属性比较多的时候,建立分层的关系能够提高查询效率,否则每个记录都要过一遍才能找到要的属性。(评语:貌似说的是以 Array 形式存储的 subdocument)
5)skip+limit 翻页,越往后面越慢。比较靠谱的做法是,先找出上次的id,翻页的时候不用 skip:

last_row_id = ObjectId('....');
db.activity_stream->find({_id:{$lt: last_row_id },user_id:20 } ).sort( {_id:-1} ).limit(10);

 
10.关于硬件资源的选择
虚拟机可以很好的隔离资源,并可动态的扩展。
我们建议 mongodb 的部署采用虚拟机的方式,每个虚拟机部署一个实例,使各节点分散在不同的物理机上,根据应用的前期预测,平衡虚拟机的之间的i/o。
 
参考资源:
1)horizonhyg,2012,Mongodb写入安全机制--GetLastError
2)horizonhyg,2012,java连接mongo

赠图2枚:
 

十个 MongoDB 使用要点的更多相关文章

  1. MongoDB 知识要点一览

    1.启动mongoDb数据库: 进入mongoDB的安装目录,执行如下命令 C:\Program Files\MongoDB\Server\3.0\bin>mongod.exe --dbpath ...

  2. (转)MongoDb的十个使用要点

    从 mongodb 阶段性技术总结 中抽取并整理了对大家有帮助的十个要点:   1.mongodb 表名和字段名统一用小写字母 mongodb 是默认区分大小写的,为了避免以前在 mysql 下遇到的 ...

  3. mongodb设置 十个要点

    mongodb设置 十个要点   一.对象ID的生成 每一个mongoDB文档那个都要求有一个主键.它在每一个集合中对全部的文档必须是唯一的.主键存放在文档_id字段中.由12个字符组成: 4c291 ...

  4. Java堆内存的十个要点

    Java中的堆空间是什么? 当Java程序开始运行时,JVM会从操作系统获取一些内存.JVM使用这些内存,这些内存的一部分就是堆内存.堆内存通常在存储地址的底层,向上排列.当一个对象通过new关键字或 ...

  5. 关于Mongodb的全面总结

    MongoDB的内部构造<MongoDB The Definitive Guide> MongoDB的官方文档基本是how to do的介绍,而关于how it worked却少之又少,本 ...

  6. MongoDB学习笔记(一) MongoDB介绍及安装(摘)

    MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种.它在许多场景下可用于替代传统的关系型数据库或键/值存储方式.Mongo使用C++开发.Mongo的官方网 ...

  7. MongoDB 分页查询的方法及性能

    最近有点忙,本来有好多东西可以总结,Redis系列其实还应该有四.五.六...不过<Redis in Action>还没读完,等读完再来总结,不然太水,对不起读者. 自从上次Redis之后 ...

  8. Java Web编程技术学习要点及方向

    学习编程技术要点及方向亮点: 传统学习编程技术落后,应跟著潮流,要对业务聚焦处理.要Jar, 不要War:以小为主,以简为宝,集堆而成.去繁取简 Spring Boot,明日之春(future of ...

  9. Windows下使用WSRM限制MongoDB内存

    有个项目用到了MongoDB,我们是在WINDOWS 2008 64位环境下部署的,为啥不部署到linux下面呢,我们没那么多服务器,只能将就一下了. 大家都知道Mongodb吃内存太厉害了,如果不重 ...

随机推荐

  1. 【题解】【数组】【查找】【Leetcode】Search in Rotated Sorted Array

    Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...

  2. OpenFlow Switch学习笔记(二)——OpenFlow Ports

    OpenFlow Ports是OpenFlow Switch与剩余网络之间传递Packet的网络接口.OpenFlow Switches之间通过OpenFlow Ports彼此相互逻辑连接.一个Ope ...

  3. PAT (Basic Level) Practise:1039. 到底买不买

    [题目链接] 小红想买些珠子做一串自己喜欢的珠串.卖珠子的摊主有很多串五颜六色的珠串,但是不肯把任何一串拆散了卖.于是小红要你帮忙判断一下,某串珠子里是否包含了全部自己想要的珠子?如果是,那么告诉她有 ...

  4. MySql配置方法,批处理进行MySql配置

    @echo 注意右击管理员运行 @pause @echo .添加环境变量 @echo .my.ini中添加如下配置 @echo [mysqld] @echo basedir=C:\Program Fi ...

  5. php二分式查找

    要求数组是有序数组 1 <?php 2 #二分查找 3 function binarySearch(Array $arr, $target) { 4 $low = 0; 5 $high = co ...

  6. OpenCV图像Surf与flann特征点(转载)

    Surf(Speed Up Robust Feature) Surf算法的原理                                                             ...

  7. 图像处理之face morphing

    以前在论坛.微博经常看到一张脸,五官长得像A,脸型似乎又是B,觉得很有意思. 比如像这张图片.这张图片应该是网友用Photoshop完成的,他们取了郭大爷的五官,放在金元帅的脸上,在把边缘处理平滑. ...

  8. HTML DOM部分---事件 windows对象;

    <!--DOM操作windows对象操作 对浏览器进行操作document对象操作 对浏览器内页面文件进行操作 window.shuxing;属性调用格式window.fangfa();方法调用 ...

  9. PHP安全配置

    vi /etc/php.ini #编辑 date.timezone = PRC #在946行把前面的分号去掉,改为date.timezone = PRC disable_functions = pas ...

  10. java的nio之:java的nio系列教程之FileChannel

    一:Java NIO的FileChannel===>Java NIO中的FileChannel是一个连接到文件的通道.可以通过文件通道读写文件. ===>FileChannel无法设置为非 ...