標籤:node.js replset node.js replica set
隨著web2.0興起,高並發大資料量的應用對資料庫快速響應的效能要求日趨明顯,傳統的關係型資料庫在這方面顯得有些乏力。有矛自有盾,記憶體DB的出現彌補了傳統關係型db的不足。目前市面流行的記憶體db主要有redis、memcach、mongodb。前面二者是基於key-value形式儲存,而mongodb是基於關係型資料庫表的一些特性的儲存方式,並支援索引。所以在一些對大資料量、資料關聯度有要求的情境下,mongodb是一種不錯選擇。
Replica Set是mongodb的一個複本集群方案,它優越於傳統的資料庫主從方式。傳統的主從方式,master負責讀寫,slaver負責從master同步資料,一旦master宕機,slaver就廢了,這種方式在災備方面有缺陷,而mongodb的Replica Set的叢集機制解決了這種缺陷。
Replica Set:
主要分為:primary(主節點,提供增刪查改服務),slaver(備節點,只提供讀),arbiter(仲裁節點,不儲存資料,只負責仲裁)。
流程:client從primary節點讀寫資料,slaver從primary那裡同步資料,當primary宕機時候,arbiter會在10秒內從眾多slaver節點中選出一個健康的slaver頂替primary,這樣就減輕了災害。arbiter節點本身不儲存資料,只是監測叢集中primary和slaver的運行情況(如果arbiter宕機,整個叢集也就廢了,唯一的不足之處)。slaver只提供讀的功能,不能寫,我們的專案查詢的需求可以去連slaver節點,這樣就大大減輕了primary主節點的負載。
以下是Replica Set的流程圖:
Replica Set的原理我們明白了,你可能會問,我們在編程的時候,對於primary、slaver這麼多db,我們一定是往primary節點寫資料,如果primary節點宕機了,程式應該怎麼檢測,怎麼找到新的primary節點呢?
不用擔心,mongodb已經解決了你的疑問。mongodb提供了對各類語言的驅動的支援,你只需調用Replica Set介面,然後參照說明來使用它,下面以node.js
var Db = require(‘mongodb‘).Db,
Server = require(‘mongodb‘).Server,
ReplSet = require(‘mongodb‘).ReplSet;
//叢集Server地址
var serverAddr = {
9001: ‘192.168.1.100‘, //節點1
9002: ‘192.168.1.100‘, //節點2
9003: ‘192.168.1.100‘ //節點3
}
//叢集Sever對象的集合
var servers = [];
for (var i in serverAddr) {
servers.push(new Server(serverAddr[i], parseInt(i)));
}
var replStat = new ReplSet(servers, {});
var db = new Db(‘blog‘, replStat);
//mongodb操作
db.open(function(err, db) {
var collection = db.collection(‘user‘);
//查詢一個document
collection.findOne({
name: ‘jerry‘
}, function(err, results) {
console.info(‘query:‘, results);
});
//插入一個document
collection.insert({
name: ‘ok‘,
age: 28
}, function(err, results) {
console.info(‘insert:‘ + results);
});
});
上面配置了幾個節點9001、9002、9003,我們無需關注哪個是主節點、備節點、沖裁節點,驅動會自動判斷出一個健康的主節點來給node,我們只需專心寫資料庫的操作邏輯就可以了。
但這裡存在一個問題,Replica Set在切換節點的時候,會出現一個斷檔期,我們知道node是非同步/O的,在這個斷檔期,如果node在執行大量操作的話,弱小的棧記憶體會溢出,報:RangeError: Maximum call stack size exceeded錯誤,這個錯誤是系統級錯誤,會導致app崩掉,即使捕獲異常或等db切換完成,程式依然會掛死在哪裡。目前還沒找到解決的方法,正在研究mongo驅動的api,試圖通過一個體現切換過程狀態監聽的事件解決,如果該事件觸發,則停止db操作,待切換完成後再恢複,這樣應該可以解決問題。
node.js mongodb ReplSet