標籤:
三個節點有一個節點掛掉也不會影響應用程式用戶端對整個複本集的讀寫!
[java] view plaincopy
- public class TestMongoDBReplSet { public static void main(String[] args)
- { try { List<ServerAddress> addresses = new ArrayList<ServerAddress>();
- ServerAddress address1 = new ServerAddress("192.168.1.136" , 27017); ServerAddress
- address2 = new ServerAddress("192.168.1.137" , 27017); ServerAddress address3
- = new ServerAddress("192.168.1.138" , 27017); addresses.add(address1);
- addresses.add(address2); addresses.add(address3); MongoClient client =
- new MongoClient(addresses); DB db = client.getDB( "test"); DBCollection
- coll = db.getCollection( "testdb"); // 插入 BasicDBObject object = new BasicDBObject();
- object.append( "test2", "testval2" ); coll.insert(object); DBCursor dbCursor
- = coll.find(); while (dbCursor.hasNext()) { DBObject dbObject = dbCursor.next();
- System. out.println(dbObject.toString()); } } catch (Exception e) { e.printStackTrace();
- } } }
目前看起來支援完美的容錯移轉了,這個架構是不是比較完美了?其實還有很多地方可以最佳化,比如開頭的第二個問題:主節點的讀寫壓力過大如何解決?常見的解決方案是讀寫分離,mongodb複本集的讀寫分離如何做呢?
看圖說話:
常規寫操作來說並沒有讀操作多,所以一台主節點負責寫,兩台副本節點負責讀。
1、設定讀寫分離需要先在副本節點SECONDARY 設定 setSlaveOk。
2、在程式中設定副本節點負責讀操作,如下代碼:
[java] view plaincopy
- public class TestMongoDBReplSetReadSplit {
-
- public static void main(String[] args) {
-
- try {
- List<ServerAddress> addresses = new ArrayList<ServerAddress>();
- ServerAddress address1 = new ServerAddress("192.168.1.136" , 27017);
- ServerAddress address2 = new ServerAddress("192.168.1.137" , 27017);
- ServerAddress address3 = new ServerAddress("192.168.1.138" , 27017);
- addresses.add(address1);
- addresses.add(address2);
- addresses.add(address3);
-
- MongoClient client = new MongoClient(addresses);
- DB db = client.getDB( "test" );
- DBCollection coll = db.getCollection( "testdb" );
-
-
- BasicDBObject object = new BasicDBObject();
- object.append( "test2" , "testval2" );
-
- //讀操作從副本節點讀取
- ReadPreference preference = ReadPreference. secondary();
- DBObject dbObject = coll.findOne(object, null , preference);
-
- System. out .println(dbObject);
-
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
讀參數除了secondary一共還有五個參數:primary、primaryPreferred、secondary、secondaryPreferred、nearest。
primary:預設參數,只從主節點上進行讀取操作;
primaryPreferred:大部分從主節點上讀取資料,只有主節點不可用時從secondary節點讀取資料。
secondary:只從secondary節點上進行讀取操作,存在的問題是secondary節點的資料會比primary節點資料“舊”。
secondaryPreferred:優先從secondary節點進行讀取操作,secondary節點不可用時從主節點讀取資料;
nearest:不管是主節點、secondary節點,從網路延遲最低的節點上讀取資料。
好,讀寫分離做好我們可以資料分流,減輕壓力解決了“主節點的讀寫壓力過大如何解決?”這個問題。不過當我們的副本節點增多時,主節點的複製壓力會加大有什麼辦法解決嗎?mongodb早就有了相應的解決方案。
看圖:
其中的仲裁節點不儲存資料,只是負責容錯移轉的群體投票,這樣就少了資料複製的壓力。是不是想得很周到啊,一看mongodb的開發兄弟熟知大資料架構體系,其實不只是主節點、副本節點、仲裁節點,還有Secondary-Only、Hidden、Delayed、Non-Voting。
Secondary-Only:不能成為primary節點,只能作為secondary副本節點,防止一些效能不高的節點成為主節點。
Hidden:這類節點是不能夠被用戶端制定IP引用,也不能被設定為主節點,但是可以投票,一般用於備份資料。
Delayed:可以指定一個時間延遲從primary節點同步資料。主要用於備份資料,如果即時同步,誤刪除資料馬上同步到從節點,恢複又恢複不了。
Non-Voting:沒有選舉權的secondary節點,純粹的備份資料節點。
到此整個mongodb複本集搞定了兩個問題:
- 主節點掛了能否自動切換串連?目前需要手工切換。
- 主節點的讀寫壓力過大如何解決?
還有這兩個問題後續解決:
- 從節點每個上面的資料都是對資料庫全量拷貝,從節點壓力會不會過大?
- 資料壓力大到機器支撐不了的時候能否做到自動擴充?
做了複本集發現又一些問題:
- 複本集容錯移轉,主節點是如何選舉的?能否手動幹涉下架某一台主節點。
- 官方說複本集數量最好是奇數,為什嗎?
- mongodb複本集是如何同步的?如果同步不及時會出現什麼情況?會不會出現不一致性?
- mongodb的容錯移轉會不會無故自動發生?什麼條件會觸發?頻繁觸發可能會帶來系統負載加重
java程式串連MongoDB複本集測試