標籤:mognodb 讀寫分離
環境:mongodb版本:2.4.6,Replica Set
需求:primary壓力過大,期望secondary分擔讀壓力
前言
從應用程式角度來看,使用Replica Set 和使用單台mongo很像。預設的驅動程式會串連primary節點,並且將所有讀寫請求都路由到主節點。但也可以通過設定驅動程式的Read Preferences 配置其他選項,將讀請求路由到其他節點。但需要知道的是將讀請求路由到其他節點所帶來的問題...... 附:驅動程式串連到Replica Set常用的連接字串類似:‘mongodb://server1:27017,server2:27017‘ .具體可以查看相關驅動程式的文檔,php可參考:http://php.net/manual/zh/mongo.tutorial.php.
問題是:
1: 一致性的考慮,對一致性要求比較高的應用程式是不應該從備份節點讀取資料,備份節點通常由於載入問題,網路等原因,而落後於主節點幾毫秒,幾秒,幾分鐘 甚至更多。如果應用程式需要讀取它自己的寫操作(比如,先插入一個文檔,再去查詢它)
那麼不應該從備份節點去讀取資料,除非針對寫操作,使用Write Concern定義w數值,在複製到所有備份節點之後,再返回執行成功與否。總之,如果從一個落後的備份節點讀取資料,就要犧牲一致性。如果希望寫入操作返回之前被複製到所有的複本集成員,就要犧牲寫入速度。
2: 如果路由到的備份節點,其中一台掛了,那麼其他節點將承擔其相應的壓力,需要注意此時線上節點的負載壓力。
小結論是: 一般是不建議做讀寫分離,但是我們這裡業務,寫操作很少,大量的讀請求,這裡決定做讀寫分離來分擔伺服器壓力,然後慢慢過度到分區。
什麼是Read Preference?
Read Preference 描述了mongodb 如何將請求路由到複本集的節點,預設下,會路由到primary節點
Read Preference 的幾個模式:
primary : 預設的模式,所有讀寫,都路由到primary節點
primaryPreferred :大部分情況,操作從primary節點讀資料,除非primary節點不可用
secondary: 所有操作從secondary節點讀取資料
secondaryPreferred:大多數情況,操作從secondary節點讀取資料,除非所有secondary節點不可用.
nearest:從最小的網路的延遲的那個節點讀取資料,不管節點的類型
什麼是 getLastError?
http://docs.mongodb.org/v2.4/reference/command/getLastError/#dbcmd.getLastError
驅動程式在執行一個寫操作後,會執行getLastError ,然後通過返回的資訊來判斷是否執行成功,返回的可以是:
1 :null ,說明執行成功
2 : 一個最後的錯誤描述
getLastError 可以有下面的選項來配置write concern:
j or "journal" option:
它會確認monod實利寫入journal資料到磁碟,保證資料在突然關機的情況下不會丟失 栗子:
> db.runCommand( { getLastError: 1, j: "true" } )
note: If you set journal to true, and the mongod does not have journaling enabled, as with nojournal, then getLastError will provide basic receipt acknowledgment, and will include a jnote field in its return document.
w option:
0 : 禁用基本的acknowledgment寫操作,返回socket異常和網路異常
1 : 提供acknowledgment 的寫操作,在單機或者複本集的primary節點
>1 : 保證寫操作成功的應用到複本集指定的節點(包含primary)
majority : 確認複本集成員多數寫入成功
wtimeout option:
設定write concern逾時的逾時時間,如果不指定或指定為0 在某些情況下可以導致寫操作一直block.
什麼是Write Concern?
Write concern: 當一個mongodb的寫入操作成功執行後什麼時候返回給用戶端.通過getLastError實現.
mongodb 提供不同的等級以方便用戶端特殊的請求Write Concern Levels:
Unacknowledged: mongod不會確認寫入是否成功,用戶端也不會提示是否報錯,除非是網路錯誤(在此版本之前是預設的層級).設定方法: 在你的驅動程式上設定此指定w為0.
650) this.width=650;" src="http://docs.mongodb.org/v2.4/_images/crud-write-concern-unack.png" width="460" height="320" alt="crud-write-concern-unack.png" />
Acknowledged: mongodb 會確認寫入是否成功,用戶端也可以擷取到網路,複製,或者其他的錯誤.(目前預設的層級)
設定方法:在你的驅動程式上設定此指定w為1.
預設的write concern 會調用getLastError( 不帶參數)來確認是否執行寫入成功, 所以也可以在複本集中通過修改預設的getLastErrorDefaults來實現 write concern的層級的更改,這裡沒有修改mongo 的預設配置,是通過修改驅動程式的配置來實現.
getLastError: http://docs.mongodb.org/v2.4/reference/command/getLastError/#dbcmd.getLastError
getLastErrorDefaults: http://docs.mongodb.org/v2.4/reference/replica-configuration/#local.system.replset.settings.getLastErrorDefaults
650) this.width=650;" src="http://docs.mongodb.org/v2.4/_images/crud-write-concern-ack.png" width="460" height="320" alt="crud-write-concern-ack.png" />
Journaled :mongodb 會在資料提交到 journal 後才返回寫操作成功.mongod服務必須開啟journal,mongodb2.4預設是開啟的. 另外在複本集中,只要primary的journal 寫入成功就返回.還可以增加mongodb 提交到journal的頻率來減小此種方式的延遲:http://docs.mongodb.org/v2.4/reference/configuration-options/#journalCommitInterval設定:指定w為1並且指定 j=true.
650) this.width=650;" src="http://docs.mongodb.org/v2.4/_images/crud-write-concern-journal.png" width="600" height="320" alt="crud-write-concern-journal.png" />
Replica Acknowledged:可以保證寫操作寫入到複本集的成員後才返回成功 . 設定w 大於1 , 比如2 是保證2個成員寫入成功後返回.
650) this.width=650;" src="http://docs.mongodb.org/v2.4/_images/crud-write-concern-w2.png" width="520" height="540" alt="crud-write-concern-w2.png" />
如何設定mongodb的讀寫分離?
1: 應用程式設定write concern 看這裡: http://api.mongodb.org/?_ga=1.237665031.647167877.1420012424
php栗子:
<?php$m = new MongoClient("mongodb://localhost/?journal=true&w=majority&wTimeoutMS=20000");?>
2: mongodb Replica Sets 修改預設的 getLastError (getLastErrorDefaults 的設定只會在getLastError 命令沒有其他參數的情況下生效):
cfg = rs.conf()cfg.settings = {}cfg.settings.getLastErrorDefaults = {w: 3,wtimeout: 6000}rs.reconfig(cfg)
以上配置意思:資料成功寫入3個節點後返回,其中包含了primary.最好設定wtimeout,當指定w的數值比複本集的成員多的情況下,寫入操作會一直被block. 另外 wtimeout設定為0 意味這一直不逾時.
參考:
http://docs.mongodb.org/v2.4/core/write-concern/
http://docs.mongodb.org/v2.4/reference/write-concern/
http://docs.mongodb.org/v2.4/core/replica-set-write-concern/
http://docs.mongodb.org/v2.4/reference/command/getLastError/#dbcmd.getLastError
本文出自 “cclo的部落格” 部落格,請務必保留此出處http://xuclv.blog.51cto.com/5503169/1614114
Mongodb Replica Set 讀寫分離