1. 程式人生 > >window配置mongodb集群(副本集)

window配置mongodb集群(副本集)

may style log 但是 ace inf ODB lse status

參數解釋:

dbpath:數據存放目錄

logpath:日誌存放路徑

pidfilepath:進程文件,有利於關閉服務

logappend:以追加的方式記錄日誌(boolean值)

replSet:副本集的名字,每一個副本集名字相同

port:mongodb的端口號

oplogSize:mongodb操作日誌文件的最大大小,單位為Mb,默認為硬盤剩余空間的5%

noprealloc:不預先分配存儲

fork:以後臺方式運行進程(linux使用)

directoryperdb:為每一個數據庫按照數據庫名建立文件夾存放

health表示副本集中該節點是否正常,0表示不正常,1表示正常

state表示節點的身份,0表示非主節點,1表示主節點

stateStr用於對節點身份進行字符描述,PRIMARY表示主節點,SECONDARY表示副節點

name是副本集節點的ip和端口信息

priority:副本集節點優先權,這個值的範圍是0--100,值越大,優先權越高,默認的值是1,假設值是0,那麽不能成為primay

arbiterOnly:設置仲裁節點

首先我們先來搭建一個副本集(副本集結構為1個主節點,一個從節點一個仲裁節點)

第一步:我們在本機的1001、1002和1003三個端口上啟動三個不同的Mongodb實例;

mongod --port 1001 --dbpath F:/mongos/mongodb1/data --logpath F:/mongos/mongodb1/log/mongodb.log --pidfilepath F:/mongos/mongodb1/mongodb1.pid --replSet test --logappend --directoryperdb
mongod --port 1002 --dbpath F:/mongos/mongodb2/data --logpath F:/mongos/mongodb2/log/mongodb.log --pidfilepath F:/mongos/mongodb2/mongodb2.pid --replSet test --logappend --directoryperdb
mongod --port 1003 --dbpath F:/mongos/mongodb3/data --logpath F:/mongos/mongodb3/log/mongodb.log --pidfilepath F:/mongos/mongodb3/mongodb3.pid --replSet test --logappend --directoryperdb

第二步:登錄到1001實例上編寫指令,將三個不同的Mongodb實例結合在一起形成一個完整的副本集;

cd F:\mongos\mongodb1\bin

mongo 127.0.0.1:1001

use admin

config_test={_id:"test",members:[
{_id:0,host:"127.0.0.1:1001",priority:1},
{_id:1,host:"127.0.0.1:1002",priority:1},
{_id:2,host:"127.0.0.1:1003",arbiterOnly:true},
]};
這裏,members中可以包含多個值,這裏列舉的就是剛才啟動的三個Mongodb實例,並且通過_id字段給副本集起了名字test。

第三步:通過執行下面的命令初始化副本集。

rs.initiate(config_test);

這裏使用上面的配置初始化Mongodb副本集。

rs.status()

想查看副本集的狀態

到這裏搭建起一個由三個Mongodb實例構成的名稱為test的副本集了。

副本集現在搭建起來了,那麽這個副本集能不能解決我們上面主從模式的兩個問題呢?

我們首先從第一個問題開始看,我們將1001端口的Mongodb服務器給關閉,然後我們使用rs.status()命令來查看下,如下所示:

技術分享圖片

從返回包信息中,可以看到關閉1001端口後,在副本集節點的狀態中該節點是不可達的,重新選取產生的主節點是1002端口上啟動的Mongodb實例,選舉過程是這樣的,當主節點掛掉之後,其他節點可以發起選舉行為,只要在選舉過程中某個節點得到副本集節點數一半以上的選票並且沒有節點投反對票,那麽該節點就可以成為主節點。(參數註釋請看開始位置)在1001端口上的Mongodb實例掛掉之後,1002成為了新的主節點,可以實現故障自動切換。

至於第二個問題,那就是主節點負責所有的讀寫操作造成主節點壓力較大,那麽在副本集中如何解決這個問題了呢?正常情況下,我們在Java中訪問副本集是這樣的,如下所示:

public class TestMongoDBReplSet {   
    public static void main(String[] args)  {  
        try {   
            List<ServerAddress> addresses = new ArrayList<ServerAddress>();    
            ServerAddress address1 = new ServerAddress("127.0.0.1",1001);   
            ServerAddress address2 = new ServerAddress("127.0.0.1",1002);   
            ServerAddress address3 = new ServerAddress("127.0.0.1",1003);   
            addresses.add(address1);    
            addresses.add(address2);   
            addresses.add(address3);   
            MongoClient client = new MongoClient(addresses);   
            DB db = client.getDB( "testdb");   
            DBCollection coll = db.getCollection( "testdb");   
            // 插入   
            BasicDBObject object = new BasicDBObject();    
            object.append("userid","001");   
            coll.insert(object);   
            DBCursor dbCursor = coll.find();   
            while (dbCursor.hasNext()) {   
                DBObject dbObject = dbCursor.next();    
                System. out.println(dbObject.toString());   
            }   
        } catch (Exception e) {   
            e.printStackTrace();    
        }   
    }   
} 

但是,上面不能做到在副本集中讀寫壓力分散,其實在代碼層面,我們可以設置再訪問副本集的時候只從副節點上讀取數據。副本集讀寫分離結構如下圖所示:

技術分享圖片

為了在副本集上實現讀寫分離,我們需要實現以下兩步:

(1)在副本節點上設置setSlaveOk;

(2)代碼層面,在讀操作過程中設置從副本節點讀取數據,如下所示:

public class TestMongoDBReplSet {   
    public static void main(String[] args)  {  
        try {   
            List<ServerAddress> addresses = new ArrayList<ServerAddress>();    
            ServerAddress address1 = new ServerAddress("127.0.0.1",1001);   
            ServerAddress address2 = new ServerAddress("127.0.0.1",1002);   
            ServerAddress address3 = new ServerAddress("127.0.0.1",1003);   
            addresses.add(address1);    
            addresses.add(address2);   
            addresses.add(address3);   
            MongoClient client = new MongoClient(addresses);   
            DB db = client.getDB( "test");   
            DBCollection coll = db.getCollection( "test");                
            BasicDBObject object = new BasicDBObject();    
            object.append("userid","001");   
            ReadPreference preference = ReadPreference.secondary();    
            DBObject dbObject = coll.findOne(object, null , preference);    
            System. out .println(dbObject);    
        } catch (Exception e) {   
            e.printStackTrace();    
        }   
    }   
}

讀參數除了secondary以外,還有其他幾個參數可以使用,他們的含義分別如下所示:

primary:默認參數,只從主節點上進行讀取操作;
primaryPreferred:大部分從主節點上讀取數據,只有主節點不可用時從secondary節點讀取數據。
secondary:只從secondary節點上進行讀取操作,存在的問題是secondary節點的數據會比primary節點數據“舊”。
secondaryPreferred:優先從secondary節點進行讀取操作,secondary節點不可用時從主節點讀取數據;
nearest:不管是主節點、secondary節點,從網絡延遲最低的節點上讀取數據。

window配置mongodb集群(副本集)