mongo海量数据生产环境下建索引

来源:互联网 发布:金牛行情分析软件 编辑:程序博客网 时间:2024/06/16 00:41

          一般情况下,在正式环境上建mongo索引,采用在后台建索引的方式来建索引。比如db.collection.ensureIndex({a:1},{background:true})。网上很多人写过类似的blog,这些人描述,后台建索引会比较慢,然后就没有然后了。

简直就是坑啊,这个比较慢,慢的要死。

          说下我的业务场景吧。我做的一个系统,用到了mongodb来存储gps数据的,这些数据的维度无外乎gps经纬度,设备id,创建时间。由于前期没有规划好,建的gps集合,里面建的索引语句为db.collection.ensureIndex({deviceID:1,createTime:1})。系统每天采集各种智能设备的gps数据,所以,对mongo用到的比较多的是插入操作,用户也会偶尔查看他行走的gps路线轨迹,所以,查询也是要满足的。其中由于我们用户的需要,对设备的最后一个gps点的位置查询尤为重要,必须要查得很快。

         就这样的系统,运行几个月之后,产生了近五亿的数据量,这时,我们系统查询一个设备的最后一个gps点的查询变得异常慢(大概数据量在2亿的时候就出现这个问题,但不是很严重)。我在查阅mongo的官方文档之后,我发现,我们之前建的索引根本就没有根据业务需求来建,我们系统本身对那些最新的数据比较感兴趣,查询也是查询最新的gps点或者gps点集合,所以,原先的索引中的createTime的方向就必须是-1,不然,查询时,经过的索引文档就会非常大(自己用mongoexplain()查看测试)。

        明白优化方法之后,我就立马删除生产环境的索引(注意了,我手贱把原先索引删了),就开始按照官方介绍的后台方式来新建索引,建索引语句db.collection.ensureIndex({deviceID:1,createTime:-1},{background:true})。由于是正式环境,所以,我们后台还是会源源不断的接受gps数据。我原本以为,也就三五个小时就建好了。后台,完全乱套了,这个后台索引建了20个小时,还只建了70%,并且后来发现,这个索引增长的速度,比gps集合默认的id索引增长速度都慢了。换句话说说,建索引的速度已经远远小于数据增长速度,什么概念,那就是索引永远建不完了。我懵了,尼玛,被自己搞死了啊~~

         后来,凌晨两点,用户在线量最小的时候,我赌了一把,就是把原先建好的70%的索引删了,采用阻塞方式建索引db.collection.ensureIndex({deviceID:1,createTime:-1})。只花了不到20分钟,14G的索引新建完毕。当然呢,这20分钟的数据,算是损失了,但影响也不太大,毕竟mongodb存的数据,价值不是很大,就是海量而已。以损失20分钟的数据,换取系统以后快速稳定运行,还是非常值的。

最后,说明下,新建索引之后,查询设备最后一个gps点几乎是秒查,我看了explain()语句,查询走索引居然只走了一个文档。下次抽时间了好好研究下mongodb的索引原理。然后写成文章来分享~~

0 0
原创粉丝点击