mongo使用经验谈

1.mongodb 的查询每次只能用到一个索引
对于较复杂的表结构,可能会导致你频频使用联合索引。
但记住:
1)mongodb 单表最大索引数为 64 。
2)索引越多,插入或修改记录就会导致 mongodb 越慢。写锁会阻塞读请求,写得越慢,阻塞读请求越多、阻塞时间越长。
所以, 索引越加越多的时候,你可能需要审视一下表结构设计的合理性
 
2.客户端连接数大小的设置
mongodb-java-driver 的连接池,目前从观察到的情况是应用一开启便根据 connectionsPerHost 变量的设置,建立全部连接,然后提供给程序使用,并且一旦其中某个连接到数据库的访问失败,则会清空整个连接池到这台数据库的连接,并重新建立连接。
而 mongodb 对中断连接的垃圾清理工作则是懒惰的被动清理方式,如果驱动程序端配置的连接数过大,一旦发生重连,则会导致 mongo 服务器端堆积大量的垃圾连接以及对应数据,导致主机资源耗尽。
建议: mongodb 驱动的连接池大小的设置一般应该控制 100 左右。
 
3.实例分离
mongodb 对数据库的访问全部加锁。
如是查询请求则设置共享锁。
数据修改请求则设置全局排他锁,且是实例级别的排他锁。
写锁会阻塞读请求,如果长时间持有写锁,会阻塞整个实例的读请求。
建议:
1) 不同应用不应该共用同一个实例,防止互相阻塞
2)如服务器资源不足,共用同一个实例, 要保证读写特性相同,如都是读多写少,防止一台写多应用阻塞读请求。

 
4.需要重点关注的 mongodb 性能指标
关注主要性能指标:
1)Faults:显示 mongodb 每秒页面故障的数量,这个是 mongodb 映射到虚拟地址空间,而不是物理内存。这个值如果飙高的话,可能意味着机器没有足够的内存来存储数据和索引。
2)Flushes:每秒做了多少次 fsync,显示多少次数据被刷新进了磁盘。
3)locked:写锁。
4)idx miss:索引未命中比例。
5)qr | qw:读写锁的请求队列长度。
6)conn: 当前已经建立的连接数。
 
5.严重的空间碎片问题
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)以此循环完成整个复制组的全部重建。
 
6.连接池 WriterConcern 模式选择
有些应用配置了 WriterConcern.FSYNC_SAFE 模式;这种配置意味着客户端在插入数据或更新数据的时候,要求 mongodb 必须将所更新的数据写入磁盘并返回更新成功的信息给程序。
如果碰上应用程序访问压力大,mongodb 就会反应迟钝,并可能会假死。
针对此情况,需要评估数据的一致性需求,做出合适调整。
我们一般建议关闭此选项。
(评语:刘奎波的业务中心优化时就关闭了这个 WriterConcern.FSYNC_SAFE 模式)
 
7.开发时注意的细节
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);

(以上不理解,请参考图灵出版社的两本mongo图书)

 
8.关于硬件资源的选择
虚拟机可以很好的隔离资源,并可动态的扩展。
我们建议 mongodb 的部署采用虚拟机的方式,每个虚拟机部署一个实例,使各节点分散在不同的物理机上,根据应用的前期预测,平衡虚拟机的之间的i/o。

9.删掉的数据收回磁盘空间
mongodb删除集合后磁盘空间不释放,只有用db.repairDatabase()去修复才能释放。
注意事项:去修复时一定要停掉读写,并且最好mongodb要有备机才可以。

10.关闭mongo服务的方式
a.kill pid,务必不要使用kill -9,不然需要repair data.
b.use admin;
   db.shutdownServer();

ref:
http://www.cnblogs.com/zhengyun_ustc/archive/2013/01/25/2875962.html
http://www.xuebuyuan.com/1281156.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值