mongo索引构建

声明索引时要当心

因为这个步骤太容易了,因此也很容易在无心间触发索引构建。若是数据集很大,构建会花很长时间。在生产环境里,这简直就是梦魇,由于没办法停止索引构建。若是发生了这种状况,你将不得不故障转移到从节点上——若是有从节点的话。最明智的建议是将索引构建当作某类数据库迁移来看待,确保应用程序的代码不会自动声明索引。数据库

索引的构建分为两步。

第一步,对要索引的值排序。通过排序的数据集在插入到B树时会更高效。注意,排序的进度会以已排序文档数和总文档数的比率来进行显示:性能

[conn1] building new index on { open: 1.0, close: 1.0 } for stocks.values
    1000000/4308303 23%
    2000000/4308303 46%
    3000000/4308303 69%
    4000000/4308303 92%
    Tue Jan 4 09:59:13 [conn1] external sort used : 5 files in 55 secs

第二步,排序后的值被插入索引中。进度显示方式与第一步相同,完成以后,完成索引构建所用的时间会显示出来,做为插入system.indexes的耗时:ui

1200300/4308303 27%
    2227900/4308303 51%
    2837100/4308303 65%
    3278100/4308303 76%
    3783300/4308303 87%
    4075500/4308303 94%
Tue Jan 4 10:00:16 [conn1] done building bottom layer, going to commit
Tue Jan 4 10:00:16 [conn1] done for 4308303 records 118.942secs

还要注意lockType,它说明索引构建用了写锁,也就是说其余客户端此时没法读写数据库。若是发生在生产环境里,这无疑是很糟糕的,这也是长时间索引构建让人抓狂的缘由。code

后台索引

若是是在生产环境里,经不住这样暂停数据库访问的状况,能够指定在后台构建索引。虽然索引构建仍会占用写锁,但构建任务会停下来容许其余读写操做访问数据库。若是应用程序大量使用MongoDB,后台索引会下降性能,但在某些状况下这是可接受的。例如,假设你知道能够在应用程序流量最低的时间窗口内完成索引的构建,那么这时后台索引会是个不错的选择。排序

要在后台构建索引,声明索引时须要指定{background: true}。能够像下面这样在后台构建以前的索引:索引

db.values.ensureIndex({open: 1, close: 1}, {background: true})

离线索引

若是生产数据集太大,没法在几小时内完成索引,这时就须要其余方案了。一般这会涉及让一个副本节点下线,在该节点上构建索引,随后让其上的数据与主节点同步。一旦完成数据同步,将该节点提高为主节点,再让另外一个从节点下线,构建它本身的索引。该策略假设你的复制oplog够大,能避免离线节点的数据在索引构建过程当中变得过旧。下一章会详细讨论复制,应该能帮你计划这样的迁移过程。文档

相关文章
相关标签/搜索