MongoDB Replica Set使用幾點總結
本文會涉及到MongoDB副本集的初始化,讀寫性能,scala driver,簡單運維等內容。
副本集初始化
在各個節點上replica set進程,
nohup numactl --interleave=all ./mongod --dbpath /home/mongodb/data/ --logpath /home/mongodb/mongodb-linux-x86_64-2.4.7/run.log --port 8017 --rest --journal --replSet smartq --oplogSize 500 --profile=1 --slowms=5 --fork &我的啟動中,開啟了rest接口,journal log,設置了oplog size大小500M(因為之後再修改oplog大小會比較麻煩),還開啟了慢查詢profile,如果有不熟悉這三塊日誌的,可以參考下麵的簡單描述:
- Journal日誌。Journal日誌通過預寫式的redo日誌為MongoDB增加了額外的可靠性,開啟該功能時,數據的更新會先寫入Journal日誌,定期提交,然後在真實數據上執行這些變更,如果服務器安全關閉,日誌會被清除在服務器啟動時,如果存在Journal日誌,則會執行提交.啟動Journal功能隻需要在啟動mongod時指定-journal參數即可,這樣,係統的Journal信息都會被放到數據庫目錄(默認是/data/db)的journal文件夾中
- oplog日誌。MongoDB的高可複用策略中有一種叫做Replica Sets,Replica Sets複製過程中一個服務器充當主服務器,而一個或多個服務器充當從服務器,主服務器將更新寫入一個本地的collection中,這個collection記錄著發生在主服務器的更新操作,並將這些操作分發到從服務器上。這個日誌是一個capped Collection,且有大小之分,所以最好在啟動mongod服務時配置好大小(單位:MB). mongd -oplogsize=1024
- 慢查詢日誌。慢查詢日誌記錄了執行時間超過所設定時間閾值的操作語句,慢查詢日誌對於發現性能有問題的語句很有幫助,建議開啟此功能經常分析該日誌的內容.要配置這個功能值需要在mongod啟動時指定profile參數即可。Eg.將超過5s的操作記錄都記錄下來 mongod --profile=1 --slowms=5 運行一段時間後,可以通過查看db.system.profile 這個collection來獲取慢日誌信息
numactl --interleave=all這塊設置。NUMA和UMA(SMP)多核CPU架構的不同實現方式,推薦閱讀下Introduction to Parallel Computing的章節內容。如果不設置這個參數,進入mongod後會有相應提示,可能帶來的問題可以參考記一次MongoDB性能問題,附原理解析這篇文章。
起了各個節點後,連接到某一台mongod上,進行副本集初始化工作:
var config = { _id: "smartq", members: [ { _id:0, host:"host0-ip:8017" }, { _id:1, host:"host1-ip:8017" }, { _id:2, host:"host2-ip:8017" } ] } rs.initiate(config)輸入rs.status()可以查看primary和secondary節點情況,剛初始化的時候節點的狀態會經曆一些變化,之後選舉出primary。更多指令可以參考 rs.help() 。更多細節可以參考文章mongodb副本集架構搭建
讀寫性能
我的副本集的寫性能,在java driver環境下,差不多是1W-2W+ 行每秒,吞吐量大約2M+ 每秒。寫隻能在primary節點上進行。
我的副本集的讀性能,在不帶索引的情況下,DBCursor的掃描速度是4K~7K 行 每秒。輸入一個查詢,執行後,返回一個DBCursor是很快的,但是遊標的順序fetch行數還是比較慢的。我嚐試了DBCursor提供的一些方式(我使用的是mongo-java-driver-2.10.1的包),對比了下以下幾種獲取速度,
rs = coll.find().sort(new BasicDBObject("_id", 1)).toArray(); rs = coll.find().batchSize(100).limit(l).toArray(); rs = coll.find().toArray(); // toArray()開銷 Iterator it = coll.find().iterator(); // little faster than toArray() while (it.hasNext()) { it.next(); }剛開始一直使用toArray()的方式把DBCursor能指向的數據全部吐到內存裏來,但其實toArray()的開銷稍稍大於返回一個iterator之後逐個掃描一次。而基於_id字段進行排序之後再toArray(),帶來的額外開銷很少,側麵說明_id字段因為有索引,做排序很快很方便,值得好好利用。batchSize這個設置,我嚐試設置了100,1000,感受是對於幾萬到幾十萬的數據吞吐沒有多大影響。
總結是讀性能在速度上還是需要索引支撐,且在能承受最終一致性的前提下,將讀分布到secondary上緩解。
Scala Driver
嚐試了下Scala Driver來進行讀性能的測試,速度和java driver是一致的,而scala driver本身也是對java driver的簡單封裝,且目前支持的api也不全。
Scala Driver項目叫Casbah,是10gen官方的Toolkit。在build.sbt下的配置如下:
name := "hi-scala" organization := "xx.xxx.xxx" version := "0.0.1-SNAPSHOT" scalaVersion := "2.9.3" libraryDependencies ++= Seq( "org.mongodb" %% "casbah" % "2.6.3" )簡單使用:
import com.mongodb.casbah.Imports._ object CasbahTest extends Logging { def main(args: Array[String]): Unit = { val mongoClient = MongoClient("host-ip", 8017) val db = mongoClient("db") val coll = db("collection") val start = System.currentTimeMillis() val rs = coll.find() // for (doc <- rs) { // doc // } logInfo("Result: " + rs.size) // no toArray() val end = System.currentTimeMillis() logInfo("Time: " + (end-start)) } }更多內容參看 Casbah Tutorial
Copy Collection
在同個db下拷貝collection似乎沒有快速的方法,那就寫簡單的js,進行insert操作,
var i = 0; while(i < 10000) { var cname = 'copy' + i; db.copy1.find().forEach( function(x){ db.getCollection(cname).insert(x); }); i++ }然後讓mongod在後台執行,效率也很慢,
nohup ./mongo localhost:8017/hdfs ../../jscript/copy_collection.js &執行一段時間後,secondary的status可能會顯示RECOVERING,原因是oplog記錄的內容過多,primary的oplog可能已經重新刷過一次了,導致secondary與primary脫節,無法再持續進行本身的同步數據的操作。解決方法是把secondary kill掉,刪掉data數據,重新起mongod加入副本集。這利用的是副本集同步機製中的初始化同步,即對於新的沒有數據的member,拷貝現有副本集內某個member的整份數據,整個過程流程為先clone數據,然後apply all changes,最後建索引。啟動之後,secondary會出於STARTUP狀態,開始比較快速地進行數據的同步,這裏比較快也就是上百M每秒的樣子。
(全文完)
最後更新:2017-04-03 14:54:23
上一篇:
Javax.swing中JFrame.getContentPane().add(pane)與JFrame.add(pane)有何區別?
下一篇:
編程的視頻
《生活大爆炸》裏那些高智商遊戲
Oracle 12c多租戶特性詳解:從Schema到PDB的變化與隔離
MyEclipse中add jars和add external jars的區別帶來的svn checkout的問題
DedeCMS後台經常無法加載編輯器
阿裏雲移動雲Apsara Mobile重磅發布 推出Cloud Native App全新研發範式
1.基本常用命令
2017年英特爾在其數據中心業務和AI方麵下大注
大型項目使用Automake/Autoconf完成編譯配置(1)——提綱挈領
Oracle中的number類型
Cocos2d-x實例:設置背景音樂與音效- AppDelegate實現