溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

詳細(xì)介紹MongoDB

發(fā)布時間:2020-05-27 16:06:47 來源:億速云 閱讀:586 作者:鴿子 欄目:軟件技術(shù)

一、概述

(1)版本歷程

  • 0.x 起步節(jié)點
  • 1.x 支持復(fù)制集和分片
  • 2.x 更加豐富的數(shù)據(jù)庫功能
  • 3.x 合并了一家專門做數(shù)據(jù)庫引擎的Wired Tiger公司,更加完善的周邊生態(tài)環(huán)境
  • 4.x 支持分布式事務(wù)

MongoDB的正式版本都是偶數(shù)版本,x.x.x,主要版本(x.x)大約每年升級一次,小版本主要是修復(fù)問題,通常1-2個月發(fā)布一次。

MongoDB支持原生高可用:Application通過Driver連接到Primary節(jié)點,一個Primary節(jié)點連接多個Secondary節(jié)點。

MongoDB支持水平擴(kuò)展,分片集群:Driver連接多個Mongos,Mongos連接多個Shard,每個Shard都是一個Primary和多個Secondary。

詳細(xì)介紹MongoDB

二、復(fù)制集

主要用于實現(xiàn)服務(wù)的高可用

(1)特征

MongoDB的復(fù)制集主要具備如下特征:

  • 快速復(fù)制:數(shù)據(jù)寫入時將數(shù)據(jù)迅速復(fù)制到另一個節(jié)點。
  • 故障轉(zhuǎn)移:在接受寫入的節(jié)點發(fā)生故障的時候自動選擇另一個新的節(jié)點代替。
  • 其他作用:數(shù)據(jù)分發(fā)、讀寫分離、異地容災(zāi)。

(2)MongoDB的數(shù)據(jù)復(fù)制原理

  • 一個修改操作會被記錄到oplog,有一個線程監(jiān)聽oplog,如果有變動就會將這個變動應(yīng)用到其他的數(shù)據(jù)庫上。
  • 從節(jié)點在主節(jié)點上打開一個tailable游標(biāo),不斷獲取新加入的oplog,并在從庫上回放。

(3)節(jié)點間選舉

  • 一個典型的復(fù)制集由3個以上具有投票權(quán)的節(jié)點構(gòu)成,一個Primary接受寫入操作和選舉時投票,兩個Secondary復(fù)制Primary節(jié)點數(shù)據(jù)和選舉時投票。

  • 具有投票權(quán)的節(jié)點兩兩發(fā)送心跳數(shù)據(jù),主節(jié)點5次沒有收到心跳被定義為失聯(lián)狀態(tài)。然后MongoDB基于Raft協(xié)議進(jìn)行選舉。
  • Replica Set中最多50個節(jié)點,具有投票權(quán)的節(jié)點最多只有7個。
  • 影響選舉的因素:整個集群必須有大多數(shù)節(jié)點存活。
  • 被選舉為主節(jié)點的條件
    • 能夠與多數(shù)節(jié)點建立連接
    • 具有較新的oplog
    • 具有較高的優(yōu)先級(可以配置)
  • 常用的配置選項
    • 是否具有投票權(quán)(v參數(shù)):有就會參與投票。
    • 優(yōu)先級(priority參數(shù)):優(yōu)先級越高的節(jié)點越優(yōu)先稱為主節(jié)點。優(yōu)先級為0的節(jié)點無法成為主節(jié)點。
    • 隱藏(hidden參數(shù)):復(fù)制數(shù)據(jù),但是對應(yīng)用不可見。隱藏節(jié)點具有投票權(quán),但是優(yōu)先級必須為0。
    • 延遲(slaveDelay參數(shù)):復(fù)制N秒之前的數(shù)據(jù),報紙與主節(jié)點的時間差。
  • 復(fù)制集的部署事項:主從數(shù)據(jù)庫配置一樣,硬件具有獨立性,軟件版本一致。

三、分片集群

詳細(xì)介紹MongoDB

(1)mongos路由節(jié)點

  • 提供集群的單一入口
  • 轉(zhuǎn)發(fā)應(yīng)用端請求
  • 選擇合適的數(shù)據(jù)節(jié)點進(jìn)行讀寫
  • 合并多個數(shù)據(jù)額節(jié)點的返回結(jié)果
  • 無狀態(tài)
  • 至少有兩個mongos節(jié)點

(2)config配置目錄節(jié)點

  • 提供集群元數(shù)據(jù)的存儲,分片數(shù)據(jù)分布的映射

(3)數(shù)據(jù)節(jié)點

  • 以復(fù)制集為單位
  • 橫向擴(kuò)展
  • 最大1024個分片
  • 分片之間數(shù)據(jù)不能重復(fù)
  • 所有分片在一起才可以完成工作

(4)特點

  • 對應(yīng)用全透明,無須特殊處理
  • 數(shù)據(jù)自動均衡
  • 動態(tài)擴(kuò)容,無須下線
  • 提供三種分片方式

(5)分片集群的3中方式

  • 基于范圍:片鍵范圍查詢性能好,優(yōu)化讀,數(shù)據(jù)分布可能不均勻,容易產(chǎn)生熱點。
  • 基于Hash:數(shù)據(jù)分布均勻,寫優(yōu)化,范圍查詢效率低,適用于日志,物聯(lián)網(wǎng)高并發(fā)場景。
  • 基于Zone:按照地域、時效等屬性分為多個Zone。一個集合(collection)中的所有的對象都被存放到一個塊(chunk)中,默認(rèn)塊的大小是 64MB。當(dāng)數(shù)據(jù)容量超過64 MB,才有可能實施一個遷移

(6)合理的架構(gòu)

  • 一個分片不超過3TB,盡量保證在2TB。常用索引必須容納進(jìn)內(nèi)存。

  • 需要多少個分片?

    分片數(shù)量=max(所需存儲容量/單節(jié)點掛載容量, 工作集大小/單服務(wù)器內(nèi)存容量0.6, 并發(fā)總量/單節(jié)點并發(fā)量0.7)

  • 如何選擇片鍵?

    • 基數(shù),基數(shù)越大越好,比如百家姓要比年齡基數(shù)大。
    • 寫分布,數(shù)據(jù)分布不均勻,比如學(xué)生的年齡。
    • 定向性,mongos可以直接將數(shù)據(jù)定位。

四、災(zāi)備與恢復(fù)

(1)備份

mongodump -h HostName:Port -d DatabaseName -c CollectionName

使用--oplog參數(shù)實現(xiàn)增量備份。復(fù)制從mongodump從開始執(zhí)行到完成所有的oplog。會輸出到dump/oplog.bson文件。

(2)恢復(fù)

mongostore -h HostName:port -d DatabaseName -c CollectionName Filename.bson

使用--oplogReplay參數(shù)實現(xiàn)增量恢復(fù)。通過—-oplogLimit參數(shù)和--oplogFile參數(shù)實現(xiàn)特定時間點的恢復(fù)。

在分片集群的備份中,多個分片可能在發(fā)生數(shù)據(jù)遷移和均衡,導(dǎo)致備份的數(shù)據(jù)發(fā)生錯亂,可以通過停止均衡器解決。

(3)備份方案

  • 延遲節(jié)點備份
  • 全量備份+OpLog增量備份
    • mongodump
    • 復(fù)制數(shù)據(jù)文件
    • 文件系統(tǒng)快照

五、事務(wù)支持

(1)寫事務(wù)

writeConcern參數(shù):決定一個寫操作落到多少個節(jié)點上才算成功。

  • w參數(shù):
    • 1:默認(rèn),要求寫操作已經(jīng)傳播到獨立的mongo實例或者副本集的Primary成員。
    • 0:不要求確認(rèn)寫操作。
    • majority:要求寫操作已經(jīng)傳播到大多數(shù)具有存儲數(shù)據(jù)且具有投票權(quán)的成員。
  • j參數(shù):
    • true:寫操作落到journal算成功。
    • false:寫操作落到內(nèi)存算成功。

(2)讀事務(wù)

  • 從哪里讀?位置
    • readPreference參數(shù)控制,取值如下:
    • Primary(默認(rèn)):主節(jié)點,一般用戶下訂單
    • PrimaryPrefered:主節(jié)點優(yōu)先,一般用戶查訂單。
    • Secondary:從節(jié)點,一般用于報表。
    • SecondaryPrefered:優(yōu)先從節(jié)點。
    • nearest:就近原則,由PingTime決定,一般用于上傳圖片分發(fā)到全球。
    • 結(jié)合使用Tag定向某些節(jié)點:通過指定{"purpose": ""}實現(xiàn)。
  • 什么樣的數(shù)據(jù)可以讀?隔離性
    • readConcern參數(shù)控制,取值如下:
    • avaliable:讀取所有可用的數(shù)據(jù)。
    • local(默認(rèn)):讀取所有可用并且屬于當(dāng)前分片的數(shù)據(jù)。
    • majority:讀取大多數(shù)節(jié)點上提交完成的數(shù)據(jù),防止臟讀。
      • 實現(xiàn)機(jī)制:節(jié)點使用MVCC機(jī)制維護(hù)多個版本,每個大多數(shù)節(jié)點確認(rèn)過的版本數(shù)據(jù)作為一個快照,MongoDB通過維護(hù)多個快照實現(xiàn)鏈接不同的版本,快照維持在不再使用。
    • linearizable:線性化讀取文檔,保證之前所有寫入的,能夠保證出現(xiàn)網(wǎng)絡(luò)分區(qū)的時候讀取的安全,因為在讀取的時候會檢查所有節(jié)點。
    • snapshot:讀取最近快照中的數(shù)據(jù)。
    • 如何安全的讀寫?
    • readConcern設(shè)置為majority
    • writeConcern設(shè)置為majority

(3)多文檔事務(wù)MongoDB的ACID

  • A=4.0版本的復(fù)制集多表多行,4.2版本的分片集群多表多行,1.0版本的單表單文檔
  • C=writeConcern和readConcern。
  • I=readConcern。
  • D=Journal和Replication。

(4)ChangeStream

用于追蹤變更,類似于觸發(fā)器,基于oplog實現(xiàn),返回的_id可用于斷點恢復(fù),有個cursor進(jìn)行追蹤,推送majority條件的變更。

  • 應(yīng)用程序可以實時的了解數(shù)據(jù)的變化。
  • 復(fù)制協(xié)議版本必須是1且使用WT存儲引擎
  • 只有副本集和Shard可用。
  • 使用MongoDB Driver3.6,并且必須開啟3.6版本特性參數(shù)featureCompatibilityVersion。writeConcern必須配置。
  • ChangeStream與觸發(fā)器的異同點:
    • ChangeStream是異步的,基于事件回調(diào)機(jī)制。
    • ChangeStream每個客戶端都會生效一次。
    • ChangeStream支持斷點,觸發(fā)器只能事務(wù)回滾。
  • 應(yīng)用場景:
    • 跨集群復(fù)制
    • 微服務(wù)聯(lián)動
  • ChangeStream的中斷事件不能超過oplog的回收時間。

六、面試題

MongoDB的優(yōu)勢?

  • 面向Collection和Document,以JSON格式保存數(shù)據(jù),支持二進(jìn)制數(shù)據(jù)和大型對象。
  • 高性能,支持Document嵌入,減少了數(shù)據(jù)庫上的IO操作,基于具有完整的索引支持,支持快速查詢。
  • 高可用,復(fù)制集,提供自動故障轉(zhuǎn)移。
  • 高可擴(kuò)展,分片集群。
  • 支持聚合管道和全文索引。
  • 支持插件式存儲引擎,WiredTiger存儲引擎和in-memory存儲引擎。

  • MongoDB支持的數(shù)據(jù)類型:

    • 類似于Java中的:String(UTF-8編碼才是合法的)、Integer、Double、Boolean、Arrays、Datetime。
    • 特有的:ObjectId(用于存儲文檔ID,ObjectId基于分布式主鍵實現(xiàn)MongoDB分片也可用)、Min/Max Keys(將一個值與BSON元素最低值和最高值比較)、Code(JavaScript代碼)、Regular Expression(正則表達(dá)式)、Binary Data(二進(jìn)制數(shù)據(jù))、Null(空值)、Object(內(nèi)嵌的文檔)。

什么是mongod,默認(rèn)參數(shù)有哪些?

  • mongod是處理MongoDB系統(tǒng)的主要進(jìn)程,默認(rèn)參數(shù)有--dbpath=/data/db,--port=27017

MySQL和MongoDB的區(qū)別:

  • MongoDB是非關(guān)系型數(shù)據(jù)庫
  • MySQL采用虛擬內(nèi)存+持久化的方式
  • MySQL使用傳統(tǒng)的SQL語句方式
  • MongoDB常見的架構(gòu)有副本集和分片集群,MySQL有MS、MHA、MMM等架構(gòu)
  • MongoDB基于內(nèi)存,將熱數(shù)據(jù)存儲在物理內(nèi)存,從而實現(xiàn)數(shù)據(jù)告訴讀寫,MySQL每個存儲引擎都有自己的特點。

更新操作會立刻fsync到磁盤?

  • 不會,磁盤寫操作默認(rèn)延遲執(zhí)行,寫操作可能在2~3s內(nèi)落到磁盤,可以通過syncPeriodSecs參數(shù)配置。

MongoDB支持的索引類型?

  • 單字段索引
  • 復(fù)合索引
  • 多鍵索引
  • 全文索引
  • Hash索引
  • 通配符索引
  • 2d sphere索引

MongoDB在A:{B,C}上建立索引,查詢A:{B,C}和A:{C,B}都會使用索引嗎?

由于MongoDB索引使用B-tree樹原理,只會在A:{B,C}上使用索引。

如果塊移動操作(moveChunk)失敗了,我需要手動清除部分轉(zhuǎn)移的文檔嗎?

不需要,移動操作是一致并且是確定的。一次失敗后,移動操作會不斷重試。當(dāng)完成后,數(shù)據(jù)只會出現(xiàn)在新的分片里。

數(shù)據(jù)在什么時候才會擴(kuò)展到多個分片里?

MongoDB 分片是基于區(qū)域(range)的。所以一個集合(collection)中的所有的對象都被存放到一個塊(chunk)中,默認(rèn)塊的大小是 64Mb。當(dāng)數(shù)據(jù)容量超過64 Mb,才有可能實施一個遷移,只有當(dāng)存在不止一個塊的時候,才會有多個分片獲取數(shù)據(jù)的選項。

更新一個正在被遷移的塊(Chunk)上的文檔時會發(fā)生什么?

更新操作會立即發(fā)生在舊的塊(Chunk)上,然后更改才會在所有權(quán)轉(zhuǎn)移前復(fù)制到新的分片上。

如果一個分片(Shard)停止或很慢的時候,發(fā)起一個查詢會怎樣?

如果一個分片停止了,除非查詢設(shè)置了 “Partial” 選項,否則查詢會返回一個錯誤。如果一個分片響應(yīng)很慢,MongoDB 會等待它的響應(yīng)。

什么是Arbiter?

仲裁節(jié)點不維護(hù)數(shù)據(jù)集。 仲裁節(jié)點的目的是通過響應(yīng)其他副本集節(jié)點的心跳和選舉請求來維護(hù)副本集中的仲裁。

復(fù)制集節(jié)點類型有哪些?

  • 優(yōu)先級0型(Priority 0)節(jié)點
  • 隱藏型(Hidden)節(jié)點
  • 延遲型(Delayed)節(jié)點
  • 投票型(Vote)節(jié)點以及不可投票節(jié)點

七、應(yīng)用案例

(1)MongoDB典型的應(yīng)用場景

MongoDB是OLTP數(shù)據(jù)庫,原則上MySQL和Oracle能做的事情,MongoDB也都可以。MongoDB具有原生的橫向擴(kuò)展能力,靈活的模型支持,適合快速開發(fā)迭代,數(shù)據(jù)模型多變的場景,并且MongoDB使用了JSON數(shù)據(jù)結(jié)構(gòu),非常適合微服務(wù)領(lǐng)域。

基于功能的選擇

MongoDB傳統(tǒng)關(guān)系型數(shù)據(jù)庫
億級以上的數(shù)據(jù)量支持Easy分庫分表
靈活的表結(jié)構(gòu)Easy數(shù)據(jù)字典,關(guān)聯(lián)查詢
高并發(fā)讀EasyHard
高并發(fā)寫EasyHard
跨地區(qū)的集群EasyHard
數(shù)據(jù)分片Easy中間件
地址位置查詢完整支持PostGreSQL還可以,其他的很麻煩
聚合計算EasyGroupBY,復(fù)雜的SQL
異構(gòu)數(shù)據(jù)Easy數(shù)據(jù)字典,關(guān)聯(lián)查詢
大、寬表Easy性能局限

基于場景的選擇

  • 移動端應(yīng)用、小程序

    場景特點:基于RESTful API,快速迭代,數(shù)據(jù)結(jié)構(gòu)頻繁變化,大部分功能基于地理信息,爆發(fā)式的增長,高可用

    業(yè)界案例:Keep(說實在的, 健身還不如專門請個私教單獨一對一),摩拜單車,ADP

  • 電商的海量商品數(shù)據(jù)

    場景特點:商品信息包羅萬象,數(shù)據(jù)庫模式設(shè)計困難

    業(yè)界案例:京東商城,小紅書,GAP

  • 內(nèi)容管理:

    場景特點:內(nèi)容數(shù)據(jù)多樣,擴(kuò)展困難

    業(yè)界案例:Adobe AEM,SiteCore

  • 物聯(lián)網(wǎng)IoT

    場景特點:傳感器數(shù)據(jù)結(jié)構(gòu)往往是半結(jié)構(gòu)化數(shù)據(jù),傳感器實時采集的數(shù)據(jù)量巨大,容易增長到百億級別

    業(yè)界案例:華為、Bosch、MindSphere

  • SaaS應(yīng)用

    場景特點:多租戶模式,需求多變,數(shù)據(jù)增長快

    業(yè)界案例:ADP、Teambition

  • 主機(jī)分流

    場景特點:高性能查詢,實時同步機(jī)制

    業(yè)界案例:金融行業(yè)

  • 實時在線分析

    場景特點:流數(shù)據(jù)計算,快速計算,秒級響應(yīng)

    業(yè)界案例:MongoDB緩存機(jī)制、MongoDB聚合框架、微分片架構(gòu)

  • 關(guān)系型遷移到MongoDB承載更多的數(shù)據(jù)和并發(fā)

    場景特點:數(shù)據(jù)增長導(dǎo)致性能低,分庫分表方案復(fù)雜

    業(yè)界案例:頭條、網(wǎng)易、百度、東航、中行

(2)MongoDB對接MySQL、Oracle

從傳統(tǒng)的關(guān)系型數(shù)據(jù)庫遷移到MongoDB需要綜合考慮的幾個問題:

  • 總體架構(gòu)

    • 運維工具、腳本
    • 權(quán)限設(shè)置
    • 分布式
    • 監(jiān)控
    • 備份恢復(fù)
  • 模式設(shè)計

    表結(jié)構(gòu)整合為JSON文檔

  • SQL語句/存儲過程/ORM層

    原始SQL

    存儲過程特性

    ORM框架

  • 數(shù)據(jù)遷移

    數(shù)據(jù)遷移的幾個方式:

    (1)數(shù)據(jù)庫導(dǎo)出導(dǎo)入,導(dǎo)出JSON或者CSV

    (2)ETL批量遷移工具,Kettle、Talend

    (3)實時同步工具,infomatica、Tapdata(會運行一個Agent),一般是解析日志模式

    (4)應(yīng)用主動遷移

(3)MongoDB與Spark

MongoDB作為Spark的存儲方案,MongoDB相比HDFS更加細(xì)粒度存儲,并且支持結(jié)構(gòu)化存儲。MongoDB支持索引機(jī)制,使得Spark的讀取更加快速,HDFS是一次寫,多次讀,但是MongoDB適合Spark的讀寫混合場景。MongoDB是在線式存儲,毫秒級的SLA。

(4)可視化與ETL

MongoDB可以通過BI Connector實現(xiàn)與SQL的結(jié)合。BI Connector會自動產(chǎn)生DRDL映射文件,然后我們根據(jù)映射文件來編寫SQL語句實現(xiàn)數(shù)據(jù)展示。

BI Connector是企業(yè)版的,并且是一個獨立的服務(wù)。

BI Connector暴露的是MySQL驅(qū)動構(gòu)建的解釋器,然后作為一個虛擬的MySQL服務(wù)。

(5)兩地三中心高級集群設(shè)計

容災(zāi)級別描述RPORTO
Level0無災(zāi)備源,只有本地的數(shù)據(jù)備份24小時4小時
Level1本地備份+異地保存,將關(guān)鍵數(shù)據(jù)保存并送到異地24小時8小時
Level2雙中心主備,通過網(wǎng)絡(luò)建立熱點備份秒級數(shù)分鐘到半小時
Level3雙中心雙活,互相進(jìn)行數(shù)據(jù)備份秒級秒級
Level4雙中心雙活+異地?zé)醾?,?dāng)一個城市的兩個中心不可用時切換秒級分鐘級

詳細(xì)介紹MongoDB

網(wǎng)絡(luò)層解決方案

GSLB實現(xiàn)MongoDB負(fù)載均衡器的健康檢查,通過域名實現(xiàn)應(yīng)用層的切換。

應(yīng)用層解決方案

使用負(fù)載均衡技術(shù),虛擬IP技術(shù),使用同一個Session,使用同一套數(shù)據(jù)。

使用HAProxy或者Nginx作為本地的SLB本地負(fù)載均衡器。

數(shù)據(jù)庫層解決方案

通過日志同步或者存儲鏡像實現(xiàn)數(shù)據(jù)拷貝。

復(fù)制集跨中心2+2+1解決方案

2+2+1保證了主中心的高可用,oplog同步實現(xiàn)了毫秒級的拷貝。

(6)全球多寫

由于復(fù)制集只解決了讀取的問題,寫入還是要在Primary上進(jìn)行所以不能夠保證幾個國家的用戶體驗。

詳細(xì)介紹MongoDB

全球多寫本質(zhì)上是一個特殊的分片集群。將集群中的分片節(jié)點分區(qū)域部署。要實現(xiàn)全球分片多寫,那么要實現(xiàn)以下三點條件:

  • 針對要分片的數(shù)據(jù)集合,模型中增加一個區(qū)域字段。

  • 給集群中的每個分片添加區(qū)域標(biāo)簽

    sh.addShardTag("shard0", "Asia");
  • 為每個區(qū)域指定屬于這個區(qū)域的分片塊范圍。

    sh.addShardRange("tableName", {"location": "China"}, "Asia");

全球多寫的事務(wù)性問題:

  • 當(dāng)海外用戶訪問讀取數(shù)據(jù)時,希望是從海外本地讀取,因此需要設(shè)置readPreference:"nearest"

  • 當(dāng)海外用戶下單,那么需要寫到本地大部分節(jié)點才算成功,在國內(nèi)的海外數(shù)據(jù)等待oplog同步,因此需要設(shè)置writeConcern:"majority"。
  • 當(dāng)需要讀取所有區(qū)域的數(shù)據(jù)進(jìn)行匯總時,只需要設(shè)置讀取本地主從節(jié)點為:readPreference:"nearset"就會保證從本地讀取就近的數(shù)據(jù)。
  • 加入海外用戶在國內(nèi)下單,那么就會導(dǎo)致需要寫入遠(yuǎn)程海外節(jié)點,因為配置了writeConcern:"majority"需要寫入大部分節(jié)點。

當(dāng)然,MongoDB也可以在國內(nèi)和海外向Oracle那樣同時部署兩套集群,通過第三方工具實現(xiàn)同步,中間也需要處理數(shù)據(jù)沖突問題。常見的中間件有:Tapdata和MongoShake這兩個第三方中間件也是基于oplog的。

八、連接與開發(fā)注意事項

  • 連接到復(fù)制集:mongodb://node1,node2/dbname?[option]
  • 連接到分片集:mongdb://mongos1,mongos2/dbname?[option]
  • 支持域名解析:mongodb+srv://mongos或者node地址
  • mongos前不可以使用負(fù)載均衡器,因為mongos自帶LB
  • 事務(wù)支持:
    • 使用4.2兼容驅(qū)動
    • 事務(wù)在60秒內(nèi)完成,否則會被取消。
    • 涉及事務(wù)的分片不能使用仲裁節(jié)點。
    • 事務(wù)會影響Chunk遷移效率。
    • 正在遷移的Chunk可能造成事務(wù)失敗。
    • 多文檔事務(wù)必須在Primary節(jié)點進(jìn)行。
    • readConcern只應(yīng)該在事務(wù)級別設(shè)置,不應(yīng)該在每次讀寫上進(jìn)行。
  • 其他:
    • 每一個查詢盡量對應(yīng)一個索引。
    • 盡量使用覆蓋索引。
    • 使用projection來減少返回到Client的內(nèi)容。
    • 處理分頁避免使用count,只是用limit。
    • 盡量控制在1000個更新文檔事務(wù)之內(nèi)。
  • 系統(tǒng)上線時的必要檢查:
    • 禁用NUMA,否則在某些情況下可能導(dǎo)致突發(fā)的大量的SWAP交換。
    • 禁用Transparent Huge Page,否則會影響數(shù)據(jù)庫效率。
    • tcp_keepalive_time設(shè)置為120秒,容忍網(wǎng)絡(luò)問題。
    • 設(shè)置最大文件句柄打開數(shù)目。
    • 關(guān)閉文件系統(tǒng)的atime,提高訪問效率。

九、索引管理

MongoDB中的索引是特殊結(jié)構(gòu),索引存儲在易于遍歷的數(shù)據(jù)集合中,而且使用BTree結(jié)構(gòu)。

(1)創(chuàng)建索引要考慮的問題

  • 每個索引至少需要8KB的空間
  • 添加索引會對寫操作性能產(chǎn)生影響,因為每個集合在插入時也必須更新索引
  • 索引處于Action狀態(tài)時,每個索引都會占用磁盤空間和內(nèi)存

(2)索引的限制

  • 索引名稱超度不可以超過128字段
  • 復(fù)合索引不能超過32個屬性
  • 每個集合不能超過64個索引

(3)索引管理

  • 創(chuàng)建索引

    db.collection.createIndex(<key>, <option>);
    參數(shù)數(shù)據(jù)類型描述
    backgroundBoolean創(chuàng)建索引會阻塞數(shù)據(jù)庫操作,可以指定為后臺操作。
    uniqueBoolean是否建立唯一索引
    nameString索引的名稱
    dropDupsBoolean3.0版本廢棄,建立索引時是否刪除重復(fù)記錄
    sparseBoolean對文檔中不存在的字段數(shù)據(jù)不建立索引
    expireAfterSecondsInteger秒,設(shè)定索引的TTL
    vIndex version索引的版本號
    weightDocument索引權(quán)重值,數(shù)值在1-99999之間
    default_languageString對于文本類型的索引,決定了分詞器規(guī)則,默認(rèn)為英語
    language_overrideString對于文本類型的索引,指定了包含在文檔中的字段名
  • 查看索引

    db.collection.getIndexs();
  • 刪除索引

    db.collection.dropIndexs();
    db.collection.dropIndex();
  • 查看創(chuàng)建過程和終止

    db.currentOp();
    db.killOp();
  • 使用情況

    // 獲取索引訪問信息
    $indexStats
    // 返回查詢計劃
    explain()
    // 控制索引, 強制MongoDB使用特定索引進(jìn)行查詢
    hint()

(4)單值索引

MongoDB可以在任何字段上創(chuàng)建索引,默認(rèn)情況下會在_id字段創(chuàng)建索引,_id索引時為了防止客戶端具有相同的值創(chuàng)建的索引,該索引無法刪除。在分片集群中使用_id索引。

(5)復(fù)合索引

將多個鍵組合到一起,這樣可以加速匹配多個鍵的查詢。

  • 無法創(chuàng)建具有Hash索引的復(fù)合索引
  • 復(fù)合字段的索引是有順序的
  • 復(fù)合索引支持前綴匹配查詢
db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } )

(6)多鍵索引

MongoDB使用多鍵索引為數(shù)組的每個元素創(chuàng)建索引,多鍵索引可以建立在字符串、數(shù)字、內(nèi)嵌文檔類型的數(shù)組上。如果創(chuàng)建的字段包含數(shù)組的值,那么MongoDB將會自動確定是否創(chuàng)建索引。

db.coll.createIndex( { <field>: < 1 or -1 > } )

(7)全文索引

MongoDB機(jī)制提供了全文索引類型,支持在集合中搜索字符串。

db.collection.createIndex( { key: "text",key:"text" ..... } )

MongoDB提供權(quán)重以及通配符的創(chuàng)建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”。每個全文索引可以通過設(shè)置權(quán)重來分配不同的搜索程度,默認(rèn)權(quán)重為1,對于文檔中的每個索引字段,MongoDB將匹配數(shù)乘以權(quán)重并將結(jié)果相加。 使用此總和,MongoDB然后計算文檔的分?jǐn)?shù)

  • 每個集合最多只有一個全文索引
  • 如果查詢使用$text表達(dá)式就無法使用hint()函數(shù)

(8)Hash索引

散列索引使用散列函數(shù)來計算索引字段值的散列值。 散列函數(shù)會折疊嵌入的文檔并計算整個值的散列值,但不支持多鍵(即數(shù)組)索引。

db.collection.createIndex( { _id: "hashed" } )

散列索引支持使用散列分片鍵進(jìn)行分片。 基于散列的分片使用字段的散列索引作為分片鍵來分割整個分片群集中的數(shù)據(jù)。

十、安全架構(gòu)

通過在命令行方式加入--auth參數(shù)或者在配置文件添加authorization: enabled開啟安全選項。

使用命令行客戶端操作:mongo -uUsername -pPassword --authenticationDatabase DbName

(1)MongoDB支持的安全策略

  • 用戶名密碼
  • 證書
  • LDAP,企業(yè)版
  • Kerberos,企業(yè)版

(2)針對集群節(jié)點之間的認(rèn)證

  • KeyFile,統(tǒng)一將Key拷貝到不同的節(jié)點,隨機(jī)的字符串
  • X.509,基于證書的模式,通過內(nèi)部或者外部的CA服務(wù)器頒發(fā),每個節(jié)點都有不同的證書

(3)MongoDB支持的用戶權(quán)限

MongoDB的Role建立在Action和Resource上,Action定義了一種動作,Resource表示某個動作可以操作的資源。MongoDB內(nèi)置權(quán)限角色繼承關(guān)系圖如下:

詳細(xì)介紹MongoDB

自定義角色和用戶分別可以使用createRole()和createUser()。

(4)傳輸加密

MongoDB支持TLS/SSL來加密所有的網(wǎng)絡(luò)數(shù)據(jù)傳輸,不管是內(nèi)部節(jié)點還是客戶端到服務(wù)器。

(5)落盤加密(企業(yè)版)

  • 生成master key,這是一個用來加密數(shù)據(jù)庫的key。每一個數(shù)據(jù)庫都對應(yīng)不同的key。
  • 當(dāng)落盤時,基于不同數(shù)據(jù)庫的key進(jìn)行數(shù)據(jù)加密。
  • key的管理通過使用KMIP協(xié)議的秘鑰管理服務(wù)器完成。MongoDB也支持文件的方式進(jìn)行管理。

(6)字段加密

  • MongoDB支持字段級別的加密。
  • 當(dāng)向加密的數(shù)據(jù)發(fā)送請求的時候,MongoDB的驅(qū)動直接聯(lián)系秘鑰管理器,獲取秘鑰,然后根據(jù)查詢條件直接去數(shù)據(jù)庫查詢,將獲取的加密數(shù)據(jù)拉取過來然后使用秘鑰解密返回明文數(shù)據(jù)。數(shù)據(jù)的加密解密都發(fā)生在MongoDB的驅(qū)動程序。

(7)審計(企業(yè)版)

  • 記錄格式為JSON
  • 可以記錄到本地文件或者syslog
  • 記錄的內(nèi)容有:DDL、DML、用戶認(rèn)證

審計日志記錄到syslog:

--auditDestination syslog

審計日志記錄到指定文件:

--auditDestination file --auditFormat JSON --auditPath /path/to/auditLog.json

對刪除進(jìn)行審計:

--auditDestination file --auditFormat JSON --auditPath /path/to/auditLog.json --auditFilter '{atype: {$in: ["dropCollection"]}}'

十一、性能優(yōu)化

(1)mongostat

用于了解MongoDB運行狀態(tài)的工具。

  • insert、query、update、delete:最近一秒鐘有多少個操作
  • getmore:針對游標(biāo)操作,最近一秒鐘的操作
  • command:創(chuàng)建索引等操作,最近一秒鐘的執(zhí)行個數(shù)
  • dirty:超過20%的時候可能會阻塞新請求,因為這個參數(shù)表示還沒有刷盤數(shù)據(jù)占比
  • used:超過95%的時候可能會阻塞新請求,由于MongoDB基于內(nèi)存緩存機(jī)制,當(dāng)緩存超過80%時,就會執(zhí)行LRU算法
  • qrw、arw:表示排隊的請求
  • conn:表示當(dāng)前連接數(shù)

(2)mongotop

用于了解集合壓力的工具

  • ns:集合
  • total:總時間耗時
  • read:讀時間耗時
  • write:寫時間耗時

(3)mongod日志

MongoDB會記錄超過100ms的查詢,會將執(zhí)行計劃輸出。

(4)mtools

pip install mtools

常用指令:

  • mplotqueries LogFile:將所有的慢查詢通過圖標(biāo)展示。
  • mloginfo —queries LogFile:總結(jié)所有慢查詢模式和出現(xiàn)的次數(shù),消耗時間等。

https://github.com/rueckstiess/mtools

十二、GridFS

GridFS是MongoDB的一個子模塊,主要用于在MongoDB中存儲文件,相當(dāng)于MongoDB內(nèi)置的一個分布式文件系統(tǒng)。本質(zhì)上還是講文件的數(shù)據(jù)分塊存儲在集合中,默認(rèn)的文件集合分為fs.filesfs.chunks。fs.files是存儲文件的基本信息,比如文件名,大小,上傳時間,MD5等。fs.chunks是存儲文件真正數(shù)據(jù)的地方,一個文件會被分割成多個chunk塊進(jìn)行存儲,一般為256KB/個。

GridFS的好處是你不用單獨去搭建一個文件系統(tǒng),直接使用Mongodb自帶的即可,備份,分片都依賴MongoDB,維護(hù)起來也方便。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI