双十一来了,别让你的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”这个双机热备分集群中。

好了,现在大致配置好了,接下来我们用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         #endregion
104
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             try
114             {
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         #endregion
127
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             try
137             {
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         #endregion
152
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             try
160             {
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                 else
170                 {
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         #endregion
187
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             try
197             {
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                 else
207                 {
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         #endregion
223
224         /// <summary>
225         /// 查询所有数据
226         /// </summary>
227         /// <returns></returns>
228         public List<T> SearchAll()
229         {
230             var list = new List<T>();
231
232             try
233             {
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 }

四:测试一下

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 = 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. 然后我把【27001】 这个primary关闭掉,通过rs.Status看看“主备情况”。

3. 接下来,我们继续用mongodbHelper执行一下search,看是否能捞取到数据,如果可以,说明一台机器挂了没关系,这个“主备集群”还是活的。

是不是很牛逼的感觉,虽然挂了一台,我的客户端程序还是可以继续从mognodb中获取到刚才插入的数据,好了,大概就说这么多,洗洗睡了,

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

--文件下载--

时间: 2024-10-21 08:53:13

双十一来了,别让你的mongodb宕机了的相关文章

MongoDB 宕机案例

2015年7月27日  帮助朋友解决公司MongoDB 宕机案例 对于数据库 选型很重要.公司内部要建立自身知识库,在没有发生问题前 做好判断,提前预防故障.

MongoDB一次节点宕机引发的思考(源码剖析)

目录 简介 日志分析 副本集 如何实现 Failover 心跳的实现 electionTimeout 定时器 业务影响评估 参考链接 声明:本文同步发表于 MongoDB 中文社区,传送门: http://www.mongoing.com/archives/26759 简介 最近一个 MongoDB 集群环境中的某节点异常下电了,导致业务出现了中断,随即又恢复了正常. 通过ELK 告警也监测到了业务报错日志. 运维部对于节点下电的原因进行了排查,发现仅仅是资源分配上的一个失误导致. 在解决了问题

MongoDB 3.2.9 关于安全认证后使用C#调用碰上的相关问题

由于项目需要MongoDB做为存储数据库,在学习过程碰上疑难杂症,心痛如海,故此终于开始书写博客之路. 操作MongoDB类库版本: ---------------------------------------------- MongoDB.Driver 2.3 MongoDB.Driver.Core 2.3 MongoDB.Bson 2.3 MongoDB 版本 3.2.9 参考相关学习链接(转载):---------------------------------------------

转:MongoDB 那些坑

原文:https://ruby-china.org/topics/20128 MongoDB 是目前炙手可热的 NoSQL 文档型数据库,它提供的一些特性很棒:如自动 failover 机制,自动 sharding,无模式 schemaless,大部分情况下性能也很棒.但是薄荷在深入使用 MongoDB 过程中,遇到了不少问题,下面总结几个我们遇到的坑.特别申明:我们目前用的 MongoDB 版本是 2.4.10,曾经升级到 MongoDB 2.6.0 版本,问题依然存在,又回退到 2.4.10

MongoDB 那些坑(转)

MongoDB 是目前炙手可热的 NoSQL 文档型数据库,它提供的一些特性很棒:如自动 failover 机制,自动 sharding,无模式 schemaless,大部分情况下性能也很棒.但是薄荷在深入使用 MongoDB 过程中,遇到了不少问题,下面总结几个我们遇到的坑.特别申明:我们目前用的 MongoDB 版本是 2.4.10,曾经升级到 MongoDB 2.6.0 版本,问题依然存在,又回退到 2.4.10 版本. MongoDB 数据库级锁 坑爹指数:5星(最高5星) MongoD

一条命令搞垮MongoDB实例

一条命令搞垮MongoDB实例 背景 Part1:写在最前 在副本集架构中,我们会经常通过rs.add(),rs.remove()命令来调整后台数据库架构,在本案例中,我们异常的触发到了一个MongoDB的BUG,并尽快的找到了官方的人进行咨询.在生产环境中,我们做实例迁移,将研发自行维护的MongoDB副本集迁移至DBA管理,由于硬件和版本都不符合规范,因此我们对集群先进行了升级处理,又使用了rs.add()和rs.remove()来完成数据库的迁移工作. Part2:背景 在研发自行维护的数

MongoDB中的一些坑(最好不要用)

MongoDB 是目前炙手可热的 NoSQL 文档型数据库,它提供的一些特性很棒:如自动 failover 机制,自动 sharding,无模式 schemaless,大部分情况下性能也很棒.但是薄荷在深入使用 MongoDB 过程中,遇到了不少问题,下面总结几个我们遇到的坑.特别申明:我们目前用的 MongoDB 版本是 2.4.10,曾经升级到 MongoDB 2.6.0 版本,问题依然存在,又回退到 2.4.10 版本. MongoDB 数据库级锁 坑爹指数:5星(最高5星) MongoD

上周热点回顾(10.12-10.18)

热点随笔: · 支付宝Cookie高危漏洞引发的思考(batsing)· 架构之路(五):忘记数据库(自由飞)· 从网易与淘宝的font-size思考前端设计稿与工作流(流云诸葛)· 天猫双十一狂抢优惠券?机智的程序猿这么玩(vajoy)· 将知识变成你的技能点(xiaotie)· 双十一来了,别让你的mongodb宕机了(一线码农)· Web开发人员必读的12个网站(葡萄城控件技术团队)· 人无梦想,那和咸鱼有何区别!(果冻迪迪)· 喜欢计算机的孩子们啊,勇敢地攀登,是登顶的唯一途径!(Ice

[转载] Redis

转载:http://snowolf.iteye.com/blog/1630697 大约一年多前,公司同事开始使用Redis,不清楚是配置,还是版本的问题,当时的Redis经常在使用一段时间后,连接爆满且不释放.印象中,Redis 2.4.8以下的版本由于设计上的主从库同步问题,就会导致整个问题,不知是否确为这个Bug所致.但从那以后,我就很少敢去尝试使用Redis.曾想转投MongoDB,但公司同事给我的回复是,由于MongoDB宕机,数据丢失,公司损失惨重.于是,我一直停留在Memcached