MongoDB 最佳實踐和場景避坑指南

FeelTouch發表於2019-03-24

Mongodb相對hbase、MySQL來說,有哪些優勢?

這裡就簡單說一下題主說的幾個資料庫中,mongodb優勢的地方

vs hbase:

hbase是基於row key儲存寬列的一款nosql,乍一看結構類似mongodb的_id主鍵和可變長的列數量。

具體的原理和區別這裡不展開。

mongodb的優勢在於輕量化部署非常簡單,不用像hbase那樣搭一整套hadoop叢集,即開即用。hbase更適合離線的海量資料分析

vs mysqlpg:

這兩款都是關係型資料庫,所以放在一起比較。

MongoDB的優勢主要有3個。

1、結構靈活,表結構更改比較自由,不用每次alter的時候付出代價,適合業務快速迭代,而且json原生和大多數的語言有天然的契合。還支援陣列,巢狀文件等資料型別

2、自帶高可用,自動主從切換(副本集)

3、自帶水平分片(分片),內建了路由,配置管理。應用只要連線路由,對應用來說是透明的。

MongoDB是否支援事務?

MongoDB只支援行級的事務,或者說支援原子性,單行的操作要麼全部成功,要麼全部失敗。

需要事務的話,得自己用程式碼實現二次提交作,模擬事務的功能,官方文件有相關的說明。

https://docs.mongodb.com/manual/tutorial/perform-two-phase-commits/

這裡放一個小彩蛋,因為WiredTiger引擎本身支援事務,官方正考慮在MongoDB上實現事務。

MongoDB黑客勒索事件是怎麼回事?

這次鬧的沸沸揚揚的黑客事件主要是使用者自己的MongoDB沒有開啟使用者驗證,而且把MongoDB保護在公網。打個比方就是你家住在鬧市區,晚上沒人的時候,門還沒鎖,然後就被小偷光顧了。

要解決問題很簡單,首先,千,萬,不,要把MongoDB暴露在公網,如果要外網訪問,無論是vpn還是ssh隧道都行。

此外,開啟Mongodb的驗證,這樣所有操作都要使用者名稱密碼了但是短連線會因為驗證造成資源損耗,這裡就自己權衡了。阿里雲和騰訊雲針對這個問題都做了優化。

MONGODB資料庫備份只能用mongodump嗎?

常用而且通用的方法就是mongodump

備份還有這幾種方法:

1. mongoexport(這個是邏輯備份,備份出json和csv)

2. 做磁碟快照

3. 停機後冷拷貝

Mongo大資料遷移方案,遷移過程中需要注意什麼,叢集的時候呢?

你的遷移是指怎麼遷移?一般來說mongodump來遷移即可。

叢集遷移的話,建議直接在目標伺服器上面搭建從節點。全部搭建完之後,把新的從節點升級為主節點,再把老機器剔除出叢集。

不過如果資料量太大,而且平時資料更改很頻繁的話,初始化同步的過程可能Oplog不夠用。

方案1

先升級到3.4版本,這個版本在初始化同步的時候會抓取oplog

方案2

停機一臺從節點,物理複製到區域網中心機器,當從節點啟動

這臺從節點配置一個大oplog,然後遷移目標端的從節點從這臺oplog從節點同步

MONGODB的水平擴充套件是什麼原理?

MONGODB的水平擴充套件是依賴什麼原理哪?如果由於前期規劃不足,導致需要通過擴容的方式提高MOGODB的能力,在給他水平擴充套件的時候是否複雜哪?是否將原有資料重新同步?是否可以線上處理哪?

MongoDB的水平擴充套件主要依賴的原理相當有一個config元件負責管理後設資料的位置,然後mongo的路由會從config取得資料所在或者應該在的資料節點位置,從而去對應的資料節點讀寫(路由本身也會有快取)

我這裡只是簡單的說明,具體可以看官方文件sharding一章節

水平擴充套件的步驟不算複雜,不用將資料重新同步(但是從單點到副本集還是要做同步的),整個過程可以線上處理(不過3.4開始,在設定為sharding模式的時候需要滾動重啟一下mongod程式,加上shardsvr的配置)

具體看這一篇文件

https://docs.mongodb.com/manual/tutorial/convert-replica-set-to-replicated-shard-cluster/

mongodb叢集實際應用中如何選擇片鍵和索引?

分片方式有兩種:

1. 範圍分片:這個類似分割槽表,合適的分片條件可以增加查詢效能,更優的設計可以優化寫入效能。

比如說資料1、2在節點a,資料3、4、5在節點b,資料6、7在節點c

2. hash分片:使資料均勻落在不同的分片節點上,優化寫入效能,但是讀的話需要掃所有節點

好的片鍵需要以下的考量:

1. 片鍵中文件儘可能的少,避免單chunk過大,這個會導致無法balance

2. 片鍵離散分佈,這樣可以在不同的節點寫入(避免自增主鍵或者時間戳單獨的做片鍵,這樣會存在寫入熱點問題)

3. 大多數的查詢的條件要包含你的分片條件

舉一個例子:

一個日誌記錄系統,有hostname,timestamp,message等資訊,經常會有查詢需求,這裡用範圍分片

很多人可能會直接拿timestamp做範圍片鍵,這樣可以覆蓋到常見的時間查詢需求,但是所有寫的請求都落到同一臺,造成熱點問題。而且查hostname的時候會掃描所有節點。

好的方案就是選擇hostname和timestamp做一個聯合的分片條件,一來資料分佈更均勻,二來基於主機和時間的查詢也可以優化到。

推薦兩個網址:

https://yq.aliyun.com/articles/60096?spm=5176.8091938.0.0.Kxyh2C

http://www.mongoing.com/blog/post/on-selecting-a-shard-key-for-mongodb

MongoDB如何進行升級?

這裡升級以副本集為例

小版本升級:

非常簡單,直接停機,替換二進位制檔案,啟動即可。先升級從節點,再升級主節點,避免業務中斷。

大版本升級(不更換儲存引擎):

也是直接替換即可,有的版本(如升級到3.4),想啟動新版本功能,需要執行

db.adminCommand( { setFeatureCompatibilityVersion: "3.4" } )

大版本升級(換儲存引擎):

資料檔案需要重做,新建從節點,升級那個從節點的二進位制檔案,配置使用新的引擎,將資料完整的同步,然後該從節點升級為主節點,其他節點正常升級。

不建議跨大版本升級,否則會有不確定的問題。

最後,官方文件非常詳細,一步一步的操作都有

https://docs.mongodb.com/manual/release-notes/3.4-upgrade-replica-set/

Mongodb升級報錯?

mongodb副本集從2.6升級到3.0,密碼驗證升級了 報如下錯誤

Failed to authenticate xxx@xxxx with mechanism MONGODB-CR: AuthenticationFailed MONGODB-CR credentials missing in the user document

應該如何解決呢? 是把原來的使用者刪了,用3.0的在建立一個一樣的使用者嗎? 有沒有更好的辦法呢?

原因是因為3.0開始mongodb的認證加密模式從Mongodb-cr改到了sha1

治標方法:

先關閉驗證,然後把

admin庫中system.version表的

{ "_id" : "authSchema", "currentVersion" : 3 }

那個currentVersion改成3(預設是5),就可以了

治本方法:

1. 升級客戶端的驅動(遲早要升級了,不然不支援新功能)

2. 上面那個currentVersion別動

參考:https://jira.mongodb.org/browse/SERVER-17459

MongoDB在出現負載過高的情況下如何處理?

原來遇到過一次mongodb負載過高的情況,主庫和從庫的負載突然就上來了,CPU佔有率都到了100%,這種情況下,如何處理?mongodb是做的副本集,但是主庫和從庫這個時候是負載同時來的。

簡單點看db.currentop,看mongotop和mongostat,currentop相當於當前所有在執行的任務,看一下是在執行什麼,有多少數量。也可以去slowlog裡面看是否有記錄,然後mongotop和mongostat是用來檢視和平時比有什麼異常資訊。

可能的情況有連線數突然變高,查詢突然變多,有一種查詢沒有索引,建立大表的索引等等。

參考:https://blog.csdn.net/jjwen/article/details/79786444

相關文章