Mongodb Replica Set 讀寫分離

來源:互聯網
上載者:User

標籤: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 讀寫分離

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.