好久没过来吹牛了,前段时间一直赶项目,没有时间来更新博客,项目也终于赶完了,接下来就要面临双十一这场惊心动魄的处女秀考验,
我们项目中会有一个wcf集群,而集群地址则放在mongodb中,所以mongodb的核心地位可想而知,如果mongodb挂掉,整个项目也就陷入
瘫痪,想让mongodb不宕机,最简单的方法就是要做双机热备,跟传统的关系型数据库的双机热备模式一样,一个主服务器,一个备份服务器,
一个仲裁服务器。如果热备集群中的主服务器宕掉,会有仲裁服务器参与投票来选出一台作为主服务器,我想这个大家都比较清楚,下面我们来
实战一下,最后会奉献源代码。
一:搭建mongodb热备集群
1. 准备工作
为了做到最简化搭建,我就做一个主,一个备,一个仲裁就好了,然后最简化配置信息都放在mongodb.conf文件中,如下图:
从上图中可以看到,三个mongodb,我建立了对应的三个文件夹来存放对应的三个db,其中“主服务器”的端口为27000,“备服务器“的端口为
27001,”仲裁服务器“端口为27002。 具体mongodb.conf内容如下:
2. 开启 “主服务器” 【27000】
3. 开启 “备服务器” 【27001】
4. 开启 “仲裁服务器” 【27002】
现在三台服务器都开启起来了,细心的你会发现,三个控制台都有这么一段英文单词” replSet info you may need to run replSetInitiate“。。。
既然都这么说了,我现在就去run这个func。
配置完了之后,然后我们把“仲裁服务器【27002】”加入到“datamip”这个双机热备分集群中。
这个命令可以参考下官网的介绍:https://docs.mongodb.com/manual/reference/command/replSetInitiate/ 好了,现在大致配置好了,接下
来我们用rs.Status()来查看下当前“主,备,仲裁”的分布情况。
从图中你应该看到了【27000】成为了主服务器,【27001】成为了备服务器,【27002】成为了仲裁服务器,到目前为止,搭建完成,是不是有
一个很爽的感觉呢???
三:使用驱动
既然mongodb的双机热备已经做好了,我们驱动也必须支持,这样我们才能够嗨,对伐???其实在配置中使用也很简单,里面有一个
MongoClientSettings,你需要配置一下”ReplicaSetName“和”Servers“列表即可,核心代码如下:
1 static MongoDBHelper()
2 {
3 var ips = connectionString.Split(';');
4
5 var servicesList = new List();
6
7 foreach (var ip in ips)
8 {
9 var host = ip.Split(':')[0];
10 var port = Convert.ToInt32(ip.Split(':')[1]);
11
12 servicesList.Add(new MongoServerAddress(host, port));
13 }
14
15 setting = new MongoClientSettings();
16 setting.ReplicaSetName = "datamip";
17
18 //集群中的服务器列表
19 setting.Servers = servicesList;
20 }
其中ips的信息是配置在app.config中。
然后我简单的封装了下mongodb。
1 namespace DataMipCRM.Common
2 {
3 public class MongoDBHelper
4 {
5 private static readonly string connectionString = ConfigurationManager.AppSettings["mongodbServerList"];
6
7 static MongoClientSettings setting = null;
8 MongoServer server = null;
9
10 public string tableName = "person";
11
12 public string databaseName = "test";
13
14 static MongoDBHelper()
15 {
16 var ips = connectionString.Split(';');
17
18 var servicesList = new List();
19
20 foreach (var ip in ips)
21 {
22 var host = ip.Split(':')[0];
23 var port = Convert.ToInt32(ip.Split(':')[1]);
24
25 servicesList.Add(new MongoServerAddress(host, port));
26 }
27
28 setting = new MongoClientSettings();
29 setting.ReplicaSetName = "datamip";
30
31 //集群中的服务器列表
32 setting.Servers = servicesList;
33 }
34
35 public MongoDBHelper(string databaseName, string tableName)
36 {
37 this.databaseName = databaseName;
38 this.tableName = tableName;
39
40 server = new MongoClient(setting).GetServer();
41 }
42
43 public bool Remove(Expression> func)
44 {
45 try
46 {
47 var database = server.GetDatabase(databaseName);
48
49 var collection = database.GetCollection(tableName);
50
51 var query = Query.Where(func);
52
53 var result = collection.Remove(query);
54
55 return result.Response["ok"].AsInt32 > 0 ? true : false;
56 }
57 catch (Exception ex)
58 {
59 return false;
60 }
61 }
62
63 public bool RemoveAll()
64 {
65 try
66 {
67 var database = server.GetDatabase(databaseName); //mongodb中的数据库
68
69 var collection = database.GetCollection(tableName);
70
71 var result = collection.RemoveAll();
72
73 return result.Response["ok"].AsInt32 > 0 ? true : false;
74 }
75 catch (Exception ex)
76 {
77 return false;
78 }
79 }
80
81 #region 单条插入
82 ///
83 /// 单条插入
84 ///
85 ///
86 ///
87 public bool Insert(T t)
88 {
89 try
90 {
91 var database = server.GetDatabase(databaseName); //mongodb中的数据库
92
93 var collection = database.GetCollection(tableName);
94
95 var result = collection.Insert(t);
96 return result.DocumentsAffected > 0;
97 }
98 catch (Exception ex)
99 {
100 return false;
101 }
102 }
103 #endregion
104
105 #region 单条覆盖,如果不存在插入,如果存在覆盖
106 ///
107 /// 单条覆盖,如果不存在插入,如果存在覆盖
108 ///
109 ///
110 ///
111 public bool Save(T t)
112 {
113 try
114 {
115 var database = server.GetDatabase(databaseName); //mongodb中的数据库
116
117 var collection = database.GetCollection(tableName);
118 var result = collection.Save(t);
119 return result.DocumentsAffected > 0;
120 }
121 catch (Exception ex)
122 {
123 return false;
124 }
125 }
126 #endregion
127
128 #region 批量插入
129 ///
130 /// 批量插入
131 ///
132 ///
133 ///
134 public bool Insert(IEnumerable t)
135 {
136 try
137 {
138 var database = server.GetDatabase(databaseName); //mongodb中的数据库
139
140 var collection = database.GetCollection(tableName);
141
142 collection.InsertBatch(t);
143
144 return true;
145 }
146 catch (Exception ex)
147 {
148 return false;
149 }
150 }
151 #endregion
152
153 #region 批量查询
154
155 public List Search(Expression> func, bool forcemaster = false)
156 {
157 var list = new List();
158
159 try
160 {
161 //是否强制使用 “主服务器”
162 if (forcemaster)
163 {
164 var database = server.GetDatabase(databaseName); //mongodb中的数据库
165
166 var collection = database.GetCollection(tableName);
167 list = collection.Find(Query.Where(func)).ToList();
168 }
169 else
170 {
171 var database = server.GetDatabase(databaseName); //mongodb中的数据库
172
173 var collection = database.GetCollection(tableName);
174
175 list = collection.Find(Query.Where(func)).ToList();
176 }
177 }
178 catch (Exception ex)
179 {
180 throw;
181 }
182
183 return list;
184 }
185
186 #endregion
187
188 #region 单条查询
189 ///
190 /// 单条查询
191 ///
192 public T SearchOne(Expression> func, bool forcemaster = false)
193 {
194 T t = default(T);
195
196 try
197 {
198 if (forcemaster)
199 {
200 var database = server.GetDatabase(databaseName); //mongodb中的数据库
201
202 var collection = database.GetCollection(tableName);
203
204 t = collection.FindOne(Query.Where(func));
205 }
206 else
207 {
208 var database = server.GetDatabase(databaseName); //mongodb中的数据库
209
210 var collection = database.GetCollection(tableName);
211
212 t = collection.FindOne(Query.Where(func));
213 }
214
215 return t;
216 }
217 catch (Exception ex)
218 {
219 return t;
220 }
221 }
222 #endregion
223
224 ///
225 /// 查询所有数据
226 ///
227 ///
228 public List SearchAll()
229 {
230 var list = new List();
231
232 try
233 {
234 var database = server.GetDatabase(databaseName); //mongodb中的数据库
235
236 var collection = database.GetCollection(tableName);
237
238 list = collection.FindAll().ToList();
239
240 return list;
241 }
242 catch (Exception ex)
243 {
244 return list;
245 }
246 }
247 }
248 }
View Code
四:测试一下
1. 首先向mongodb中插入一条记录,dbname=mydb, tablename=test,插入后我们用mongodUVE看一下数据:
1 namespace ConsoleApplication2
2 {
3 class Program
4 {
5 static void Main(string[] args)
6 {
7 MongoDBHelper helper = new MongoDBHelper("mydb", "test");
8
9 helper.Save(new MongodbCustomerModel()
10 {
11 SendLastTime = DateTime.Now,
12 ShopID = 1
13 });
14 }
15 }
16
17 public class MongodbCustomerModel
18 {
19 public ObjectId _id { get; set; }
20
21 public int ShopID { get; set; }
22
23 public DateTime SendLastTime { get; set; }
24 }
25 }
2. 然后我把【27000】 这个primary关闭掉,通过rs.Status看看“主备情况”。
3. 接下来,我们继续用mongodbHelper执行一下search,看是否能捞取到数据,如果可以,说明一台机器挂了没关系,这个“主备集群”还是活的。
是不是很牛逼的感觉,虽然挂了一台,我的客户端程序还是可以继续从mognodb中获取到刚才插入的数据,好了,大概就说这么多,洗洗睡了,
最后祝顶着双十一压力的兄弟们,一路平安。
–文件下载–
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.e1idc.net