在某些狀況下,將讀請求發送給副本集的備份節點是合理的,例如,單個服務器沒法處理應用的讀壓力,就能夠把查詢請求路由到可複製集中的多臺服務器上。如今絕大部分MongoDB驅動支持讀偏好設置(read preference;或翻譯爲讀取首選項),用來告訴驅動從特定的節點讀取數據。html
primary — 這是默認的設置,代表只從可複製集的主節點讀取數據,所以具備強一致性。若是可複製集有問題,而且沒有可選舉的從節點,就表示出現錯誤。sql
premaryPreferred — 設置了此參數的驅動會從主節點讀取數據,除非某些緣由使主節點不可用或者沒有主節點,此時它會從從節點讀取數據。此種設置下,讀請求沒法保證一致性。mongodb
secondary — 這個設置告訴驅動應該一直從從節點讀取數據。這種設置對於咱們想確保讀請求不會影響主節點的寫入請求時很是有用。若是沒有可用的從節點,讀請求會拋出異常。服務器
secondarypreferred — 讀請求會發出到從節點,除非沒有從節點可用,此時纔會從主節點讀取。網絡
nearest – 驅動會嘗試從最近的可複製集成員節點讀取讀取數據,經過網絡延遲判斷。能夠是主節點也能夠是從節點。所以讀請求只會發送給驅動認爲最快通訊的節點。測試
primary是惟一一個能夠確保讀一致的模式。由於寫請求首先在主節點完成,從服務器的更新會有些延遲,因此可能在從節點沒法找到剛剛在主節點寫入的文檔數據。spa
彙總以上知識,各偏好設置下讀取數據請求所發往的節點以下所示:翻譯
MongoDB 3.4及更新的版本新增了maxStalenessSeconds設置。rest
副本集的從節點可能由於網絡阻塞、磁盤吞吐低、長時間執行操做等,致使其落後於主節點。讀設置maxStalenessSeconds選項讓你對從節點讀取定義了最大落後或「過時」時間。當從節點估計過時時間超過了maxStalenessSeconds,客戶端會中止使用它進行讀操做。htm
最大過時和primary模式不匹配,只有選擇從節點成員讀取操做才能應用。
當選擇了使用maxStalenessSeconds進行讀操做的服務端,客戶端會經過比較從節點和主節點的最後一次寫時間來估計從節點的過時程度。客戶端會把鏈接指向估計落後小於等於maxStalenessSeconds的從節點。若是沒有主節點,客戶端使用從節點間的最近一次寫操做來比較。
默認是沒有最大過時時間而且客戶端也不會在指向讀操做時考慮從節點的落後。
注意:
必須定義maxStalenessSeconds的值大於等於90秒:定義一個更小的值會拋出異常。客戶端經過按期檢查每一個副本集成員最後一次寫時間來估計副本集過時程度。由於檢查不頻繁,因此估計是粗略的。所以,客戶端不能強制maxStalenessSecconds小於90秒。
副本集鏈接字符串格式
mongodb://username:password@host1:port1,host2:port2[,...,hostN:portN]/database?options
options 是鏈接配置中的可選項,replicaSet、readPreference、maxStalenessSeconds是其中的一個子項。
下面咱們舉一個例子來講明字符串是怎麼配置的,測試環境的副本集信息以下:
副本集名稱 | 節點IP | 節點Role | 端口 |
repltest | 168.17.XXX.XX1 | 主節點 | 27017 |
168.17.XXX.XX2 | 從節點 | ||
168.17.XXX.XX3 | 仲裁節點 |
帳號信息以下:
Username | Password | DBName |
mongousertest | testuserpwd | mongotestdb |
若是但願程序讀請求路由到從節點secondary,100秒爲節點數據失效時間,此時C# 程序中connectionStr的字符串能夠設置以下:
string connectionStr = "mongodb://mongousertest:testuserpwd@168.17.XXX.xx1:27017,168.17.XXX.xx2:27017/mongotestdb?replicaSet=repltest&readPreference=secondary&maxStalenessSeconds=100";
部份內容參考官網:https://docs.mongodb.com/manual/core/read-preference/index.html