一、搭建Mongodb 副本集
副本集中有三個角色:
主節點:所有副節點的資料均來自于主節點,并且隻能對主節點進行讀寫操作。
副節點:資料來自于主節點,可以進行讀取操作,但是不能進行寫操作。
仲裁者:不含資料也不與用戶端交流,隻在選舉主節點的時候進行投票。
Mongodb最多支援50個副本內建員以及最多7個選舉成員,啟動副本集後将開始第一次選舉,在選舉過程中,所有副本內建員都隻能讀取,直到選舉出主節點後主節點才能進行讀寫,但是在這個期間副本成員可以提供查詢服務。
而主節點要保持主節點的位置需要每兩秒發送一個ping請求,如果10秒内沒有得到響應則标記為不可通路,當一半以上的副本內建員不可通路,那麼主節點将降級為副節點。
其中設定成員的priority值可以優先成員主節點,這個值介于0-1000之間,預設為1,如果這個值為0,那麼它的votes值也為0,隻要votes為0的成員不能投選舉票,但是可以投否決票。但是我們也可以手動設定成員priority值為大于1的成員是否有投票權利。
在進行選舉的時候,其他成員會作以下幾點判斷來進行投票參與選舉的成員是否能作為主節點,選舉步驟:
自己是否能與主節點通訊。
參與選舉的成員是否比其他參與選舉的成員資料最新。
如果參與選舉的成員資料相等則嘗試使用具有最高priority的值的成員。
仲裁者
仲裁者的出現是為了避免隻有兩個成員的副本集,兩個成員的副本集投票可能無法滿足一半以上的投票情況。
仲裁者不負責資料和用戶端交流,隻有參與選舉的功能,需要注意的是仲裁者一旦設定過後就再也無法變為非仲裁者了。
首先部署一個副本集很簡單,下面的代碼是部署了一個本地含有三個成員的副本集。
建立三個成員的副本集,首先你得建立三個資料庫的存放目錄:
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的成員中,并配置副本集。
進入到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,來讓目前成員滞後多少秒後才開始複制資料。
> slaveDelay: 120,
索引管理
通過成員的buildIndexes的值并且優先值priority為0,來設定是否在備份機器上建立相同的索引,一般這個選項隻用于純粹備份的伺服器。
下面的代碼設定添加的副本內建員不建立索引。
> buildIndexes: false
二、搭建配置伺服器
首先搭建配置伺服器,配置伺服器如同分片的大腦,儲存着叢集和資料的描述資訊。
因為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
方法來檢視我們查詢的過程中哪些分片伺服器參與了查詢。
六使用MongoDB
下載下傳驅動
打開vs,使用nuget下載下傳驅動
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcukTZmNDZlFzYkJGMjFGNxUzYhRjZhRjNjFjN3QGOiRWZfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
下載下傳驅動封裝庫
打開
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>
測試CS代碼
以下是測試代碼:
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 * 聯系人郵箱:[email protected]
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 = "[email protected]";
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 如果發現本文有什麼問題和任何建議,也随時歡迎交流~
感謝您的閱讀,如果您對我的部落格所講述的内容有興趣,請繼續關注我的後續部落格,我是yswenli 。