手记

双十一来了,别让你的mongodb宕机了

 

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

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

 <appSettings>    <add key="mongodbServerList" value="127.0.0.1:27000;127.0.0.1:27001;127.0.0.1:27002"/>  </appSettings>

 

然后我简单的封装了下mongodb。

  1 namespace DataMipCRM.Common  2 {  3     public class MongoDBHelper<T>  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<MongoServerAddress>(); 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<T, bool>> func) 44         { 45             try 46             { 47                 var database = server.GetDatabase(databaseName); 48  49                 var collection = database.GetCollection<T>(tableName); 50  51                 var query = Query<T>.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<T>(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         /// <summary> 83         /// 单条插入 84         /// </summary> 85         /// <typeparam name="T"></typeparam> 86         /// <param name="t"></param> 87         public bool Insert(T t) 88         { 89             try 90             { 91                 var database = server.GetDatabase(databaseName);   //mongodb中的数据库 92  93                 var collection = database.GetCollection<T>(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         /// <summary>107         /// 单条覆盖,如果不存在插入,如果存在覆盖108         /// </summary>109         /// <typeparam name="T"></typeparam>110         /// <param name="t"></param>111         public bool Save(T t)112         {113             try114             {115                 var database = server.GetDatabase(databaseName);   //mongodb中的数据库116 117                 var collection = database.GetCollection<T>(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         /// <summary>130         /// 批量插入131         /// </summary>132         /// <typeparam name="T"></typeparam>133         /// <param name="t"></param>134         public bool Insert(IEnumerable<T> t)135         {136             try137             {138                 var database = server.GetDatabase(databaseName);   //mongodb中的数据库139 140                 var collection = database.GetCollection<T>(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<T> Search(Expression<Func<T, bool>> func, bool forcemaster = false)156         {157             var list = new List<T>();158 159             try160             {161                 //是否强制使用 “主服务器”162                 if (forcemaster)163                 {164                     var database = server.GetDatabase(databaseName);   //mongodb中的数据库165 166                     var collection = database.GetCollection<T>(tableName);167                     list = collection.Find(Query<T>.Where(func)).ToList();168                 }169                 else170                 {171                     var database = server.GetDatabase(databaseName);    //mongodb中的数据库172 173                     var collection = database.GetCollection<T>(tableName);174 175                     list = collection.Find(Query<T>.Where(func)).ToList();176                 }177             }178             catch (Exception ex)179             {180                 throw;181             }182 183             return list;184         }185 186         #endregion187 188         #region 单条查询189         /// <summary>190         /// 单条查询191         /// </summary>192         public T SearchOne(Expression<Func<T, bool>> 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<T>(tableName);203 204                     t = collection.FindOne(Query<T>.Where(func));205                 }206                 else207                 {208                     var database = server.GetDatabase(databaseName);   //mongodb中的数据库209 210                     var collection = database.GetCollection<T>(tableName);211 212                     t = collection.FindOne(Query<T>.Where(func));213                 }214 215                 return t;216             }217             catch (Exception ex)218             {219                 return t;220             }221         }222         #endregion223 224         /// <summary>225         /// 查询所有数据226         /// </summary>227         /// <returns></returns>228         public List<T> SearchAll()229         {230             var list = new List<T>();231 232             try233             {234                 var database = server.GetDatabase(databaseName);    //mongodb中的数据库235 236                 var collection = database.GetCollection<T>(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<MongodbCustomerModel> helper = new MongoDBHelper<MongodbCustomerModel>("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中获取到刚才插入的数据,好了,大概就说这么多,洗洗睡了,

 

最后祝顶着双十一压力的兄弟们,一路平安。

 

--文件下载--

0人推荐
随时随地看视频
慕课网APP