默認情況下 驅動程序會將所有的請求路由到主節點 這通常也是你需要的 但是也可以通過設置驅動程序的讀取首選項(read preferences)配置其他選項 可以在讀選項中設置需要將查詢路由到的服務器的類型
雖然將讀請求路由到到備份節點不是一個好主意 但是在特定的情況下這是有意義的 如果你正在考慮將讀請求發送到備份節點 請先從下面幾個方面好好權衡
- 考慮一致性 對於一致性要求非常高的應用程序 不應該從備份節點讀取數據 通常來說 備份節點的數據只會比主節點 落后幾號秒 ,但是由於加載問題 配置錯誤 網絡故障等原因 落后幾分鍾幾個小時 幾天也是有可能 但是客戶端並不知道備份節點的數據有多新鮮 讀取一個遠遠落后於主節點的數據 客戶端不會覺得有任務問題 至於這些數據 是不是有問題這就需要你自己根據業務來判斷了 如果應用程序需要讀取他自己的寫操作 那么就不要把讀請求發給備份節點 后果自己想.因為客戶端發送請求的速度可能會不備份節點復制操作要快 為了能夠始終將寫請求和讀請求發給主節點 許多將讀選項設置為Primary 默認就是這個選項 如果沒有主節點 查詢會出錯誤
- 考慮負載均衡 許多用戶將請求發給備份節點 以便實現分布式的負載均衡 例如如果你的服務器每秒只能處理1000次查詢 而你需要每秒3000次的查詢 那么就需要設置幾個備份節點 來分擔一些數據加載的工作 這種做法很危險 容易系統意外過載 一旦出現這種情況 很難恢復 假如你遇到了上述情況 你決定創建擁有4個成員的副本集 每個備份節點的壓力都在可承受范圍內 整個系統也在正常運轉 后來其中一個備份節點崩潰了.那么剩余的每個成員的負載都是100 如果需要恢復剛剛崩潰的成員 那么就需要從其他成員處復制數據 這個崩潰的成員換選擇一個同步源 這樣 這個作為同步源的成員的要過載 服務器過載晉朝導致新能變慢,副本集性能進一步降底 然后強制其他成員承擔過多的負載 導致這些成員變得更慢 這是一個惡心循環, 如果能明確知道每台服務器能夠承受的負載,你可能會覺得自己能夠更好地因對這種情況 使用五台 而不是4台 這樣即使1台崩潰 也不會過載 即使這樣你也要處理其他服務器負載過大的情況 一個更好地選擇就是用分片做分布式負載
讀偏好(Read Preference)
讀偏好描述了MongoDB客戶端如何將讀請求路由到副本集的成員。
默認情況下,一個應用會將其讀操作導向副本集中的primary。從primary中讀可以保證讀操作返回的是最新的文檔。如果一個應用不需要完全實時的數據,則可以通過分布一些或全部的讀操作到副本集的secondary成員上,從而提高讀操作的吞吐量或者降低時延。
MongoDB驅動允許客戶端應用對於每個連接、每個collection或者每個操作進行讀偏好設置。
讀偏好模式同樣對通過mongos連接分片簇的客戶端有效。
注意:如果一個應用的讀操作比例很大,則從secondary成員分布式讀可以提高吞吐量。
讀偏好模式:
primary
所有的讀操作只訪問當前副本集的primary,為默認模式。如果primary不可用,則讀操作會產生一個error或拋出一個異常。
primaryPreferred [prɪ'fɜ:d]
在通常情況下,從副本集的primary上讀數據,當primary不可用時,也就是在故障切換的過程中,從副本集的secondary成員上讀數據。
secondary
讀操作只從副本集的secondary成員上讀數據。如果沒有secondary可用,則產生一個error或者拋出一個異常。
secondaryPreferred
在通常情況下,讀操作從secondary成員上讀數據,但是當副本集中只有一個primary成員時,則從primary讀數據。
nearest['nɪərɪst]
驅動從最近的集合成員中讀數據時一個成員選擇的過程。該模式不關注成員的類型,不管是primary還是secondary成員。
為了做離線處理 你可能希望創建很多索引,但是又不想將這些索引創建在主節點上 這種情況下 可以設置一個與主節點擁有不同索引的備份節點,如果希望這樣使用備份節點的話 最好使用驅動程序創建一個直接連接目標備份節點的連接 而不是連接副本集
總結 應該根據應用程序的實際需求選擇合適的選項 也可以多個選項組合使用
1,如果某些讀請求必須從主節點讀取數據,那就對這些請求使用Primary選項
2,如果另一些請求並不要求數據是最新的,那么可以對這些讀請求使用Primary preferred選項
3,如果某些請求要求對延遲的要求打過一致性的要求 那么可以使用Nearest.