MongoDB磁盘IO问题的3种解决方法

  • A+
所属分类:MongoDB

IO观点

在数据库优化和存储规划进程中,总会提到IO的一些紧张观点,在这里就具体记载一下,对这个观点的认识水平也决议了对数据库与存储优化的懂得水平,以下这些观点并非权势巨子文档,权势巨子水平确定就不克不及说了。

读/写IO,最为常见说法,读IO,便是发指令,从磁盘读取某段扇区的内容。指令一样平常是关照磁盘开端扇区地位,然后给出必要从这个初始扇区今后读取的持续扇区个数,同时给出动作是读,照样写。磁盘收到这条指令,就会依照指令的要求,读或者写数据。节制器发出的这种指令+数据,便是一次IO,读或者写。

年夜/小块IO,指节制器的指令中给出的持续读取扇区数量的若干,假如数量很年夜,好比128,64等等,就应该算是年夜块IO,假如很小,好比1, 4,8等等,就应该算是小块IO,年夜块和小块之间,没有明白的边界。

持续/随机IO,持续和随机,是指本次IO给出的初始扇区地址,和上一次IO的停止扇区地址,是不是完全持续的,或者相隔不多的,假如是,则本次IO应该算是一个持续IO,假如相差太年夜,则算一次随机IO。持续IO,由于本次初始扇区和前次停止扇区相隔很近,则磁头险些不消换道或换道光阴极短;假如相差太年夜,则磁头必要很长的换道光阴,假如随机IO许多,导致磁头不绝换道,效力年夜年夜降底。

次序/并发IO,这个的意思是,磁盘节制器每一次对磁盘组发出的指令套(指完成一个事物所必要的指令或者数据),是一条照样多条。假如是一条,则节制器缓存中的IO行列步队,只能一个一个的来,此时是次序IO;假如节制器可以同时对磁盘组中的多块磁盘,同时发出指令套,则每次就可以执行多个IO,此时便是并发IO模式。并发IO模式进步了效力和速率。

IO并发几率。单盘,IO并发几率为0,由于一块磁盘同时只可以进行一次IO。对付raid0,2块盘环境下,条带深度比拟年夜的时刻(条带太小不克不及并发IO,下面会讲到),并发2个IO的几率为1/2。其他环境请自行运算。

IOPS。一个IO所用的光阴=寻道光阴+数据传输光阴。 IOPS=IO并发系数/(寻道光阴+数据传输光阴),因为寻道光阴相对传输光阴,年夜几个数目级,以是影响IOPS的症结因素,便是降底寻道光阴,而在持续IO的环境下,寻道光阴很短,仅在换磁道时刻必要寻道。在这个条件下,传输光阴越少,IOPS就越高。

每秒IO吞吐量。显然,每秒IO吞吐量=IOPS乘以均匀IO SIZE。 Io size越年夜,IOPS越高,每秒IO吞吐量就越高。设磁头每秒读写数据速率为V,V为定值。则IOPS=IO并发系数/(寻道光阴+IO SIZE/V),代入,得每秒IO吞吐量=IO并发系数乘IO SIZE乘V/(V乘寻道光阴+IO SIZE)。我们可以看出影响每秒IO吞吐量的最年夜因素,便是IO SIZE和寻道光阴,IO SIZE越年夜,寻道光阴越小,吞吐量越高。相比能明显影响IOPS的因素,只有一个,便是寻道光阴。

MongoDB磁盘IO问题的3种办理办法

1.使用组合式的年夜文档

我们知道MongoDB是一个文档数据库,其每一笔记录都是一个JSON格局的文档。好比像下面的例子,每一天会天生一条如许的统计数据:

  { metric: content_count, client: 5, value: 51, date: ISODate(2012-04-01 13:00) }

  { metric: content_count, client: 5, value: 49, date: ISODate(2012-04-02 13:00) }

而假如采纳组合式年夜文档的话,就可以如许将一个月的数据全体存到一笔记录里:

  { metric: content_count, client: 5, month: 2012-04, 1: 51, 2: 49, ... }

经由过程上面两种方式存储,预先一共存储年夜约7GB的数据(机械只有1.7GB的内存),测试读取一年信息,这二者的读机能差异很显著:

  第一种: 1.6秒

  第二种: 0.3秒

  那么问题在哪里呢?

现实上缘故原由是组合式的存储在读取数据的时刻,可以读取更少的文档数目。而读取文档假如不克不及完全在内存中的话,其价值主要是被花在磁盘seek上,第一种存储方式在获取一年数据时,必要读取的文档数更多,以是磁盘seek的数目也越多。以是更慢。

现实上MongoDB的着名使用者foursquare就年夜量采纳这种方式来晋升读机能。

2.采纳特殊的索引布局

我们知道,MongoDB和传统数据库一样,都是采纳B树作为索引的数据布局。对付树形的索引来说,保留热数据使用到的索引在存储上越集中,索引挥霍失落的内存也越小。以是我们对照下面两种索引布局:

采纳这两种分歧的布局,在插入机能上的差异也很显著。

当采纳第一种布局时,数据量在2万万以下时,可以或许根本坚持10k/s 的插入速率,而当数据量再增年夜,其插入速率就会逐步低落到2.5k/s,当数据量再增年夜时,其机能可能会更低。

而采纳第二种布局时,插入速率可以或许根本稳固在10k/s。

其缘故原由是第二种布局将date字段放在了索引的第一位,如许在构建索引时,新数据更新索引时,不是在中央去更新的,只是在索引的尾巴处进行改动。那些插入光阴过早的索引在后续的插入操作中险些不必要进行改动。而第一种环境下,因为date字段不在最前面,以是其索引更新常常是产生在树布局的中央,导致索引布局会常常进行年夜范围的变化。

3.预留空间

与第1点雷同,这一点同样是斟酌到传统机器硬盘的主要操作光阴是花在磁盘seek操作上。

好比照样拿第1点中的例子来说,我们在插入数据的时刻,预先将这一年的数据必要的空间都一次性插入。这能保证我们这一年12个月的数据是在一笔记录中,是次序存储在磁盘上的,那么在读取的时刻,我们可能只必要一次对磁盘的次序读操作就可以或许读到一年的数据,相比前面的12次读取来说,磁盘seek也只有一次。

成果:

  假如不采纳预留空间的方式,读取一年的记载必要62ms

  假如采纳预留空间的方式,读取一年的记载只必要6.6ms

总结

以上便是这篇文章的全体内容了,愿望本文的内容对年夜家的进修或者事情具有必定的参考进修代价,假如有疑问年夜家可以留言交流,谢谢年夜家对剧本之家的支撑。

您可能感兴致的文章:

办理启动MongoDB差错:error while loading shared libraries: libstdc++.so.6:cannot open shared object file:关于Mongodb参数阐明与常见差错处置的总结Mongodb常见差错与办理办法小结(Mongodb中常常呈现的差错)MongoDB差错32-bit servers don''t have journaling enabled by default办理办法办理mongodb在ubuntu下启动失败,提醒couldn‘t remove fs lock errno:9 Bad file descriptor的差错mongodb差错tcmalloc: large alloc out of memory, printing stack and exiting办理方法MongoDB最年夜衔接数设置失效的非常阐发进程与办理办法Win10 安装 MongoDB 3.6.5 失败的问题及办理办法mongodb 3.4下长途衔接认证失败的办理办法MongoDb的"大众not master and slaveok=false"大众差错及办理办法

发表评论

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