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

好久没过来吹牛了,2018的双十一快来了,接下来就要面临双十一这场惊心动魄的处女秀考验

我们项目中会有一个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“列表即可,核心代码如下:

1staticMongoDBHelper()

2{

3varips = connectionString.Split(';');

4

5varservicesList =newList();

6

7foreach(varipinips)

8{

9varhost = ip.Split(':')[];

10varport = Convert.ToInt32(ip.Split(':')[1]);

11

12servicesList.Add(newMongoServerAddress(host, port));

13}

14

15setting =newMongoClientSettings();

16setting.ReplicaSetName ="datamip";

17

18//集群中的服务器列表

19setting.Servers =servicesList;

20}

其中ips的信息是配置在app.config中。

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

1namespaceDataMipCRM.Common

2{

3publicclassMongoDBHelper

4{

5privatestaticreadonlystringconnectionString = ConfigurationManager.AppSettings["mongodbServerList"];

6

7staticMongoClientSettings setting =null;

8MongoServer server =null;

9

10publicstringtableName ="person";

11

12publicstringdatabaseName ="test";

13

14staticMongoDBHelper()

15{

16varips = connectionString.Split(';');

17

18varservicesList =newList();

19

20foreach(varipinips)

21{

22varhost = ip.Split(':')[];

23varport = Convert.ToInt32(ip.Split(':')[1]);

24

25servicesList.Add(newMongoServerAddress(host, port));

26}

27

28setting =newMongoClientSettings();

29setting.ReplicaSetName ="datamip";

30

31//集群中的服务器列表

32setting.Servers =servicesList;

33}

34

35publicMongoDBHelper(stringdatabaseName,stringtableName)

36{

37this.databaseName =databaseName;

38this.tableName =tableName;

39

40server =newMongoClient(setting).GetServer();

41}

42

43publicboolRemove(Expression>func)

44{

45try

46{

47vardatabase =server.GetDatabase(databaseName);

48

49varcollection = database.GetCollection(tableName);

50

51varquery = Query.Where(func);

52

53varresult =collection.Remove(query);

54

55returnresult.Response["ok"].AsInt32 >?true:false;

56}

57catch(Exception ex)

58{

59returnfalse;

60}

61}

62

63publicboolRemoveAll()

64{

65try

66{

67vardatabase = server.GetDatabase(databaseName);//mongodb中的数据库

68

69varcollection = database.GetCollection(tableName);

70

71varresult =collection.RemoveAll();

72

73returnresult.Response["ok"].AsInt32 >?true:false;

74}

75catch(Exception ex)

76{

77returnfalse;

78}

79}

80

81#region单条插入

82///

83///单条插入

84///

85///

86///

87publicboolInsert(T t)

88{

89try

90{

91vardatabase = server.GetDatabase(databaseName);//mongodb中的数据库

92

93varcollection = database.GetCollection(tableName);

94

95varresult =collection.Insert(t);

96returnresult.DocumentsAffected >;

97}

98catch(Exception ex)

99{

100returnfalse;

101}

102}

103#endregion

104

105#region单条覆盖,如果不存在插入,如果存在覆盖

106///

107///单条覆盖,如果不存在插入,如果存在覆盖

108///

109///

110///

111publicboolSave(T t)

112{

113try

114{

115vardatabase = server.GetDatabase(databaseName);//mongodb中的数据库

116

117varcollection = database.GetCollection(tableName);

118varresult =collection.Save(t);

119returnresult.DocumentsAffected >;

120}

121catch(Exception ex)

122{

123returnfalse;

124}

125}

126#endregion

127

128#region批量插入

129///

130///批量插入

131///

132///

133///

134publicboolInsert(IEnumerablet)

135{

136try

137{

138vardatabase = server.GetDatabase(databaseName);//mongodb中的数据库

139

140varcollection = database.GetCollection(tableName);

141

142collection.InsertBatch(t);

143

144returntrue;

145}

146catch(Exception ex)

147{

148returnfalse;

149}

150}

151#endregion

152

153#region批量查询

154

155publicList Search(Expression> func,boolforcemaster =false)

156{

157varlist =newList();

158

159try

160{

161//是否强制使用 “主服务器”

162if(forcemaster)

163{

164vardatabase = server.GetDatabase(databaseName);//mongodb中的数据库

165

166varcollection = database.GetCollection(tableName);

167list = collection.Find(Query.Where(func)).ToList();

168}

169else

170{

171vardatabase = server.GetDatabase(databaseName);//mongodb中的数据库

172

173varcollection = database.GetCollection(tableName);

174

175list = collection.Find(Query.Where(func)).ToList();

176}

177}

178catch(Exception ex)

179{

180throw;

181}

182

183returnlist;

184}

185

186#endregion

187

188#region单条查询

189///

190///单条查询

191///

192publicT SearchOne(Expression> func,boolforcemaster =false)

193{

194T t =default(T);

195

196try

197{

198if(forcemaster)

199{

200vardatabase = server.GetDatabase(databaseName);//mongodb中的数据库

201

202varcollection = database.GetCollection(tableName);

203

204t = collection.FindOne(Query.Where(func));

205}

206else

207{

208vardatabase = server.GetDatabase(databaseName);//mongodb中的数据库

209

210varcollection = database.GetCollection(tableName);

211

212t = collection.FindOne(Query.Where(func));

213}

214

215returnt;

216}

217catch(Exception ex)

218{

219returnt;

220}

221}

222#endregion

223

224///

225///查询所有数据

226///

227///

228publicListSearchAll()

229{

230varlist =newList();

231

232try

233{

234vardatabase = server.GetDatabase(databaseName);//mongodb中的数据库

235

236varcollection = database.GetCollection(tableName);

237

238list =collection.FindAll().ToList();

239

240returnlist;

241}

242catch(Exception ex)

243{

244returnlist;

245}

246}

247}

248}

四:测试一下

1. 首先向mongodb中插入一条记录,dbname=mydb, tablename=test,插入后我们用mongodUVE看一下数据:

1namespaceConsoleApplication2

2{

3classProgram

4{

5staticvoidMain(string[] args)

6{

7MongoDBHelper helper =newMongoDBHelper("mydb","test");

8

9helper.Save(newMongodbCustomerModel()

10{

11SendLastTime =DateTime.Now,

12ShopID =1

13});

14}

15}

16

17publicclassMongodbCustomerModel

18{

19publicObjectId _id {get;set; }

20

21publicintShopID {get;set; }

22

23publicDateTime SendLastTime {get;set; }

24}

25}

2. 然后我把【27000】 这个primary关闭掉,通过rs.Status看看“主备情况”。

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

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

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180621G1XHWM00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券