您好,登錄后才能下訂單哦!
環境: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.
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
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.
Replica Acknowledged:可以保證寫操作寫入到副本集的成員后才返回成功 . 設置w 大于1 , 比如2 是保證2個成員寫入成功后返回.
如何設置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
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。