第七章 - 性能和工具

2018-02-24 16:17 更新

在這章中,我們來講幾個(gè)關(guān)于性能的話題,以及在 MongoDB 開發(fā)中用到的一些工具。我們不會深入其中的一個(gè)話題,不過我們會指出每個(gè)話題中最重要的方面。

索引(Index)

首先我們要介紹一個(gè)特殊的集合?system.indexes?,它保存了我們數(shù)據(jù)庫中所有的索引信息。索引的作用在 MongoDB 中和關(guān)系型數(shù)據(jù)庫基本一致: 幫助改善查詢和排序的性能。創(chuàng)建索引用?ensureIndex?:

// where "name" is the field name
db.unicorns.ensureIndex({name: 1});

刪除索引用?dropIndex:

db.unicorns.dropIndex({name: 1});

可以創(chuàng)建唯一索引,這需要把第二個(gè)參數(shù)?unique?設(shè)置為?true:

db.unicorns.ensureIndex({name: 1},
    {unique: true});

索引可以內(nèi)嵌到字段中 (再說一次,用點(diǎn)號) 和任何數(shù)組字段。我們可以這樣創(chuàng)建復(fù)合索引:

db.unicorns.ensureIndex({name: 1,
    vampires: -1});

索引的順序 (1 升序, -1 降序) 對單鍵索引不起任何影響,但它會在使用復(fù)合索引的時(shí)候有所不同,比如你用不止一個(gè)索引來進(jìn)行排序的時(shí)候。

閱讀?indexes page?獲取更多關(guān)于索引的信息。

Explain

需要檢查你的查詢是否用到了索引,你可以通過?explain?方法:

db.unicorns.find().explain()

輸出告訴我們,我們用的是?BasicCursor?(意思是沒索引), 12 個(gè)對象被掃描,用了多少時(shí)間,什么索引,如果有索引,還會有其他有用信息。

如果我們改變查詢索引語句,查詢一個(gè)有索引的字段,我們可以看到?BtreeCursor?作為索引被用到填充請求中去:

db.unicorns.find({name: 'Pilot'}).explain()

復(fù)制(Replication)

MongoDB 的復(fù)制在某些方面和關(guān)系型數(shù)據(jù)庫的復(fù)制類似。所有的生產(chǎn)部署應(yīng)該都是副本集,理想情況下,三個(gè)或者多個(gè)服務(wù)器都保持相同的數(shù)據(jù)。寫操作被發(fā)送到單個(gè)服務(wù)器,也即主服務(wù)器,然后從它異步復(fù)制到所有的從服務(wù)器上。你可以控制是否允許從服務(wù)器上進(jìn)行讀操作,這可以讓一些特定的查詢從主服務(wù)器中分離出來,當(dāng)然,存在讀取到舊數(shù)據(jù)的風(fēng)險(xiǎn)。如果主服務(wù)器異常關(guān)閉,從服務(wù)中的一個(gè)將會自動晉升為新的主服務(wù)器繼續(xù)工作。另外,MongoDB 的復(fù)制不在本書的討論范圍之內(nèi)。

分片(Sharding)

MongoDB 支持自動分片。分片是實(shí)現(xiàn)數(shù)據(jù)擴(kuò)展的一種方法,依靠在跨服務(wù)器或者集群上進(jìn)行數(shù)據(jù)分區(qū)來實(shí)現(xiàn)。一個(gè)最簡單的實(shí)現(xiàn)是把所有的用戶數(shù)據(jù),按照名字首字母 A-M 放在服務(wù)器 1 ,然后剩下的放在服務(wù)器 2。謝天謝地,MongoDB 的拆分能力遠(yuǎn)比這種分法要強(qiáng)。分片不在本書的討論范圍之內(nèi),不過你應(yīng)當(dāng)有分片的概念,并且,當(dāng)你的需求增長超過了使用單一副本集的時(shí)候,你應(yīng)該考慮它。

盡管復(fù)制有時(shí)候可以提高性能(通過將長時(shí)間查詢隔離到從服務(wù)器,或者降低某些類型的查詢的延遲),它的主要目的是維護(hù)高可用性。分片是擴(kuò)展 MongoDB 集群的主要方法。把復(fù)制和分片結(jié)合起來實(shí)現(xiàn)可擴(kuò)展和高可用性是禁術(shù)。

狀態(tài)(Stats)

你可以通過?db.stats()?查詢數(shù)據(jù)庫的狀態(tài)?;旧隙际顷P(guān)于數(shù)據(jù)庫大小的信息。你還可以查詢集合的狀態(tài),比如說unicorns?集合,可以輸入?db.unicorns.stats()。基本上都是關(guān)于集合大小的信息,以及集合的索引信息。

分析器(Profiler)

你可以這樣執(zhí)行 MongoDB profiler :

db.setProfilingLevel(2);

啟動之后,我們可以執(zhí)行一個(gè)命令:

db.unicorns.find({weight: {$gt: 600}});

然后檢查 profiler:

db.system.profile.find()

輸出會告訴我們:什么時(shí)候執(zhí)行了什么,有多少文檔被掃描,有多少數(shù)據(jù)被返回。

你要停止 profiler 只需要再調(diào)用一次?setProfilingLevel?,不過這次參數(shù)是?0。指定?1?作為第一個(gè)參數(shù),將會過濾統(tǒng)計(jì)超過 100 milliseconds 的任務(wù). 100 milliseconds 是默認(rèn)的閾值,你可以在第二個(gè)參數(shù)中,指定不同的閾值時(shí)間,以 milliseconds 為單位:

//profile anything that takes
//more than 1 second
db.setProfilingLevel(1, 1000);

備份和還原

在 MongoDB 的?bin?目錄下有一個(gè)可執(zhí)行文件?mongodump?。簡單執(zhí)行?mongodump?會鏈接到 localhost 并備份你所有的數(shù)據(jù)庫到?dump?子目錄。你可以用?mongodump --help?查看更多執(zhí)行參數(shù)。常用的參數(shù)有?--db DBNAME?備份指定數(shù)據(jù)庫和--collection COLLECTIONNAME?備份指定集合。你可以用?mongorestore?可執(zhí)行文件,同樣在?bin?目錄下,還原之前的備份。同樣,?--db?和?--collection?可以指定還原的數(shù)據(jù)庫和/或集合。?mongodump?和?mongorestore?使用 BSON,這是 MongoDB 的原生格式。

比如,來備份我們的?learn?數(shù)據(jù)庫導(dǎo)?backup?文件夾,我們需要執(zhí)行(在控制臺或者終端中執(zhí)行該命令,而不是在 mongo shell 中):

mongodump --db learn --out backup

如果只還原?unicorns?集合,我們可以這樣做:

mongorestore --db learn --collection unicorns \
    backup/learn/unicorns.bson

值得一提的是,?mongoexport?和?mongoimport?是另外兩個(gè)可執(zhí)行文件,用于導(dǎo)出和從 JSON/CSV 格式文件導(dǎo)入數(shù)據(jù)。比如說,我們可以像這樣導(dǎo)出一個(gè) JSON:

mongoexport --db learn --collection unicorns

CSV 格式是這樣:

mongoexport --db learn \
    --collection unicorns \
    --csv --fields name,weight,vampires

注意?mongoexport?和?mongoimport?不一定能正確代表數(shù)據(jù)。真實(shí)的備份中,只能使用?mongodump?和?mongorestore?。 你可以從 MongoDB 手冊中讀到更多的?備份須知?。

小結(jié)

在這章中我們介紹了 MongoDB 的各種命令,工具和性能細(xì)節(jié)。我們沒有涉及所有的東西,不過我們已經(jīng)把常用的都看了一遍。MongoDB 的索引和關(guān)系型數(shù)據(jù)庫中的索引非常類似,其他一些工具也一樣。不過,在 MongoDB 中,這些更易于使用。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號