MongoDB优化心得分享

  • A+
所属分类:MongoDB

这里总结下这段光阴使用mongo的心得,列出了几个必要注意的处所。

1. 体系参数及mongo参数设置

mongo参数主要是storageEngine和directoryperdb,这两个参数一开端不选定后续就无法再变动。

directoryperdb主要是将数据库分文件夹寄存,便利后续的备份及数据迁徙。

storageEngine(存储引擎)默认使用的是MMAPv1,保举使用3.0新参加的引擎wiredTiger。经现实使用wiredTiger占用的磁盘空间是MMAP的1/5,索引年夜小是其1/2,查询速率也进步许多,更紧张的是该引擎提供了document级其余锁,当聚拢插入或更新数据时不必要壅闭读操作了。独一的问题是市道市情上支撑该引擎查询的对象不多,MongoVUE无法查到该引擎存储的聚拢,NosqlManager-mongo可以查到但必要.net情况支撑。小我感到认识下mongo command用mongo shell就足够了,以是照样强烈保举使用wiredTiger引擎。

2. 无需对聚拢进行程度切分

因为之前一直使用关系型数据库,关系型数据库当单表数据量超年夜时常常使用的一直办法是对数据表进行分表。在使用mongo时便很天然的感到这招仍旧有效。因为该体系的分表都是动态天生的,做到后面发现这招对mongo带来的机能晋升远远抵不外维护本钱的增长。

阐发一下关系型数据库分表会进步机能的最年夜缘故原由是许多关系型数据库一张表是一个文件,分表可以避免一个文件过年夜所造成数据提取速率变慢。然则mongo并不是如许存储的,以是这条并不成立了。

用过的都知道mongo对索引的依附异常年夜,假如聚拢不克不及一开端就设计好,那后续索引就得写剧本来创立。这里进献个给mongo年夜表动态创立索引的剧本:

这么看动态创立索引勉强照样可以办理的,然则最坑的一个处所是sharding完全没方法做了。shard必要指定要shard的聚拢和分区键,这个就没法提前动态指定了。以是mongo聚拢不必要做程度切分(至少万万级不必要了,更年夜直接shard失落),只必要按营业离开就可以了。

3. 使用Capped Collection

有人使用mongo做数据缓存,并且是缓存固定数目的数据,仍旧用正常的聚拢,然后按期清算数据。实在这时用capped collection机能会好许多。

4. 临盆情况必定要用副本集

许多人线上情况照样用单机版,固然部署快然则许多mongo天然提供的功效都没有效到像主动故障转移、读写分别,这些对后续体系扩容及机能优化太紧张了。我想会使用mongo的应该是数据量到达必定级别,查询机能会异常紧张,以是强烈建议上线时直接使用副本集。

5. 学会使用explain

之前一直习气用对象来查询,如今发现应该多使用mongo shell敕令来查询,并使用explain查看查询方案。另外在探求最优索引的时刻hint敕令也长短常有效的。

6. 写操作频仍无法使用读写分别

因为体系写操作较多,造成各类w级别锁常常呈现(这种锁一样平常是block read的)并且体系对付数据同等性要求不会太多(年夜多是后台写入,前台读取,是以容许有必定延迟)以是想用副本集来做读写分别。当真正测试后发现副本集上的读取也常常呈现壅闭的环境。经由过程db.currentOp()发现常常呈现一个op:none的操作在申请global write lock,这时所有操作的状况都是在waitingForLock:true,这个问题google了好久都没找到办理办法。后面在官方文档有关并发的FAQ中发现下面这个年夜坑:

How does concurrency affect secondaries?

In replication, MongoDB does not apply writes serially to secondaries.
Secondaries collect oplog entries in batches and then apply those
batches in parallel. Secondaries do not allow reads while applying the
write operations, and apply write operations in the order that they
appear in the oplog.

本来mongodb的副本在复制主节点数据执行oplog的时刻,读取是被壅闭的,这根本宣告无法在副本上去读取数据了,白白消耗了几天精神。以是mongo官方不保举做读写分别,本来坑是在这里。。。实在写多读少的环境做读写分别作用也不年夜,由于机能瓶颈主要是在写入,读取一样平常不用耗若干资本(另外wiredTiger引擎的锁做到了doc级别,以是锁的环境相对较少)。官方保举的做法是shard,可以有用的将写入分派到多台服务器进步写入速率,使体系实现程度扩容。

7、万万不要让磁盘满了

80%的时刻就要开端注意从集拆分片,假如你的数据增加分外快,很可能你还没有拆分磁盘就满了导致MongoDB挂失落了。假如数据量很年夜,只管即便使用分片,不要使用副本集,做好磁盘容量规划,便是使用分片了也提前扩容,究竟chunk迁徙照样那么的慢。

8、平安风险

MongoDB是默认不提醒用户设置暗码的,以是,假如你没有设置装备摆设暗码又把MongoDB放在公网上面了,那么「恭喜」,你可能已经成为了肉鸡

9、数据库级锁

MongoDB的锁机制和一样平常关系数据库如 MySQL(InnoDB), Oracle 有很年夜的差别,InnoDB 和 Oracle 能提供行级粒度锁,而 MongoDB 只能提供 库级粒度锁,这意味着当 MongoDB 一个写锁处于占用状况时,其它的读写操作都得干等。

初看起来库级锁在年夜并发情况下有严重的问题,然则 MongoDB 依然可以或许坚持年夜并发量和高机能,这是由于 MongoDB 的锁粒度固然很粗放,然则在锁处置机制和关系数据库锁有很年夜差别,主要表示在:

•MongoDB 没有完备事务支撑,操作原子性只到单个 document 级别,以是通常操作粒度比拟小;

•MongoDB 锁现实占用光阴是内存数据计算和变革光阴,通常很快;

•MongoDB 锁有一种暂时废弃机制,当呈现必要期待慢速 IO 读写数据时,可以先暂时废弃,等 IO 完成之后再从新获取锁。

通常不出问题不即是没有问题,假如数据操作欠妥,依然会导致永劫间占用写锁,好比下面提到的前台建索引操作,当呈现这种环境的时刻,整个数据库就处于完全壅闭状况,无法进行任何读写操作,环境十分严重。

办理问题的办法,只管即便避免永劫间占用写锁操作,假如有一些聚拢操作其实难以避免,可以斟酌把这个聚拢放到一个零丁的 MongoDB 库里,由于 MongoDB 分歧库锁是互相隔离的,分别聚拢可以避免某一个聚拢操作激发全局壅闭问题。

您可能感兴致的文章:

浅析Mongodb机能优化的相关问题Mongodb索引的优化MongoDB查询机能优化验证及验证MongoDB机能优化及监控若何对 MongoDB 进行机能优化(五个简单步调)

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: