本書分為以下幾個主要部分:第 1-3 章介紹方法和技術。在這些章節(jié)中,我們描述了一種性能調優(yōu)方法。還提供了一些關于 MongoDB 架構和 MongoDB 提供的用于調查、監(jiān)控和診斷 MongoDB 性能的工具的背景知識。第 4 章和第 5 章介紹應用程序和數(shù)據(jù)庫設計。第 6-10 章介紹應用程序代碼的優(yōu)化。第 11-14 章討論MongoDB 服務器及其運行硬件的優(yōu)化。
當MongoDB于2009年出現(xiàn)時,數(shù)據(jù)庫技術正處于十字路口。20多年來,Oracle、SQL Server和MySQL等關系數(shù)據(jù)庫一直主導著數(shù)據(jù)庫市場。這些數(shù)據(jù)庫與關系數(shù)據(jù)模型、SQL語言和“ACID”事務,一起成為改變現(xiàn)代商業(yè)應用程序的基礎,推動了互聯(lián)網(wǎng)革命。但到了2005年左右,關系數(shù)據(jù)庫顯然無法滿足Web應用程序的永遠在線、全球可擴展的新型需求。這些“Web 2.0”應用程序需要新的數(shù)據(jù)庫管理系統(tǒng)。
到2010年,出現(xiàn)了大量非關系型“NoSQL”系統(tǒng)—Hadoop、HBase、Cassandra等。在這些非關系型“新貴”中,MongoDB幾乎是最成功的。在撰寫本文時,MongoDB是排名前五的數(shù)據(jù)庫管理系統(tǒng)之一。在前五名中,只有MongoDB基于21世紀的技術,其他4個(Oracle、MySQL、SQL Server和Postgres)都起源于20世紀80年代和90年代。
MongoDB的成功可以歸因于許多因素,例如,遵循面向對象的編程范式以及與現(xiàn)代DevOps實踐的兼容性?偟膩碚f,MongoDB之所以蓬勃發(fā)展,是因為它讓開發(fā)人員更輕松。然而,在過去幾年中,我們已經(jīng)看到MongoDB從“由開發(fā)人員為開發(fā)人員服務”的數(shù)據(jù)庫升級為支持新一代關鍵任務系統(tǒng)的平臺,適用于越來越廣泛的企業(yè)。
隨著MongoDB的成熟以及在企業(yè)應用上的擴展,性能管理變得越來越重要。眾所周知,性能不佳的客戶應用程序對于當今的在線企業(yè)來說可能是致命的。例如,當網(wǎng)頁的加載時間從1s增加到5s時,用戶放棄瀏覽該頁面的概率會增加90%,這會直接影響在線收入。由于數(shù)據(jù)庫執(zhí)行大量的磁盤IO操作和數(shù)據(jù)處理,因此數(shù)據(jù)庫通常是導致性能不佳的根本原因。
此外,在云中,性能管理就是成本管理:性能不佳的數(shù)據(jù)庫會消耗不必要的CPU、內存和IO資源,而這些資源需要支付費用;◣滋鞎r間調優(yōu)基于MongoDB的大型云應用程序可能會節(jié)省數(shù)十萬美元的托管費用。
事實上,我們甚至可以說性能管理是出于對環(huán)境的考慮。為繁忙的數(shù)據(jù)庫服務器供電不僅耗費金錢,還會產(chǎn)生溫室氣體。減少家庭能源消耗是一項社會責任,降低數(shù)據(jù)中心的能耗也同樣重要。調優(yōu)不當?shù)腗ongoDB數(shù)據(jù)庫就像調優(yōu)不當?shù)钠,會適得其反:它可以讓你從A到B,但會花費更多的汽油,并對環(huán)境造成更嚴重的損害。
我們試圖制作一本連貫而全面的MongoDB調優(yōu)手冊,本書就是一次嘗試。為此,我們制定了以下目標:
為MongoDB性能調優(yōu)提供一種方法論,系統(tǒng)而有效地解決性能問題。特別是,這種方法論試圖先于癥狀來定位原因。
解決MongoDB性能管理各方面的問題,從數(shù)據(jù)庫設計到應用程序代碼的調整,再到服務器和集群優(yōu)化。
高度關注調優(yōu)相關的基本技能。基本技能是顯著提升性能不可或缺的能力,如果不能很好地掌握,則通常會限制由應用先進技術而獲得的好處。
本書結構
本書分為以下幾個主要部分:
第1~3章介紹方法和工具。在這幾章中,我們描述了一種性能調優(yōu)方法論,它為調優(yōu)MongoDB數(shù)據(jù)庫提供了最有效的手段。我們還提供了一些關于MongoDB架構和工具的背景知識,這些工具是MongoDB提供的,用于調查、監(jiān)控和診斷MongoDB的性能。
第4章和第5章介紹應用程序和數(shù)據(jù)庫設計。在這里,我們介紹了開發(fā)高效文檔模型和為MongoDB集合建立索引的基礎知識。
第6~10章介紹應用程序代碼的優(yōu)化。調整應用程序代碼通?梢燥@著提升數(shù)據(jù)庫性能,并且這應該在調整服務器或集群配置之前解決。我們將研究如何優(yōu)化MongoDB的f?ind()語句、聚合管道和數(shù)據(jù)操作語句。
第11~14章討論MongoDB服務器及其運行硬件的優(yōu)化。我們將解釋如何優(yōu)化內存以避免IO、如何優(yōu)化無法阻止的IO,以及如何配置高效的MongoDB集群。
讀者對象
本書適用于對提高MongoDB數(shù)據(jù)庫性能或提高依賴該數(shù)據(jù)庫的應用程序的性能感興趣的人,包括應用程序架構師、開發(fā)人員和數(shù)據(jù)庫管理員。
盡管本書提出了一種連貫且符合邏輯的數(shù)據(jù)庫調優(yōu)方法,但并非本書的所有部分都對所有讀者有同樣的吸引力。例如,開發(fā)人員可能會發(fā)現(xiàn)應用程序代碼部分比IO優(yōu)化部分對他更有幫助。同樣,無法訪問應用程序代碼的數(shù)據(jù)庫管理員可能會發(fā)現(xiàn)服務器優(yōu)化部分更有用。
每個讀者都可以選擇跳過自己不感興趣的內容。然而,我們要強調的是,本書主張的是在緩解癥狀之前定位性能問題的根本原因。在使用后面章節(jié)(例如第12章)中的方法時,我們假設你已經(jīng)執(zhí)行了前面章節(jié)(例如第5章)中概述的處理方法。
我們希望這本書適合那些對MongoDB數(shù)據(jù)庫比較陌生的人閱讀,所以也簡要地解釋了關鍵概念和MongoDB架構。但前提是你對MongoDB和JavaScript編程語言有一定的了解。
腳本和示例數(shù)據(jù)
本書使用各種腳本來報告MongoDB的性能。所有這些腳本都可以在GitHub上找到,網(wǎng)址為https://github.com/gharriso/MongoDBPerformanceTuningBook。
主腳本mongoTuning.js提供從MongoDB shell會話中訪問所有這些腳本的權限。要在MongoDB shell中使用這些腳本,只需以腳本名稱為參數(shù)發(fā)出Mongo命令并添加--shell選項即可,例如:
這些示例也可以在GitHub存儲庫中的examples文件夾下找到。這些示例使用的數(shù)據(jù)以壓縮轉儲文件的形式存儲在sampleData文件夾中。有關如何加載數(shù)據(jù)的說明詳見同一文
件夾。
譯者序
前言
致謝
審校者簡介
第一部分 方法和工具
第1章性能調優(yōu)方法 2
1.1 警示故事 2
1.2 對癥性能調優(yōu) 3
1.3 系統(tǒng)性能調優(yōu) 3
1.3.1 數(shù)據(jù)庫請求剖析 3
1.3.2 MongoDB數(shù)據(jù)庫的層次 4
1.4 小化應用程序工作負載 5
1.5 減少物理IO 6
1.6 優(yōu)化磁盤IO 6
1.7 集群調優(yōu) 7
1.8 小結 7
第2章MongoDB架構與概念 8
2.1 MongoDB文檔模型 8
2.1.1 JSON 9
2.1.2 二進制JSON 9
2.1.3 集合 9
2.1.4 MongoDB schema 9
2.2 MongoDB協(xié)議 12
2.2.1 有線協(xié)議 12
2.2.2 MongoDB驅動程序 12
2.3 MongoDB命令 13
2.3.1 查找命令 13
2.3.2 聚合命令 14
2.3.3 數(shù)據(jù)操作命令 15
2.4 一致性機制 15
2.4.1 讀取策略與寫入策略 15
2.4.2 事務 16
2.5 查詢優(yōu)化 16
2.6 MongoDB架構 17
2.6.1 mongod 17
2.6.2 存儲引擎 17
2.6.3 副本集 18
2.6.4 分片 19
2.6.5 分片機制 19
2.6.6 集群平衡 20
2.7 小結 20
第3章行業(yè)工具 21
3.1 explain() 21
3.1.1 開始使用explain() 22
3.1.2 替代計劃 24
3.1.3 執(zhí)行統(tǒng)計信息 25
3.1.4 使用explain()來調優(yōu)查詢 26
3.1.5 可視化解釋函數(shù)的使用方法 28
3.2 查詢剖析器 29
3.2.1 system.prof?ile集合 30
3.2.2 分析剖析數(shù)據(jù) 31
3.3 使用MongoDB日志進行調優(yōu) 33
3.4 服務器統(tǒng)計信息 35
3.5 檢查當前操作 38
3.6 操作系統(tǒng)監(jiān)控 41
3.7 MongoDB Compass 42
3.8 小結 43
第二部分 應用程序與數(shù)據(jù)庫設計
第4章schema建!46
4.1 指導原則 46
4.2 鏈接與嵌入 47
4.2.1 案例研究 47
4.2.2 獲取客戶的所有數(shù)據(jù) 50
4.2.3 獲取所有未結訂單 51
4.2.4 熱門產(chǎn)品 52
4.2.5 插入新訂單 53
4.2.6 更新產(chǎn)品 54
4.2.7 刪除客戶 54
4.2.8 案例研究總結 55
4.3 高級模式 56
4.3.1 子集化 56
4.3.2 垂直分區(qū) 58
4.3.3 屬性模式 58
4.4 小結 60
第5章索引 61
5.1 B樹索引 61
5.1.1 索引選擇性 62
5.1.2 唯一索引 63
5.1.3 索引掃描 63
5.1.4 不區(qū)分大小寫的搜索 64
5.2 復合索引 65
5.2.1 復合索引性能 66
5.2.2 復合索引鍵順序 66
5.2.3 復合索引指南 67
5.2.4 覆蓋索引 67
5.3 索引合并 68
5.4 局部索引和稀疏索引 68
5.4.1 局部索引 69
5.4.2 稀疏索引 69
5.5 使用索引進行排序和連接 70
5.5.1 排序 70
5.5.2 連接 70
5.6 索引開銷 70
5.7 文本索引 73
5.8 地理空間索引 78
5.8.1 地理空間索引性能 81
5.8.2 地理空間索引限制 81
5.9 小結 82
第三部分 MongoDB代碼調優(yōu)
第6章查詢調優(yōu) 84
6.1 緩存結果 84
6.2 優(yōu)化網(wǎng)絡往返 86
6.2.1 投影 86
6.2.2 批處理 87
6.2.3 在代碼中避免過多的
網(wǎng)絡往返 88
6.2.4 批量插入 90
6.2.5 應用程序架構 90
6.3 選擇索引與選擇掃描 90
6.4 優(yōu)化排序操作 93
6.5 選擇或創(chuàng)建正確的索引 95
6.6 過濾策略 97
6.6.1 不等條件 97
6.6.2 范圍查詢 99
6.6.3 $OR或$IN操作 100
6.6.4 數(shù)組查詢 101
6.6.5 正則表達式 102
6.6.6 $exists查詢 103
6.7 優(yōu)化集合掃描 105
6.8 小結 105
第7章調優(yōu)和利用聚合管道 106
7.1 調優(yōu)聚合管道 106
7.1.1 優(yōu)化聚合排序 109
7.1.2 自動管道優(yōu)化 111
7.2 優(yōu)化多集合連接 113
7.2.1 連接順序 115
7.2.2 優(yōu)化圖查找 116
7.3 聚合內存利用 118
7.4 在聚合管道中排序 119
7.4.1 索引聚合排序 119
7.4.2 磁盤排序 121
7.5 優(yōu)化視圖 122
7.6 小結 126
第8章插入、更新和刪除 127
8.1 基礎知識 127
8.1.1 過濾器優(yōu)化 127
8.1.2 解釋數(shù)據(jù)操作語句 128
8.1.3 索引開銷 128
8.1.4 找到未使用的索引 129
8.1.5 寫入策略 130
8.2 插入 130
8.2.1 批處理 130
8.2.2 克隆數(shù)據(jù) 132
8.2.3 從文件加載 134
8.3 更新 134
8.3.1 動態(tài)值批量更新 134
8.3.2 multi:true標志 135
8.3.3 upsert 136
8.3.4 使用$merge的批量upsert 137
8.4 刪除 138
8.5 小結 138
第9章事務 139
9.1 事務理論 139
9.2 MongoDB事務 140
9.2.1 事務限制 141
9.2.2 TransientTransactionError 141
9.2.3 MongoDB驅動程序中的事務 143
9.2.4TransientTransactionError對
性能的影響 145
9.3 事務優(yōu)化 146
9.3.1 避免事務 146
9.3.2 操作順序 148
9.3.3 對熱文檔分區(qū) 149
9.4 小結 150
第10章服務器監(jiān)控 152
10.1 主機級監(jiān)控 152
10.1.1 網(wǎng)絡 153
10.1.2 CPU 155
10.1.3 內存 156
10.1.4 磁盤IO 156
10.2 MongoDB服務器監(jiān)控 156
10.2.1 Compass 156
10.2.2 Free Monitoring服務 157
10.2.3 Ops Manager 158
10.2.4 MongoDB Atlas 158
10.2.5 第三方監(jiān)控工具 160
10.3 小結 160
第四部分 服務器調優(yōu)
第11章內存調優(yōu) 162
11.1 MongoDB內存架構 162
11.1.1 主機內