Mongodb 筆記08 瞭解應用的動態、數據管理、持久性

瞭解應用的動態shell

1. 瞭解正在進行的操做:db.currentOp() , 能夠加過濾條件,從而只顯示符合條件的結果。數據庫

    1). 尋找有問題的操做:db.currentOp() 最多見的操做就是用來尋找速度較慢的操做服務器

    2). 終止操做的執行:將該操做的opid做爲參數,執行db.killOp()來終止該操做的執行。並不是全部操做都能被終止。通常來說,只有交出了鎖的進程才能被終止。網絡

    3). 假象:在查找哪些操做耗時過長時,可能會發現一些長時間運行的內部操做。全部local.oplog.rs中長時間運行的請求,以及全部回寫監聽命令,均可以被忽略掉。函數

    4). 避免幽靈操做:阻止幽靈寫入的最好方式是使用應答式寫入,即每次寫入操做都會等待上一次寫入操做完成後才進行下去。工具

2. 使用系統分析器:能夠利用系統分析器來查找耗時過長的操做。系統分析器會記錄特殊集合system.profile中的操做,但會致使總體性能降低,因此應該只在須要時候開啓。性能

    可在shell中運行db.setProfilingLevel()來開啓分析器:db.setProfilingLevel(2)      級別爲2,意味着"分析器會記錄全部內容",性能損失大。操作系統

    可將分析器級別設置爲1,即只顯示長耗時的操做。級別爲1默認記錄耗時大於100ms的操做。也能夠自定義"耗時過長"的標準,把耗時值做爲函數的第二個參數。db.setProfilingLevel(1,500)命令行

    將分析級別設爲0可關閉分析器。一般狀況下,不要將耗時值slows的值設置的太小。即便分析器處於關閉狀態,slowns也會對mongod有所影響,由於它決定了哪些操做將做爲耗時過長操做日誌

    被記錄到日誌中。

3. 計算空間消耗:

    1). 文檔:使用Object.bsonsize()函數:Object.bsonsize({_id:ObjectId()})              Object.bsonsize(db.users.findOne())

    2). 集合:stats函數可用來顯示一個集合的信息:db.boards.stats()

    3). 數據庫:db.stats()            在一個繁忙的系統上列出數據庫信息會很是慢,並且會阻礙其餘操做,應避免此類操做。

4. 使用mongotop和mongostat

    1). mongotop相似於UNIX中的top工具,能夠概述那個集合最爲繁忙。經過運行mongotop-locks ,從而得知每一個數據庫的狀態。

    2). mongostat 提供服務器的信息。mongostat默認每秒輸出一次包含當前狀態的列表,可在命令行中傳入參數更改時間間隔。每一個字段都會給出自上一次被輸出以來,所對應的活動發生次數。

    3). 想要得到數據庫中正在進行的操做快照,mongostat是很好的選擇,但若是要對數據庫進行長期監控昂,相似MMS的工具可能更爲適合。

    

 

數據管理

1. 配置身份驗證

    1). 身份驗證基本原理:admin(管理員)和local(本地)是兩個特殊的數據庫,他們當中的用戶可對任何數據庫進行操做。這兩個數據庫中的用戶可被看作是超級用戶。經認證後,管理員用戶可對任何數據庫

         進行讀寫,同時能執行某些只有管理員才能執行的命令,如listDatabases和shutdown。

         在shell中用addUser建立用戶時,經第三個參數readOnly設置爲true,便可建立一個只讀權限用戶。

    2). 配置身份驗證:啓用身份驗證後,客戶端必須登陸才能進行讀寫。然而,在MongoDB中有一點值得注意:在admin數據庫中創建用戶前,服務器上的"本地"客戶端可對數據庫進行讀寫。

         通常狀況下正常新建管理員用戶進行身份驗證便可避免上的問題,但分片例外,由於數據庫admin會被保存到配置服務器上。能夠將網絡配置爲只容許客戶端訪問mongos進程便可,或者在分片添加管理員帳戶。

    3). 身份驗證的工做原理:數據庫中的用戶是做爲文檔被保存在器system.users集合中的。這種用以保存用戶信息的文檔結構是{user:username,readOnly:true,pwd:password hash} 。其中password hash

         是基於username和密碼生成的散列值。

2. 創建和刪除索引:創建和刪除索引是數據庫最耗費資源的操做之一,因此應當心地安排創建索引

    1). 在獨立服務器上創建索引:db.foo.ensureIndex({"somefield":1},{"background":true})

    2). 在副本集上創建索引:

    3). 在分片集羣上創建索引:在分片集羣上創建索引,與在副本集中創建索引的步驟相同,不過須要在每一個分片上分佈創建一次。首先,關閉均衡器,而後按照 副本集創建索引的步驟,依次在每一個分片中進行操做,

         即把每一個分片當作一個單獨的副本集。最後,經過mongos運行ensureIndex,並重啓均衡器。

         只有在現存分片中添加索引時才須要這樣作,新的分片會在開始接收集合數據塊時抓取集合的索引。

    4). 刪除索引:使用dropIndexes命令並制定索引名來刪除索引:db.runCommand({"dropIndexes":foo,"index":"alphabet"})  。索引名爲「*」時會刪除一個集合上的全部索引,但這種方法沒法刪除"_id"索引。

         只有刪除整個集合才能刪除掉該索引。刪除集合中的所有文檔不會對索引產生影響,新文檔插入後索引仍可正常增長。

    5). 注意內存溢出殺手(OOM Killer):Linux的內存溢出殺手負責終止使用過多內存的進程。考慮到MongoDB使用內存的方式,除了在創建索引的狀況下,它一般不會遇到這種問題。若是在創建索引時,mongod忽然消失,請檢查

         /var/log/messages文件,其中記錄了OOM Killer 的輸出信息。在後臺創建索引或增長交換空間可避免此類狀況。若是有機器的慣例權限,能夠將MongoDB設置爲不可被OOM Killer終止。

3. 預熱數據:

    1). 將數據庫移至內存:若是須要將數據庫移至內存中,可以使用UNIX中的dd工具,從而在啓動mongod前載入數據文件。將/data/db/brains.*替換爲/data/db/*可將真個數據目錄載入內存。如將一個或一組數據庫載入

         內存,需佔的內存又要比實際內存大的話,則其中一些數據會當即被清除出內存。

         mongod 啓動時,會向操做系統請求數據文件。若是操做系統發現內存中已經存在了這些數據文件,就能夠當即訪問mongod。

    2). 將集合移至內存:MongoDB提供了touch命令來預熱數據。啓動mongod(也許在另外一個端口,或關閉防火牆對它的限制),對一個集合使用touch命令,從而將其載入內存:

         db.runCommand({"touch":"logs","data":true,"index":true})  將logs集合中的全部文檔和索引載入內存。能夠指定值載入文檔或只載入索引。注意內存的使用狀況。

    3). 自定義預熱:

         a. 加載一個特定的索引

         b. 加載最近更新文檔

         c. 記載最近建立的文檔:利用最近建立文檔的時間戳進行文檔查詢。ObjectId中包含時間戳。

         d. 重放應用使用記錄:MongoDB提供名爲診斷日誌的功能來記錄和回放操做流水。啓動診斷日誌會形成性能損失,因此最好經過臨時使用的方式來得到一份"有表明性的操做流水"

4. 壓縮數據:爲消除空區段,並高效重整集合,可以使用compact命令:db.runCommand({"compact":"collName"})    

    壓縮操做會消耗大量資源,不該再mongod向客戶端提供服務時,計劃壓縮操做。推薦作法相似於創建索引的作法,即在每一個備份節點中對數據執行壓縮操做,而後關閉主節點,進行最後壓縮操做。

    壓縮會將文檔儘量地安排在一塊兒,文檔間的間隔參數默認爲1.如需更大的間隔參數,可以使用額外的參數來指定它:db.runCommand({"compact":"collname","paddingFactor":1.5}) ,最大值爲4

    能夠經過repair命令來回收磁盤空間。repair命令會對全部數據進行復制,因此必須擁有和當前數據文件同樣大小的額空餘磁盤空間。在啓動mongod時使用--repair選項(如須要,還可使用--repairepath

     選項)來進行修復。能夠在shell中調用db.repairDatabase()來修復數據庫。

5. 移動集合:

    1). 可以使用renameCollection命令重命名集合:db.sourceColl.renameCollection("newname")  , 執行這個命令時能夠傳入第二個參數,從而決定當名爲newname的集合存在時如何處理。true 會

         刪除名爲newname的集合,false ,會拋出錯誤。

    2). 想要在數據庫間移動集合,必須進行轉儲和恢復操做,或手動複製集合中的文檔。

         cloneCollection將一個集合移動到另外一個不一樣的mongod中:db.runCommond({"cloneCollection":collName,"from":"hostname":27017})

6. 預分配數據數據文件: 

 

 

持久性

1. 如磁盤和軟件正常運行,則MongoDB可以在系統崩潰或強制關閉後,確保數據的完整性。

2. 日誌系統的用途:MongoDB會在進行寫入時建立一條日誌,日記中包含了這次寫入操做具體更改的磁盤地址和字節。所以,一旦服務器忽然停機,能夠在啓動時對日誌進行重放,從而從新執行

    那些停機前沒有可以刷新到磁盤的寫入操做。數據文件默認每60秒刷新一次,所以日誌文件值需記錄約60秒的寫入內容。日記系統爲此預先分配了若干個空間文件,這些文件存放在/data/db/journal目錄中,

    文件名爲_j.0,_j.1等。數據庫正常關閉日誌文件會被清除。如發生崩潰,mongod會在啓動時重放日誌文件,同時顯示出大量的校驗信息。

    1). 批量提交寫入操做:MongoDB默認每隔100毫秒,或是寫入數據達到若干兆字節時,便會將這些操做寫入日記。這意味着MongoDB會成批量地提交更改,即每次寫入不會當即刷新到磁盤。不過默認設置

         下,系統發生崩潰時,最多丟失100毫秒的寫入。可經過向getLastEror傳遞 j 選項,來確保寫入操做的成功。設置此選項後,大約等待30毫秒。對一些重要的數據,可使用此選項。

    2). 設定提交時間間隔:運行setParameter命令,設定journalCommitInterval的值(最小爲2毫秒,最大爲500毫秒)。不管時間間隔設置爲多少,使用帶有"j":true的getLastError命令都會將該值減小到原來的三分之一。

3. 關閉日記系統:若是寫入數據的價值不及寫入速度下降帶來的損失,咱們可能會禁用日記系統。若是但願系統崩潰後能繼續工做,有如下幾種方法:

    1). 替換數據文件

    2). 修復數據文件:mongod自帶兩種修復工具,一種是mongod內置的,一種是mongodump內置的。mongodump的修復更接近底層。 --repair. 

    3). mongod.lock 文件:異常退出時會有mongod.lock文件,阻礙mongod從新啓動,標誌咱們須要先修復數據。也能夠經過刪除該文件重啓mongod(生產環境不建議).

    4). 隱蔽的異常退出:

4. MongoDB沒法包保證的事項:在硬盤或文件系統出現故障的狀況下,MongoDB沒法保證操做的持久性。

5. 檢驗數據損壞:可使用validate命令,檢驗集合是否有損壞:db.foo.validate()

6. 副本集的持久性:能夠經過db.runCommand({"getLastError":1,"j":true,"w":"majority"})  中的"w"參數的值,保證寫入操做寫入到主節點和備份節點中,其中只有對主節點的寫入可保證持久性。

相關文章
相關標籤/搜索