MongoDB的配置服務器
引入了分片機制之后,MongoDB啟用了配置服務器(config server) 來存儲元數據,這些元數據包括分片信息、權限控制信息,用來控制分布式鎖。其中分片信息還會被負責執行查詢mongos使用。
MongoDB的配置服務器有一個很大的優點,就是主節點崩潰了,它也可以繼續提供讀服務。
大多數中間件的主從結構都是在主節點崩潰之后完全不可用,直到選舉出了一個新的主節點。
但是不管怎么說,配置服務器在MongoDB里是一個非常關鍵的組件,如果一旦配置服務器有問題,哪怕只是輕微地性能抖動一下,對整個MongoDB集群的影響都很大。
MongoDB的復制機制(主從機制)
MongoDB的副本也是MongoDB實例,它們和主實例持有一樣的數據。在MongoDB里,用Primary來代表主實例,用Secondary來代表副本實例。主從實例合并在一起,也叫做一個復制集(Replica Set)
類似于數據庫的讀寫分離機制,可以在MongoDB上進行讀寫分離。讀從Secondary0實例讀,寫入Primary實例,同時Secondary0和Secondary1從Primary實例里同步數據
在MongoDB里,主從之間的數據同步是通過所謂的oplog來實現的,類似MySQL的binlog。但是oplog會有一些缺點:
- 在一些特定的操作里,oplog可能會超乎想象地大。這主要是因為oplog是冪等的,所以任何操作都比要轉化為冪等操作。簡單來說,任何對MongoDB里數據的操作,最后都會被轉化成一個set操作。所以可以預計的是,就是只更新了數據的一小部分,但是生成的oplpg還是set整個數據。
- oplog是有期限的,即MongoDB限制了oplog的大小。當oplog占據了太多的磁盤之后,就會被刪除。就算某個從節點來不及同步,oplog也是會被刪除的。這個時候,這個從節點只能重新發起一次全量的數據同步。
寫入語義
和Kafka的寫入語義非常像,可以通過參數來控制寫入數據究竟寫到哪里,寫入語義對性能、可用性和數據可靠性有顯著的影響。
在MongoDB里,寫入語義也叫Write Concern,它由w、j和wtimeout三個參數控制。
w參數
它的取值如下:
majority
:要求寫操作已經同步給大部分節點,默認取值,可用性強,但是寫入性能差- 數字
N
:如果N=1,要求必須寫入主節點;如果N大于1,那么就必須寫入主節點,而且寫入N-1個從節點;如果N=0,那么就不用等任何節點寫入。性能很好,但是雖然客戶端收到了成功的響應,數據也有可能丟失。 - 自定義寫入節點策略:可以給一些節點打上標簽,然后要求寫入的時候一定要寫入帶有這些標簽的節點,實踐中用的較少
j參數
控制數據有沒有被寫到磁盤上,對于j來說它的取值就是true或false
wtimeout參數
寫入的超時時間,只會在w>1
的時候生效。
在超時之后MongoDB就直接返回一個錯誤,但是這種情況下,MongoDB可能還是寫入數據成功了
面試準備
- 負責的業務或公司有沒有使用MongoDB,主要用來做什么
- 為什么要用MongoDB,用MySQL可以嗎
- 用MongoDB的時候,文檔支持分片嗎?如果支持的話,按什么來分片的?
- 業務有多少數據量,并發有多高?
- MongoDB怎么部署的,主從節點有多少?有沒有多數據中心的部署方案?
- MongoDB的寫入語義,即w和j這兩個參數的取值
面試話題引導
- Kafka的acks機制,可以引申到MongoDB的寫入語義上
- 其他中間件的對等結構,或主從結構,可以引導到MongoDB的分片和主從機制上
- Kafka的元數據,可以結合MongoDB的元數據一起回答
- MongoDB數據不丟失的問題,可以結合寫入語義來回答,參考Kafka分析的思路。
在整個MongoDB的面試過程中,注意和不同的中間件進行對比,凸顯在這方面的積累