`
zzc1684
  • 浏览: 1190627 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

三招解决MongoDB的磁盘IO问题

阅读更多

有点标题党的意思,不过下面三招确实比较实用,内容来自Conversocial公司的VP Colin Howe在London MongoDB用户组的一个分享。

 

申请:下面几点并非放四海皆准的法则,具体是否能够使用,还需要根据自己的应用场景和数据特点来决定。

 

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树作为索引的数据结构。对于树形的索引来说,保存热数据使用到的索引在存储上越集中,索引浪费掉的内存也越小。所以我们对比下面两种索引结构:

 

db.metrics.ensureIndex({ metric: 1, client: 1, date: 1})

 

 

db.metrics.ensureIndex({ date: 1, metric: 1, client: 1 })

 

采用这两种不同的结构,在插入性能上的差别也很明显。

 

当采用第一种结构时,数据量在2千万以下时,能够基本保持10k/s 的插入速度,而当数据量再增大,其插入速度就会慢慢降低到2.5k/s,当数据量再增大时,其性能可能会更低。

 

而采用第二种结构时,插入速度能够基本稳定在10k/s。

 

其原因是第二种结构将date字段放在了索引的第一位,这样在构建索引时,新数据更新索引时,不是在中间去更新的,只是在索引的尾巴处进行修改。那 些插入时间过早的索引在后续的插入操作中几乎不需要进行修改。而第一种情况下,由于date字段不在最前面,所以其索引更新经常是发生在树结构的中间,导 致索引结构会经常进行大规模的变化。

 

3.预留空间

 

与第1点相同,这一点同样是考虑到传统机械硬盘的主要操作时间是花在磁盘seek操作上。

 

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

 

db.metrics.insert([
    { metric: 'content_count', client: 3, date: '2012-01', 0: 0, 1: 0, 2: 0, ... }
    { .................................., date: '2012-02', ... })
    { .................................., date: '2012-03', ... })
    { .................................., date: '2012-04', ... })
    { .................................., date: '2012-05', ... })
    { .................................., date: '2012-06', ... })
    { .................................., date: '2012-07', ... })
    { .................................., date: '2012-08', ... })
    { .................................., date: '2012-09', ... })
    { .................................., date: '2012-10', ... })
    { .................................., date: '2012-11', ... })
    { .................................., date: '2012-12', ... })
])

 

结果:

 

  • 如果不采用预留空间的方式,读取一年的记录需要62ms
  • 如果采用预留空间的方式,读取一年的记录只需要6.6ms

来源:www.colinhowe.co.uk

分享到:
评论

相关推荐

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

    磁盘IO是不可避免的,除去减少或延缓磁盘操作,也需要尽量的增强磁盘IO性能和吞吐量。下面这篇文章主要给大家介绍了关于MongoDB磁盘IO问题的3种解决方法,需要的朋友可以参考借鉴,需要的朋友们下面来一起看看吧

    分布式文档存储数据库之MongoDB分片集群的问题

     我们知道数据库服务器一般出现瓶颈是在磁盘io上,或者高并发网络io,又或者单台server的cpu、内存等等一系列原因;于是,为了解决这些瓶颈问题,我们就必须扩展服务器性能;通常扩展服务器有向上扩展和向外扩展;...

    详解MongoDB4.0构建分布式分片群集

    高数据量和吞吐量的数据库应用会对单机的性能造成较大压力,大的查询量会将单机的 CPU 耗尽,大的数据量对单机的存储压力较大,最终会耗尽系统的内存而将压力转移到磁盘 IO 上。 MongoDB 分片是使用多个服务器存储...

    将MongoDB作为Redis式的内存数据库的使用方法

    基本思想 将MongoDB用作内存数据库(in-memory database),也即,根本就不让MongoDB把数据保存到磁盘中的这种用法,引起了越来越多的人的兴趣。...可能你也知道,在99%的情况下,磁盘IO(特别是随机IO

    MongoDB整库备份与还原以及单个collection备份、恢复方法

    mongodump.exe备份的原理是通过一次查询获取当前服务器快照,并将快照写入磁盘中,因此这种方式保存的也不是实时的,因为在获取快照后,服务器还会有数据写入,为了保证备份的安全,同样我们还是可以利用fsync锁使...

    大创经验分享&项目资源&代码程序资源

    网络或磁盘IO全部异步化,以前都是只有mongodb是异步客户端,而redis和oss都是同步请求 对url.py做了重大改变,以前是只有多了一个api,就往url.py里写,弄得后面上百个api很难找到某个 功能高度封装,降低代码耦合...

    Java思维导图xmind文件+导出图片

    Redis缓存与数据库一致性问题解决方案 基于redis实现分布式实战 图解Redis中的AOF和RDB持久化策略的原理 redis读写分离架构实践 redis哨兵架构及数据丢失问题分析 redis Cluster数据分布算法之Hash slot ...

    xiaodi:重庆大学国创创业组优秀项目-笑递

    xiaodi 重庆大学国创创业组优秀...网络或磁盘IO全部异步化,以前都是只有mongodb是异步客户端,而redis和oss都是同步请求 对url.py做了重大改变,以前是只有多了一个api,就往url.py里写,弄得后面上百个api很难找到某

    market-sentiment:收获有关股票的推文并对其评分并放入数据库中进行分析

    市场情绪收获有关股票的推文并对其评分并放入数据库中进行分析示例项目展示了业务逻辑服务器如何不需要对磁盘或网络执行缓慢的输入/输出操作。 架构是这样的: 输入服务器:此服务器接收有关股票的推文,并将它们...

    redis简介_动力节点Java学院整理

    Redis是一个开源的,先进的 key-value 存储可用于构建高性能,可扩展的 Web 应用程序的解决方案。Redis官方网网站是:http://www.redis.io/,如下: Redis 有三个主要使其有别于其它很多竞争对手的特点: Redis是...

Global site tag (gtag.js) - Google Analytics