您好,登錄后才能下訂單哦!
環(huán)境:mongodb版本:2.4.6,Replica Set
需求:primary壓力過大,期望secondary分擔(dān)讀壓力
前言
從應(yīng)用程序角度來看,使用Replica Set 和使用單臺(tái)mongo很像。默認(rèn)的驅(qū)動(dòng)程序會(huì)連接primary節(jié)點(diǎn),并且將所有讀寫請(qǐng)求都路由到主節(jié)點(diǎn)。但也可以通過設(shè)置驅(qū)動(dòng)程序的Read Preferences 配置其他選項(xiàng),將讀請(qǐng)求路由到其他節(jié)點(diǎn)。但需要知道的是將讀請(qǐng)求路由到其他節(jié)點(diǎn)所帶來的問題...... 附:驅(qū)動(dòng)程序連接到Replica Set常用的連接字符串類似:'mongodb://server1:27017,server2:27017' .具體可以查看相關(guān)驅(qū)動(dòng)程序的文檔,php可參考:http://php.net/manual/zh/mongo.tutorial.php.
問題是:
1: 一致性的考慮,對(duì)一致性要求比較高的應(yīng)用程序是不應(yīng)該從備份節(jié)點(diǎn)讀取數(shù)據(jù),備份節(jié)點(diǎn)通常由于加載問題,網(wǎng)絡(luò)等原因,而落后于主節(jié)點(diǎn)幾毫秒,幾秒,幾分鐘 甚至更多。如果應(yīng)用程序需要讀取它自己的寫操作(比如,先插入一個(gè)文檔,再去查詢它)
那么不應(yīng)該從備份節(jié)點(diǎn)去讀取數(shù)據(jù),除非針對(duì)寫操作,使用Write Concern定義w數(shù)值,在復(fù)制到所有備份節(jié)點(diǎn)之后,再返回執(zhí)行成功與否。總之,如果從一個(gè)落后的備份節(jié)點(diǎn)讀取數(shù)據(jù),就要犧牲一致性。如果希望寫入操作返回之前被復(fù)制到所有的副本集成員,就要犧牲寫入速度。
2: 如果路由到的備份節(jié)點(diǎn),其中一臺(tái)掛了,那么其他節(jié)點(diǎn)將承擔(dān)其相應(yīng)的壓力,需要注意此時(shí)在線節(jié)點(diǎn)的負(fù)載壓力。
小結(jié)論是: 一般是不建議做讀寫分離,但是我們這里業(yè)務(wù),寫操作很少,大量的讀請(qǐng)求,這里決定做讀寫分離來分擔(dān)服務(wù)器壓力,然后慢慢過度到分片。
什么是Read Preference?
Read Preference 描述了mongodb 如何將請(qǐng)求路由到副本集的節(jié)點(diǎn),默認(rèn)下,會(huì)路由到primary節(jié)點(diǎn)
Read Preference 的幾個(gè)模式:
primary : 默認(rèn)的模式,所有讀寫,都路由到primary節(jié)點(diǎn)
primaryPreferred :大部分情況,操作從primary節(jié)點(diǎn)讀數(shù)據(jù),除非primary節(jié)點(diǎn)不可用
secondary: 所有操作從secondary節(jié)點(diǎn)讀取數(shù)據(jù)
secondaryPreferred:大多數(shù)情況,操作從secondary節(jié)點(diǎn)讀取數(shù)據(jù),除非所有secondary節(jié)點(diǎn)不可用.
nearest:從最小的網(wǎng)絡(luò)的延遲的那個(gè)節(jié)點(diǎn)讀取數(shù)據(jù),不管節(jié)點(diǎn)的類型
什么是 getLastError?
http://docs.mongodb.org/v2.4/reference/command/getLastError/#dbcmd.getLastError
驅(qū)動(dòng)程序在執(zhí)行一個(gè)寫操作后,會(huì)執(zhí)行g(shù)etLastError ,然后通過返回的信息來判斷是否執(zhí)行成功,返回的可以是:
1 :null ,說明執(zhí)行成功
2 : 一個(gè)最后的錯(cuò)誤描述
getLastError 可以有下面的選項(xiàng)來配置write concern:
j or "journal" option:
它會(huì)確認(rèn)monod實(shí)利寫入journal數(shù)據(jù)到磁盤,保證數(shù)據(jù)在突然關(guān)機(jī)的情況下不會(huì)丟失 栗子:
> 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異常和網(wǎng)絡(luò)異常
1 : 提供acknowledgment 的寫操作,在單機(jī)或者副本集的primary節(jié)點(diǎn)
>1 : 保證寫操作成功的應(yīng)用到副本集指定的節(jié)點(diǎn)(包含primary)
majority : 確認(rèn)副本集成員多數(shù)寫入成功
wtimeout option:
設(shè)置write concern超時(shí)的超時(shí)時(shí)間,如果不指定或指定為0 在某些情況下可以導(dǎo)致寫操作一直block.
什么是Write Concern?
Write concern: 當(dāng)一個(gè)mongodb的寫入操作成功執(zhí)行后什么時(shí)候返回給客戶端.通過getLastError實(shí)現(xiàn).
mongodb 提供不同的等級(jí)以方便客戶端特殊的請(qǐng)求Write Concern Levels:
Unacknowledged: mongod不會(huì)確認(rèn)寫入是否成功,客戶端也不會(huì)提示是否報(bào)錯(cuò),除非是網(wǎng)絡(luò)錯(cuò)誤(在此版本之前是默認(rèn)的級(jí)別).設(shè)置方法: 在你的驅(qū)動(dòng)程序上設(shè)置此指定w為0.
Acknowledged: mongodb 會(huì)確認(rèn)寫入是否成功,客戶端也可以獲取到網(wǎng)絡(luò),復(fù)制,或者其他的錯(cuò)誤.(目前默認(rèn)的級(jí)別)
設(shè)置方法:在你的驅(qū)動(dòng)程序上設(shè)置此指定w為1.
默認(rèn)的write concern 會(huì)調(diào)用getLastError( 不帶參數(shù))來確認(rèn)是否執(zhí)行寫入成功, 所以也可以在副本集中通過修改默認(rèn)的getLastErrorDefaults來實(shí)現(xiàn) write concern的級(jí)別的更改,這里沒有修改mongo 的默認(rèn)配置,是通過修改驅(qū)動(dòng)程序的配置來實(shí)現(xiàn).
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 會(huì)在數(shù)據(jù)提交到 journal 后才返回寫操作成功.mongod服務(wù)必須開啟journal,mongodb2.4默認(rèn)是開啟的. 另外在副本集中,只要primary的journal 寫入成功就返回.還可以增加mongodb 提交到j(luò)ournal的頻率來減小此種方式的延遲:http://docs.mongodb.org/v2.4/reference/configuration-options/#journalCommitInterval設(shè)置:指定w為1并且指定 j=true.
Replica Acknowledged:可以保證寫操作寫入到副本集的成員后才返回成功 . 設(shè)置w 大于1 , 比如2 是保證2個(gè)成員寫入成功后返回.
如何設(shè)置mongodb的讀寫分離?
1: 應(yīng)用程序設(shè)置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 修改默認(rèn)的 getLastError (getLastErrorDefaults 的設(shè)置只會(huì)在getLastError 命令沒有其他參數(shù)的情況下生效):
cfg = rs.conf() cfg.settings = {} cfg.settings.getLastErrorDefaults = {w: 3,wtimeout: 6000} rs.reconfig(cfg)
以上配置意思:數(shù)據(jù)成功寫入3個(gè)節(jié)點(diǎn)后返回,其中包含了primary.最好設(shè)置wtimeout,當(dāng)指定w的數(shù)值比副本集的成員多的情況下,寫入操作會(huì)一直被block. 另外 wtimeout設(shè)置為0 意味這一直不超時(shí).
參考:
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
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。