博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
双十一来了,别让你的mongodb宕机了
阅读量:5773 次
发布时间:2019-06-18

本文共 8067 字,大约阅读时间需要 26 分钟。

 

        好久没过来吹牛了,前段时间一直赶项目,没有时间来更新博客,项目也终于赶完了,接下来就要面临双十一这场惊心动魄的处女秀考验,

我们项目中会有一个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。

 

db.runCommand({    "replSetInitiate":{        "_id":"datamip",        "members":[            {                "_id":1,                "host":"127.0.0.1:27000"            },            {                "_id":2,                "host":"127.0.0.1:27001"            }        ]    }}) 

 

配置完了之后,然后我们把“仲裁服务器【27002】”加入到“datamip”这个双机热备分集群中。

 

rs.addArb( { host: "127.0.0.1:27002"} )

 

这个命令可以参考下官网的介绍: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 #endregion104 105 #region 单条覆盖,如果不存在插入,如果存在覆盖106 ///
107 /// 单条覆盖,如果不存在插入,如果存在覆盖108 /// 109 ///
110 ///
111 public bool Save(T t)112 {113 try114 {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 #endregion127 128 #region 批量插入129 ///
130 /// 批量插入131 /// 132 ///
133 ///
134 public bool Insert(IEnumerable
t)135 {136 try137 {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 #endregion152 153 #region 批量查询154 155 public List
Search(Expression
> func, bool forcemaster = false)156 {157 var list = new List
();158 159 try160 {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 else170 {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 #endregion187 188 #region 单条查询189 ///
190 /// 单条查询191 /// 192 public T SearchOne(Expression
> func, bool forcemaster = false)193 {194 T t = default(T);195 196 try197 {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 else207 {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 #endregion223 224 ///
225 /// 查询所有数据226 /// 227 ///
228 public List
SearchAll()229 {230 var list = new List
();231 232 try233 {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 = 113 });14 }15 }16 17 public class MongodbCustomerModel18 {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://uzaux.baihongyu.com/

你可能感兴趣的文章
About Me
查看>>
Linux-grep命令
查看>>
一秒去除Win7快捷方式箭头
查看>>
Oracle序列使用:建立、删除
查看>>
html5 渐变按钮练习
查看>>
ES8 (2017)新特性
查看>>
由创建文件想起的。。。
查看>>
数据字典生成工具之旅(2):数据字典生成工具及文档工具作用介绍
查看>>
asp.net(C#)去除html格式
查看>>
构建之法读后感part1
查看>>
Linux内存管理(二)
查看>>
duilib+cef自定义浏览器控件编译错误
查看>>
PF_RING 总结
查看>>
Java字符串中常用字符占用字节数
查看>>
(原创)Python字符串系列(1)——str对象
查看>>
离散化
查看>>
UVALive 5052 Genome Evolution ——(xjbg)
查看>>
OpenCV学习系列教程第四篇:图像的算术操作
查看>>
虚拟环境建立相关操作
查看>>
一篇文章
查看>>