十个 MongoDB 使用要点

转自:http://www.cnblogs.com/zhengyun_ustc/archive/2013/01/25/2875962.html

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 左右。

( 参考阅读:PHP-FPM模式下可怕的 MongoDB-PHP-Driver 连接池无节制连接问题

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

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

时间: 2024-10-15 17:13:01

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

【转】MongoDB 知识要点一览

原文链接 http://www.cnblogs.com/zhangzili/p/4975080.html MongoDB 知识要点一览 1.启动mongoDb数据库: 进入mongoDB的安装目录,执行如下命令 C:\Program Files\MongoDB\Server\3.0\bin>mongod.exe --dbpath "C:\Program Files\MongoDB\Server\3.0\db" 启动成功后在打开一个cmd窗口,进入mongoDB的安装目录,执行mo

(转)MongoDb的十个使用要点

从 mongodb 阶段性技术总结 中抽取并整理了对大家有帮助的十个要点: 1.mongodb 表名和字段名统一用小写字母 mongodb 是默认区分大小写的,为了避免以前在 mysql 下遇到的大小写敏感导致程序访问频频出错, 建立规范,mongodb 的表名和字段名都用小写字母命名. 2.尽可能的缩短字段名的长度 mongodb 的 schema free 导致了每笔数据都要存储它的 key 以及属性,这导致了这些数据的大量冗余. 开发人员也许考虑到,从易读性出发设计的 key 名,基本都是

牛A人士分享关于软件开发十个要点 (一)

英特尔® 黑带软件开发人员是我们社区中最受推崇的成员.他们因为出色的技术专长以及领导力而得到普遍认可.我们采访了一组英特尔® 黑带软件开发成员,分享他们对开发人员所犯的最严重的业务错误的看法,以及他们如何纠正这些错误.以下是他们的看法: 保持原创. 一名黑带开发人员解释道,复制别人的成功很容易. 但是,如果您真的希望赚钱,就需要做些其他开发人员没在做的事情. 提前制定您的商业计划. 许多新手开发人员都是等到最后一刻才会规划自己的商业计划和其他商业方面,但这种做法会适得其反.当您的技术专长非常适合

MONGODB全面总结

关于Mongodb的全面总结,学习mongodb的人,可以从这里开始! 分类:            MongoDB2013-06-08 09:5610213人阅读评论(0)收藏举报 目录(?)[+] BSON 效率 传输性 性能 写入协议 数据文件 名字空间和盘区 内存映射存储引擎 其他 MongoDB的架构 MongoDB的特点 MongoDB的功能 MongoDB的局限性与不足 适用范围 MongoDB的不适用范围 要点 MongoDB分布式复制 MongoDB语法与现有关系型数据库SQL

使用Node.js + MongoDB 构建restful API

很多天前已经翻译了一大半了,今天收收尾~ RESTful API With Node.js + MongoDB Translated By 林凌灵 翻译目的:练练手,同时了解别人的思维方式 原文地址:RESTful API With Node.js + MongoDB 12 Sep 2013 我是一名移动应用开发者,我需要某种后端服务用来频繁地处理用户数据到数据库中.当然,我可以使用后端即服务类的网站(Parse, Backendless, 等等-),(译者:国内比较出名的有Bmob).但自己解

mongodb之master/slave模式 + auth

## 主从带认证: 主服务器和从服务器必须开启安全认证:--auth, 主服务器和从服务器的admin数据库中必须有全局用户, 然后主服务器的local数据库和从服务器的local数据均有名为repl且密码相同的用户名. 注:local:本地数据库 这个数据库不会同步,主要存放同步的信息.在MongoDB2.0.2版本测试时,从服务器的admin数据库中没有全局用户时也能进行复制(Deven:我们就是采用这个方式, 从服务器admin数据库没有建立用户),尽管admin中无用户,客户端连接此服务

mongoDB学习笔记<一>

1.find函数的要点和使用 find的介绍与使用 MongoDB数据查询使用find函数,其功能与SQL中的select函数相同,可提供与关系型数据库类似的许多功能,包含映射.排序等. db.集合名.find(query,fields,limit,skip) 主要有四个参数: query:指明查询条件,相当于SQL中的where语句 fields:用于字段映射,指定是否返回该字段,0代表不返回,1代表返回 limit:限制查询的结果集的文档数量,指定查询返回结果集的上限 skip:跳过一定数据

Mongodb聚合操作之读书笔记

Mongodb聚合操作 读书笔记 mongodb,两种计算聚合pipeline和mapreduce pipeline查询速度快于mapreduce,但MapReduce能够在多台Server上并行执行复杂的聚合逻辑. mongodb不允许Pipeline的单个聚合操作占用过多的系统内存,如果一个聚合操作消耗20%以上的内存,那么mongodb直接停止操作,并向客户端输出错误消息. Pipeline方式使用db.collection.aggregate()函数进行聚合运算,运算速度较快,操作简单.

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

这是MongoDB的系列学习笔记的第一篇,主要介绍什么是非关系型数据库MongoDB,如何下载,去哪儿下载,又该怎么正确的安装等一系列问题. 一.前言 最近开始学习非关系型数据库MongoDB,却在博客园上找不到比较系统的教程,很多资料都要去查阅英文网站,效率比较低下.本人不才,借着自学的 机会把心得体会都记录下来,方便感兴趣的童鞋分享讨论.部分资源出自其他博客,旨将零散知识点集中到一起,如果有侵犯您的权利,请联系li- [email protected].大部分内容均系原创,欢迎大家转载分享,