副本集中有三個角色:javascript
主節點:全部副節點的數據均來自於主節點,而且只能對主節點進行讀寫操做。
副節點:數據來自於主節點,能夠進行讀取操做,可是不能進行寫操做。
仲裁者:不含數據也不與客戶端交流,只在選舉主節點的時候進行投票。html
Mongodb最多支持50個副本集成員以及最多7個選舉成員,啓動副本集後將開始第一次選舉,在選舉過程當中,全部副本集成員都只能讀取,直到選舉出主節點後主節點才能進行讀寫,可是在這個期間副本成員能夠提供查詢服務。java
而主節點要保持主節點的位置須要每兩秒發送一個ping請求,若是10秒內沒有獲得響應則標記爲不可訪問,當一半以上的副本集成員不可訪問,那麼主節點將降級爲副節點。git
其中設置成員的priority值能夠優先成員主節點,這個值介於0-1000之間,默認爲1,若是這個值爲0,那麼它的votes值也爲0,只要votes爲0的成員不能投選舉票,可是能夠投否決票。可是咱們也能夠手動設置成員priority值爲大於1的成員是否有投票權利。github
在進行選舉的時候,其餘成員會做如下幾點判斷來進行投票參與選舉的成員是否能做爲主節點,選舉步驟:web
本身是否能與主節點通信。
參與選舉的成員是否比其餘參與選舉的成員數據最新。
若是參與選舉的成員數據相等則嘗試使用具備最高priority的值的成員。mongodb
仲裁者的出現是爲了不只有兩個成員的副本集,兩個成員的副本集投票可能沒法知足一半以上的投票狀況。數據庫
仲裁者不負責數據和客戶端交流,只有參與選舉的功能,須要注意的是仲裁者一旦設置事後就再也沒法變爲非仲裁者了。bash
首先部署一個副本集很簡單,下面的代碼是部署了一個本地含有三個成員的副本集。服務器
創建三個成員的副本集,首先你得創建三個數據庫的存放目錄:
mkdir -p ./replDb/s0 ./replDb/s1 ./replDb/s2
而後咱們啓動三個副本集成員,其中replSet參數後面跟的是副本集的名稱,將須要有關聯的成員的副本集名稱要一致。
mongod --dbpath ./replDb/s0 --port 27017 --replSet s0
mongod --dbpath ./replDb/s0 --port 27018 --replSet s0
mongod --dbpath ./replDb/s0 --port 27019 --replSet s0
建立仲裁者也一樣很是簡單,創建一個空的數據目錄,而後和其餘副本集成員同樣設置一樣的副本集名稱啓動,最後經過rs.add方法的第二個參數設置爲true:
mongod --dbpath ./replDb/s5 --port 27020 --replSet s0
mongod --port 27017 --host localhost
> rs.add('localhost:27020', true);
而後經過Mongo Shell進入到端口爲27017的成員中,並配置副本集。
mongod --port 27017 --host localhost
進入到Mongo Shell後經過rs.initiate方法來配置副本集。
> var conf = {
_id: 'r0',
version: 1,
members: [
{
_id: 0,
host: 'localhost:27017'
},
{
_id: 1,
host: 'localhost:27018'
},
{
_id: 2,
host: 'localhost:27019'
},
{
_id: 3,
host: 'localhost:27020'
}
]
};
> rs.initiate(conf);
initiate接受一個對象,對象_id爲副本集名稱,必須和啓動副本集設置的一致才能添加進來(本例爲rs0)。version爲版本號,每當咱們修改副本集配置的時候這個版本號都會遞加1,而members則爲副本集成員,咱們能夠在這裏一次性添加完,也能夠只添加一個後面再經過add方法添加,好比下面這樣:
> rs.add('localhost:27018');
> rs.add('localhost:27019');
刪除副本集經過rs.remove方法來刪除,它接受一個<localhost>:<port>這樣的字符串。下面是刪除一個副本集成員:
> rs.remove('localhost:27019');
查看副本集配置是經過rs.conf方法查詢,返回包含全部副本集的配置內容.
> rs.conf();
每當使用rs.add方法添加成員的時候可能會影響選舉來選擇主節點是誰,查看主節點經過rs.isMaster()方法來查看。
> rs.isMaster();
返回的內容中有幾個能夠了解
{
"hosts" : [ //副本集成員
"localhost:27017",
"localhost:27018",
"localhost:27019"
],
"setName" : "rs0", //副本集名稱
"setVersion" : 3, //副本集配置版本
"ismaster" : true, //是不是主節點
"primary" : "localhost:27017", //主節點成員的主機地址
"me" : "localhost:27017", //當前所在主機
}
副節點默認是沒法讀取的,咱們能夠經過rs.setSlaveOk()方法來設置Slave屬性爲true。下面是設置端口爲27018的副節點能夠進行讀取
mongod --port 27018 --host localhost
> rs.setSlaveOk();
隱藏成員經過設置成員的hidden屬性爲true而且優先值priority爲0則能夠隱藏此成員,隱藏成員不能當主節點也不能當其餘成員的複製源
> rs.add({
> _id: 1,
> _host: 'localhost:27017',
> hidden: true,
> priority: 0
> })
經過設置成員的slaveDelay的值而且優先值priority爲0,來讓當前成員滯後多少秒後纔開始複製數據。
> rs.add({
> _id: 1,
> _host: 'localhost:27017',
> slaveDelay: 120,
> priority: 0
> })
經過成員的buildIndexes的值而且優先值priority爲0,來設置是否在備份機器上創建相同的索引,通常這個選項只用於純粹備份的服務器。
下面的代碼設置添加的副本集成員不建立索引。
> rs.add({
> _id: 1,
> _host: 'localhost:27017',
> buildIndexes: false
> priority: 0
> })
首先搭建配置服務器,配置服務器如同分片的大腦,保存着集羣和數據的描述信息。
由於Mongodb3.4版本後須要配置服務器必須配置爲副本集,因此須要給配置服務器配置副本集
首先創建三個空的數據庫目錄,用於搭建配置服務器的副本集,並分別啓動它們,在啓動的時候須要加上咱們副本集的名稱和--configsvr
來表示這是一個配置服務器,並分別指定不一樣的端口。
$ mkdir config0 config1 config2 $ mongod --dbpath config0 --replSet conServer --configsvr --port 27020 $ mongod --dbpath config1 --replSet conServer --configsvr --port 27021 $ mongod --dbpath config2 --replSet conServer --configsvr --port 27020
而後經過mongo隨意進入一個副本集成員,併爲配置服務器的副本集進行配置:
$ mongo --port 27020 --host localhost > var conf = { _id: 'conServer', version: 1, members: [ { _id: 0, host: 'localhost:27020' }, { _id: 1, host: 'localhost:27021' }, { _id: 2, host: 'localhost:27022' } ] }; > rs.initiate(conf);
至此配置服務器配置完成。
官方建議咱們的分片服務區至少在3個或以上才能發揮出更好的性能,咱們這裏也建立三個分片服務器。
由於分片服務器沒有強制要求必須是副本集,因此下面就建立了三個單機分片服務器,可是Mongodb接受分片服務器爲副本集。
下面建立三個空數據庫目錄,而後啓動它們,在啓動的時候須要加上--shardsvr
以表示這是一個分片服務器:
$ mkdir sh0 sh1 sh2 $ mongod --dbpath sh0 --shardsvr --port 27030 $ mongod --dbpath sh1 --shardsvr --port 27031 $ mongod --dbpath sh2 --shardsvr --port 27032
至此分片服務器也搭建完成。
mongodb提供了一個路由工具,它會隨着咱們下載包一塊兒下載,名字爲mongos
或mongos.exe
,經過它配置路由功能。
啓動路由咱們須要加上參數--configdb
,它的語法爲:
--configdb 配置服務器副本集名稱/配置服務器1地址端口,配置服務器1地址端口...
啓動路由,併爲路由指定一個端口,用於開放給客戶端連接:
$ mongos --configdb conServer/localhost:27020,localhost:27021,localhost:27022 --port 27040
至此路由已經搭建完成。
經過mongodb提供的mongo進入到路由服務器中進行配置,把咱們開始建立的三個分片服務器經過sh.addShard()
方法添加進行,這個方法接受一個字符串裏面的格式爲host:port
。
$ mongo --port 27040 --host localhost > sh.addShard('localhost:27030'); > sh.addShard('localhost:27031'); > sh.addShard('localhost:27032');
能夠經過rs.status()
方法中返回的shards
字段看是否添加成功。
到目前爲止,分片服務器已經搭建完成,可是目前分片服務器沒法正常工做,咱們全部的操做都將在隨機的一個主分片上操做,這是由於分片服務器不知道怎麼進行分片,因此咱們還須要配置片鍵來告訴分片服務器按照什麼來分片。
分片是基於數據庫集合中的文檔的一個鍵進行分片的,好比選擇username鍵,那麼會根據這個鍵的順序就行分片,而mongodb會自動平衡分片的數據。
Mongodb要求做爲片鍵的鍵必須是索引過的,因此咱們在創建片鍵以前須要對鍵進行索引,創建後片鍵就是集合中的最重要的索引。
在生產環境中建議先想好數據建構創建索引和片鍵後開始操做數據,這樣會減輕分片服務器的負載。
首先咱們在須要進行分片的數據庫上開啓分片功能,經過sh.enableSharding
方法開啓。
$ mongo --port 27040 --host localhost > sh.enableSharding('test');
而後在開啓分片的數據庫中的test集合插入測試數據,注意此時咱們尚未進行配置片鍵,因此全部的數據操做都在分片服務器隨機分配的一個主分片上面進行的。
> for(var i = 0; i < 100; i++){ db.test.insert({ username: 'user' + i, idNum: i }) }
這時候以username爲片鍵,經過sh.shardCollection
方法進行創建,它的語法爲:
sh.shardCollection(namespace, key, unique, options)
首先給咱們要創建的片鍵創建索引:
> db.test.ensureIndex({'username': 1});
而後創建片鍵:
> sh.shardCollection('test.test', {username:1});
等待幾分鐘後,能夠經過sh.status
方法查看數據分片的狀況了,能夠從中很清楚的看見哪些數據在哪一個分片服務器上面,而且經過explain
方法來查看咱們查詢的過程當中哪些分片服務器參與了查詢。
打開vs,使用nuget下載驅動
打開https://github.com/yswenli/MongoDBOperator/releases下載二次驅動封裝庫
打開app.config或web.config填寫mongo鏈接配置
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <connectionStrings> 4 <add name="MongoServerSettings" connectionString="mongodb://admin:admin@localhost:27017/MongoTests?authSource=admin" /> 5 </connectionStrings> 6 </configuration>
如下是測試代碼:
1 /***************************************************************************************************** 2 * 本代碼版權歸@wenli全部,All Rights Reserved (C) 2015-2017 3 ***************************************************************************************************** 4 * CLR版本:4.0.30319.42000 5 * 惟一標識:63fcdf18-8930-4a86-93ca-f99f5a020844 6 * 機器名稱:WENLI-PC 7 * 聯繫人郵箱:wenguoli_520@qq.com 8 ***************************************************************************************************** 9 * 項目名稱:$projectname$ 10 * 命名空間:MongoDBOperator.Test 11 * 類名稱:Program 12 * 建立時間:2017/7/13 16:00:44 13 * 建立人:wenli 14 * 建立說明: 15 *****************************************************************************************************/ 16 17 using System; 18 using System.Linq; 19 using System.Threading.Tasks; 20 using MongoDBOperator.Interface; 21 using MongoDBOperator.Test.Model; 22 23 namespace MongoDBOperator.Test 24 { 25 class Program 26 { 27 static void Main(string[] args) 28 { 29 Console.Title = "MongoDBOperator.Test"; 30 31 IOperator<Account> customerOperator = new MongoOperator<Account>(); 32 33 34 var account = new Account(); 35 account.FirstName = "li"; 36 account.LastName = "wen"; 37 account.Phone = "13800138000"; 38 account.Email = "wenguoli_520@qq.com"; 39 account.HomeAddress = new Address 40 { 41 Address1 = "上海", 42 Address2 = "徐匯", 43 PostCode = "210001", 44 City = "上海", 45 Country = "中國" 46 }; 47 48 Console.WriteLine("Create"); 49 50 customerOperator.Add(account); 53 54 Console.WriteLine("Read"); 55 56 var c = customerOperator.Where(b => b.FirstName == "li").FirstOrDefault(); 57 58 Console.WriteLine("Update"); 59 60 c.FirstName = "guo li"; 61 62 customerOperator.Update(c); 63 64 Console.WriteLine("Delete"); 65 66 customerOperator.Delete(c); 67 68 customerOperator.DeleteAll(); 69 70 Console.ReadLine(); 71 72 } 73 } 74 }
vs調試效果以下:
轉載請標明本文來源:http://www.cnblogs.com/yswenli/p/7421909.html
更多內容歡迎star做者的github:https://github.com/yswenli/MongoDBOperator若是發現本文有什麼問題和任何建議,也隨時歡迎交流~