MongoDB副本(一主一备+仲裁)环境部署记录

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介:

MongoDB复制集是一个带有故障转移的主从集群。是从现有的主从模式演变而来,增加了自动故障转移和节点成员自动恢复。
MongoDB复制集模式中没有固定的主结点,在启动后,多个服务节点间将自动选举产生一个主结点。该主结点被称为primary,一个或多个从结点被称为secondaries。
primary结点基本上就是master结点,不同之处在于primary结点在不同时间可能是不同的服务器。如果当前的主结点失效了,复制集中的其余结点将会试图选出一个
新的主结点。

MongoDB复制集模式的好处:

  • 一切自动化。首先,复制集模式本身做了大量的管理工作,自动管理从节点,确保数据不会不一致。
  • 主节点挂掉后,会自动判断集群中的服务器并进行故障转移,推举新的主节点。
  • 一个复制集集群支持1-7台服务器,在一个复制集中各个服务器数据保持完全一致。

在一个MongoDB复制集集群中,各个服务器有以下几种状态:

  • Primary 主节点,一个复制集有且仅有一台服务器处于Primary状态,只有主节点才对外提供读写服务。如果主节点挂掉,复制集将投票选出一个备节点成为新的主节点。
  • Secondary 备用节点,复制集允许有多台Secondary,每个备用节点的数据与主节点的数据是完全同步的。Recovering 恢复中,当复制集中某台服务器挂掉或者掉线后数据无法同步,重新恢复服务后从其他成员复制数据,这时就处于恢复过程,数据同步后,该节点又回到备用状态。
  • Arbiter 仲裁节点,该类节点可以不用单独存在,如果配置为仲裁节点,就主要负责在复本集中监控其他节点状态,投票选出主节点。该节点将不会用于存放数据。如果没有仲裁节点,那么投票工作将由所有节点共同进行。
  • Down 无效节点,当服务器挂掉或掉线时就会处于该状态。复制集的从节点读请求,也是在各个Driver层设置slaveOk的值来实现的。

如上介绍所知,mongodb中的复制可以在多台服务器中同步数据。复制提供了冗余和增加了数据的高可用性,防止单个节点易丢失数据的可能性,也可以用来进行读写分离提高客户端操作性能。复制集中各节点的mongodb实例有相同的数据集副本。主节点可以接收客户端所有写操作记录到日志中,从库复制主库的操作日志记录应用到其数据库中。一个客户端只能有一个主节点,如果主节点不可用(10秒内无法连接),复制集中将选一个成员节点作为主节点。

mongodb主备+仲裁的基本结构如下:

下面简单介绍下MongoDB 副本集的部署过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
1)服务器信息
sign-mongo01.wangshibo.cn  172.16.51.216   Primary
sign-mongo02.wangshibo.cn  172.16.51.217   Secondary
sign-mongo03.wangshibo.cn  172.16.51.218   Arbiter
 
三台服务器均设置好主机名,关闭iptables及selinux(略)
 
2)在3台服务器文件hosts文件中都添加以下3行:
[root@sign-mongo01 ~] # cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
172.16.51.216   sign-mongo01.wangshibo.cn
172.16.51.217   sign-mongo02.wangshibo.cn
172.16.51.218   sign-mongo03.wangshibo.cn
 
3)安装部署mongodb(三台机器都安装)
下载地址:https: //www .mongodb.org /dl/linux/x86_64-rhel62
[app@sign-mongo01 software]$  pwd
/data/software
[app@sign-mongo01 software]$  ls
mongodb-linux-x86_64-rhel62-v3.2-latest.tgz
[app@sign-mongo01 software]$  tar  -zvxf mongodb-linux-x86_64-rhel62-v3.2-latest.tgz
[app@sign-mongo01 software]$  mv  mongodb-linux-x86_64-rhel62-3.2.17-34-g4c1bae566c  /data/mongodb
[app@sign-mongo01 software]$  cd  /data/mongodb/
[app@sign-mongo01 mongodb]$  mkdir  data
[app@sign-mongo01 mongodb]$  mkdir  log
[app@sign-mongo01 mongodb]$ vim mongodb.conf
pidfilepath= /data/mongodb/log/mongod .pid
logpath= /data/mongodb/log/mongod .log
dbpath= /data/mongodb
logappend= true
bind_ip=172.16.51.216
port=27017
fork= true
replSet=rs0
 
备节点的mongodb.conf配置文件分别为:
[app@sign-mongo02 mongodb]$ vim mongodb.conf
pidfilepath= /data/mongodb/log/mongod .pid
logpath= /data/mongodb/log/mongod .log
dbpath= /data/mongodb
logappend= true
bind_ip=172.16.51.217
port=27018
fork= true
replSet=rs0
 
其中:replSet=rs0   #表示复制集名称:rs0
 
启动主备服务器的mongodb
[app@sign-mongo01 ~]$  /data/mongodb/bin/mongod  --config  /data/mongodb/mongodb .conf
about to fork child process, waiting  until  server is ready  for  connections.
forked process: 7317
child process started successfully, parent exiting
[app@sign-mongo01 mongodb]$  ps  -ef| grep  mongodb
app       7317     1  0 21:38 ?        00:00:00  /data/mongodb/bin/mongod  --config  /data/mongodb/mongodb .conf
app       7342  7254  0 21:38 pts /1     00:00:00  grep  mongodb
[app@sign-mongo01 mongodb]$  lsof  -i:27017
COMMAND  PID USER   FD   TYPE DEVICE SIZE /OFF  NODE NAME
mongod  7317  app    6u  IPv4  27011      0t0  TCP sign-mongo01.wangshibo.cn:27017 (LISTEN)
 
[app@sign-mongo02 mongodb]$  /data/mongodb/bin/mongod  --config  /data/mongodb/mongodb .conf
about to fork child process, waiting  until  server is ready  for  connections.
forked process: 9725
child process started successfully, parent exiting
[app@sign-mongo02 mongodb]$  lsof  -i:27018
COMMAND  PID USER   FD   TYPE DEVICE SIZE /OFF  NODE NAME
mongod  9725  app    6u  IPv4  27191      0t0  TCP sign-mongo02.wangshibo.cn:27018 (LISTEN)
 
设置mongodb的环变量
[root@sign-mongo01 src] # vim /etc/profile
......
export  PATH=$PATH: /data/mongodb/bin
[root@sign-mongo01 src] # source /etc/profile
 
登录到mongodb中:
[app@sign-mongo01 ~]$ mongo 172.16.51.216:27017
MongoDB shell version: 3.2.17-34-g4c1bae566c
connecting to: 172.16.51.216:27017 /test
Welcome to the MongoDB shell.
For interactive help,  type  "help" .
For  more  comprehensive documentation, see
     http: //docs .mongodb.org/
Questions? Try the support group
     http: //groups .google.com /group/mongodb-user
Server has startup warnings:
2017-11-22T21:38:18.063+0800 I CONTROL  [initandlisten]
2017-11-22T21:38:18.063+0800 I CONTROL  [initandlisten] ** WARNING:  /sys/kernel/mm/transparent_hugepage/enabled  is  'always' .
2017-11-22T21:38:18.063+0800 I CONTROL  [initandlisten] **        We suggest setting it to  'never'
2017-11-22T21:38:18.063+0800 I CONTROL  [initandlisten]
2017-11-22T21:38:18.063+0800 I CONTROL  [initandlisten] ** WARNING:  /sys/kernel/mm/transparent_hugepage/defrag  is  'always' .
2017-11-22T21:38:18.063+0800 I CONTROL  [initandlisten] **        We suggest setting it to  'never'
2017-11-22T21:38:18.063+0800 I CONTROL  [initandlisten]
>
 
初始化复制集:(集合为: "rs0"  ;第一个成员为: "sign-mongo01.wangshibo.cn:27017"
> rs.initiate({_id:  "rs0" ,members: [{ _id: 0 , host:  "sign-mongo01.wangshibo.cn:27017"  }]})
"ok"  : 1 }
rs0:OTHER>                     // 接着回车,显示这个节点为Primary主节点
rs0:PRIMARY>
 
接着添加另1个成员:
rs0:PRIMARY> rs.add( "sign-mongo02.wangshibo.cn:27018" )
"ok"  : 1 }
 
查看成员信息 (或者使用 db.isMaster() )
rs0:PRIMARY> rs.status()
{
     "set"  "rs0" ,
     "date"  : ISODate( "2017-11-22T13:55:28.446Z" ),
     "myState"  : 1,
     "term"  : NumberLong(1),
     "heartbeatIntervalMillis"  : NumberLong(2000),
     "members"  : [
         {
             "_id"  : 0,
             "name"  "sign-mongo01.wangshibo.cn:27017" ,
             "health"  : 1,
             "state"  : 1,
             "stateStr"  "PRIMARY" ,
             "uptime"  : 1031,
             "optime"  : {
                 "ts"  : Timestamp(1511358895, 1),
                 "t"  : NumberLong(1)
             },
             "optimeDate"  : ISODate( "2017-11-22T13:54:55Z" ),
             "infoMessage"  "could not find member to sync from" ,
             "electionTime"  : Timestamp(1511358843, 2),
             "electionDate"  : ISODate( "2017-11-22T13:54:03Z" ),
             "configVersion"  : 2,
             "self"  true
         },
         {
             "_id"  : 1,
             "name"  "sign-mongo02.wangshibo.cn:27018" ,
             "health"  : 1,
             "state"  : 2,
             "stateStr"  "SECONDARY" ,
             "uptime"  : 32,
             "optime"  : {
                 "ts"  : Timestamp(1511358895, 1),
                 "t"  : NumberLong(1)
             },
             "optimeDate"  : ISODate( "2017-11-22T13:54:55Z" ),
             "lastHeartbeat"  : ISODate( "2017-11-22T13:55:27.684Z" ),
             "lastHeartbeatRecv"  : ISODate( "2017-11-22T13:55:27.827Z" ),
             "pingMs"  : NumberLong(0),
             "configVersion"  : 2
         }
     ],
     "ok"  : 1
}
 
 
或者使用该方法查看,结果也是一样:
rs0:PRIMARY> use admin
switched to db admin
rs0:PRIMARY> db.runCommand( { replSetGetStatus : 1 } ) 
{
     "set"  "rs0" ,
     "date"  : ISODate( "2017-11-23T01:12:20.701Z" ),
     "myState"  : 1,
     "term"  : NumberLong(1),
     "heartbeatIntervalMillis"  : NumberLong(2000),
     "members"  : [
         {
             "_id"  : 0,
             "name"  "sign-mongo01.wangshibo.cn:27017" ,
             "health"  : 1,
             "state"  : 1,
             "stateStr"  "PRIMARY" ,
             "uptime"  : 41643,
             "optime"  : {
                 "ts"  : Timestamp(1511358895, 1),
                 "t"  : NumberLong(1)
             },
             "optimeDate"  : ISODate( "2017-11-22T13:54:55Z" ),
             "electionTime"  : Timestamp(1511358843, 2),
             "electionDate"  : ISODate( "2017-11-22T13:54:03Z" ),
             "configVersion"  : 2,
             "self"  true
         },
         {
             "_id"  : 1,
             "name"  "sign-mongo02.wangshibo.cn:27018" ,
             "health"  : 1,
             "state"  : 2,
             "stateStr"  "SECONDARY" ,
             "uptime"  : 40645,
             "optime"  : {
                 "ts"  : Timestamp(1511358895, 1),
                 "t"  : NumberLong(1)
             },
             "optimeDate"  : ISODate( "2017-11-22T13:54:55Z" ),
             "lastHeartbeat"  : ISODate( "2017-11-23T01:12:19.418Z" ),
             "lastHeartbeatRecv"  : ISODate( "2017-11-23T01:12:16.225Z" ),
             "pingMs"  : NumberLong(0),
             "configVersion"  : 2
         }
     ],
     "ok"  : 1
}
rs0:PRIMARY>
 
详细说明如下:
"_id"  :   #集群中节点编号 
"name"  :   #成员服务器名称及端口 
"health"  :   #表示成员中的健康状态(0:down;1:up) 
"state"  :   #为0~10,表示成员的当前状态 
"stateStr"  :   #描述该成员是主库(PRIMARY)还是备库(SECONDARY) 
"uptime"  :   #该成员在线时间(秒) 
"optime"  :   #成员最后一次应用日志(oplog)的信息 
"optimeDate"  :   #成员最后一次应用日志(oplog)的时间 
"electionTime"  :   #当前primary从操作日志中选举信息 
"electionDate"  :   #当前primary被选定为primary的日期 
"configVersion"  :   #mongodb版本 
"self"  :   #为true 表示当前节点 
 
4)测试操作。在主库中,可以任意操作:
rs0:PRIMARY> show dbs
local   0.000GB
rs0:PRIMARY> use mydb       // 切换到要创建的数据库
switched to db mydb
rs0:PRIMARY> show dbs       //use 只是转到相关数据库,此时并没有做任何操作,所以并不会创建相应的数据库,只有当真正的操作了一次数据库就会自动创建。
local   0.000GB
rs0:PRIMARY> db.stats();
{
     "db"  "mydb" ,
     "collections"  : 0,
     "objects"  : 0,
     "avgObjSize"  : 0,
     "dataSize"  : 0,
     "storageSize"  : 0,
     "numExtents"  : 0,
     "indexes"  : 0,
     "indexSize"  : 0,
     "fileSize"  : 0,
     "ok"  : 1
}
rs0:PRIMARY> db.coll.insert({ "id" :1})
WriteResult({  "nInserted"  : 1 })
rs0:PRIMARY> db.coll. find ()
"_id"  : ObjectId( "5a162222991b83743942d169" ),  "id"  : 1 }
rs0:PRIMARY> db.coll.remove({ "id" :1})
WriteResult({  "nRemoved"  : 1 })
rs0:PRIMARY> show dbs
local   0.000GB
mydb   0.000GB
 
 
现在到备库中
172.16.51.217 (sign-mongo02.wangshibo.cn )
查看分库数据库目录,发现多了数据库,数据库与主库(172.16.51.216)一致!是主库同步过来的。
[app@sign-mongo02 ~]$ mongo 172.16.51.217:27018
MongoDB shell version: 3.2.17-34-g4c1bae566c
connecting to: 172.16.51.217:27018 /test
Server has startup warnings:
2017-11-22T21:46:38.417+0800 I CONTROL  [initandlisten]
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] ** WARNING:  /sys/kernel/mm/transparent_hugepage/enabled  is  'always' .
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] **        We suggest setting it to  'never'
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten]
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] ** WARNING:  /sys/kernel/mm/transparent_hugepage/defrag  is  'always' .
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] **        We suggest setting it to  'never'
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten]
 
在副本服务器中登录其本地数据库,发现可以连接,但是无法读写操作:
rs0:SECONDARY> show dbs
2017-11-23T09:25:35.961+0800 E QUERY    [thread1] Error: listDatabases failed:{  "ok"  : 0,  "errmsg"  "not master and slaveOk=false" "code"  : 13435 } :
_getErrorWithCode@src /mongo/shell/utils .js:25:13
Mongo.prototype.getDBs@src /mongo/shell/mongo .js:62:1
shellHelper.show@src /mongo/shell/utils .js:781:19
shellHelper@src /mongo/shell/utils .js:671:15
@(shellhelp2):1:1
rs0:SECONDARY>
 
从库开启读操作(此时可以测试主库插入,从库查看,同步正常):
rs0:SECONDARY> rs.slaveOk(); 
rs0:SECONDARY> show dbs
local   0.000GB
mydb   0.000GB
 
 
5)现在模拟主库不可用,将主节点服务停止:
[app@sign-mongo01 mongodb]$ pkill -9 mongod
[app@sign-mongo01 mongodb]$  ps  -ef| grep  mongodb
app       9524  9398  0 09:32 pts /0     00:00:00  grep  mongodb
 
到备节点172.16.51.217 中登录mongodb,查看复制集状态:
[app@sign-mongo02 ~]$ mongo 172.16.51.217:27018
MongoDB shell version: 3.2.17-34-g4c1bae566c
connecting to: 172.16.51.217:27018 /test
Server has startup warnings:
2017-11-22T21:46:38.417+0800 I CONTROL  [initandlisten]
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] ** WARNING:  /sys/kernel/mm/transparent_hugepage/enabled  is  'always' .
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] **        We suggest setting it to  'never'
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten]
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] ** WARNING:  /sys/kernel/mm/transparent_hugepage/defrag  is  'always' .
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] **        We suggest setting it to  'never'
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten]
rs0:SECONDARY> rs.status()
{
     "set"  "rs0" ,
     "date"  : ISODate( "2017-11-23T01:33:29.688Z" ),
     "myState"  : 2,
     "term"  : NumberLong(1),
     "heartbeatIntervalMillis"  : NumberLong(2000),
     "members"  : [
         {
             "_id"  : 0,
             "name"  "sign-mongo01.wangshibo.cn:27017" ,
             "health"  : 0,
             "state"  : 8,
             "stateStr"  "(not reachable/healthy)" ,
             "uptime"  : 0,
             "optime"  : {
                 "ts"  : Timestamp(0, 0),
                 "t"  : NumberLong(-1)
             },
             "optimeDate"  : ISODate( "1970-01-01T00:00:00Z" ),
             "lastHeartbeat"  : ISODate( "2017-11-23T01:33:28.732Z" ),
             "lastHeartbeatRecv"  : ISODate( "2017-11-23T01:32:28.099Z" ),
             "pingMs"  : NumberLong(0),
             "lastHeartbeatMessage"  "Connection refused" ,
             "configVersion"  : -1
         },
         {
             "_id"  : 1,
             "name"  "sign-mongo02.wangshibo.cn:27018" ,
             "health"  : 1,
             "state"  : 2,
             "stateStr"  "SECONDARY" ,
             "uptime"  : 42412,
             "optime"  : {
                 "ts"  : Timestamp(1511399985, 1),
                 "t"  : NumberLong(1)
             },
             "optimeDate"  : ISODate( "2017-11-23T01:19:45Z" ),
             "infoMessage"  "could not find member to sync from" ,
             "configVersion"  : 2,
             "self"  true
         }
     ],
     "ok"  : 1
}
 
有上面可看出,主节点删除服务进程,primary并没有切换到备节点上:
再次启动主节点的mongodb服务,发现primary才自动切换回到主节点:
[app@sign-mongo01 mongodb]$  nohup  /data/mongodb/bin/mongod  --config  /data/mongodb/mongodb .conf
nohup : ignoring input and appending output to ` nohup .out'
[app@sign-mongo01 mongodb]$  ps  -ef| grep  mongodb
app       9538     1  8 09:37 ?        00:00:00  /data/mongodb/bin/mongod  --config  /data/mongodb/mongodb .conf
app       9610  9398  0 09:37 pts /0     00:00:00  grep  mongodb
[app@sign-mongo01 mongodb]$ mongo 172.16.51.216:27017
MongoDB shell version: 3.2.17-34-g4c1bae566c
connecting to: 172.16.51.216:27017 /test
Server has startup warnings:
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten]
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] ** WARNING:  /sys/kernel/mm/transparent_hugepage/enabled  is  'always' .
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] **        We suggest setting it to  'never'
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten]
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] ** WARNING:  /sys/kernel/mm/transparent_hugepage/defrag  is  'always' .
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] **        We suggest setting it to  'never'
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten]
rs0:PRIMARY> rs.status()
{
     "set"  "rs0" ,
     "date"  : ISODate( "2017-11-23T01:38:19.631Z" ),
     "myState"  : 1,
     "term"  : NumberLong(2),
     "heartbeatIntervalMillis"  : NumberLong(2000),
     "members"  : [
         {
             "_id"  : 0,
             "name"  "sign-mongo01.wangshibo.cn:27017" ,
             "health"  : 1,
             "state"  : 1,
             "stateStr"  "PRIMARY" ,
             "uptime"  : 54,
             "optime"  : {
                 "ts"  : Timestamp(1511401058, 2),
                 "t"  : NumberLong(2)
             },
             "optimeDate"  : ISODate( "2017-11-23T01:37:38Z" ),
             "infoMessage"  "could not find member to sync from" ,
             "electionTime"  : Timestamp(1511401058, 1),
             "electionDate"  : ISODate( "2017-11-23T01:37:38Z" ),
             "configVersion"  : 2,
             "self"  true
         },
         {
             "_id"  : 1,
             "name"  "sign-mongo02.wangshibo.cn:27018" ,
             "health"  : 1,
             "state"  : 2,
             "stateStr"  "SECONDARY" ,
             "uptime"  : 53,
             "optime"  : {
                 "ts"  : Timestamp(1511401058, 2),
                 "t"  : NumberLong(2)
             },
             "optimeDate"  : ISODate( "2017-11-23T01:37:38Z" ),
             "lastHeartbeat"  : ISODate( "2017-11-23T01:38:18.072Z" ),
             "lastHeartbeatRecv"  : ISODate( "2017-11-23T01:38:18.596Z" ),
             "pingMs"  : NumberLong(0),
             "syncingTo"  "sign-mongo01.wangshibo.cn:27017" ,
             "configVersion"  : 2
         }
     ],
     "ok"  : 1
}
 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
现在开始部署仲裁节点sign-mongo03.wangshibo.cn
[app@sign-mongo03 ~]$  mkdir  /data/mongodb/arbiter
[app@sign-mongo03 ~]$ ll -d  /data/mongodb/arbiter
drwxrwxr-x 2 app app 4096 Nov 23 09:39  /data/mongodb/arbiter
 
本案例是在普通用户app账号下部署的,权限都是app.app。
如果是在root账号下部署,那么需要将mongodb数据目录下的文件全部设置mongodb.mongodb权限
 
mongodb.conf配置:
[app@sign-mongo03 ~]$ vim  /data/mongodb/mongodb .conf
pidfilepath= /data/mongodb/log/mongod .pid
logpath= /data/mongodb/log/mongod .log
dbpath= /data/mongodb/arbiter
logappend= false
bind_ip=172.16.51.218
port=27019
fork= true
replSet=rs0
 
接着重启服务:
[app@sign-mongo03 ~]$  /data/mongodb/bin/mongod  --config  /data/mongodb/mongodb .conf
about to fork child process, waiting  until  server is ready  for  connections.
forked process: 9217
child process started successfully, parent exiting
[app@sign-mongo03 ~]$  ps  -ef| grep  mongo
app       9217     1  1 09:46 ?        00:00:00  /data/mongodb/bin/mongod  --config  /data/mongodb/mongodb .conf
app       9242  9158  0 09:46 pts /0     00:00:00  grep  mongo
[app@sign-mongo03 ~]$  lsof  -i:27019
COMMAND  PID USER   FD   TYPE DEVICE SIZE /OFF  NODE NAME
mongod  9217  app    6u  IPv4  37321      0t0  TCP sign-mongo03.wangshibo.cn:27019 (LISTEN)
 
然后在Paimary主节点sign-mongo01.wangshibo.cn的mongodb中添加仲裁节点并查看结果
[app@sign-mongo01 mongodb]$ mongo 172.16.51.216:27017
MongoDB shell version: 3.2.17-34-g4c1bae566c
connecting to: 172.16.51.216:27017 /test
Server has startup warnings:
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten]
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] ** WARNING:  /sys/kernel/mm/transparent_hugepage/enabled  is  'always' .
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] **        We suggest setting it to  'never'
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten]
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] ** WARNING:  /sys/kernel/mm/transparent_hugepage/defrag  is  'always' .
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] **        We suggest setting it to  'never'
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten]
rs0:PRIMARY> rs.addArb( "sign-mongo03.wangshibo.cn:27019" )
"ok"  : 1 }
rs0:PRIMARY> db.isMaster()
{
     "hosts"  : [
         "sign-mongo01.wangshibo.cn:27017" ,
         "sign-mongo02.wangshibo.cn:27018"
     ],
     "arbiters"  : [
         "sign-mongo03.wangshibo.cn:27019"
     ],
     "setName"  "rs0" ,
     "setVersion"  : 4,
     "ismaster"  true ,
     "secondary"  false ,
     "primary"  "sign-mongo01.wangshibo.cn:27017" ,
     "me"  "sign-mongo01.wangshibo.cn:27017" ,
     "electionId"  : ObjectId( "7fffffff0000000000000003" ),
     "maxBsonObjectSize"  : 16777216,
     "maxMessageSizeBytes"  : 48000000,
     "maxWriteBatchSize"  : 1000,
     "localTime"  : ISODate( "2017-11-23T01:59:03.554Z" ),
     "maxWireVersion"  : 4,
     "minWireVersion"  : 0,
     "ok"  : 1
}
rs0:PRIMARY> rs.status()
{
     "set"  "rs0" ,
     "date"  : ISODate( "2017-11-23T02:00:26.312Z" ),
     "myState"  : 1,
     "term"  : NumberLong(3),
     "heartbeatIntervalMillis"  : NumberLong(2000),
     "members"  : [
         {
             "_id"  : 0,
             "name"  "sign-mongo01.wangshibo.cn:27017" ,
             "health"  : 1,
             "state"  : 1,
             "stateStr"  "PRIMARY" ,
             "uptime"  : 368,
             "optime"  : {
                 "ts"  : Timestamp(1511402420, 1),
                 "t"  : NumberLong(3)
             },
             "optimeDate"  : ISODate( "2017-11-23T02:00:20Z" ),
             "electionTime"  : Timestamp(1511402069, 1),
             "electionDate"  : ISODate( "2017-11-23T01:54:29Z" ),
             "configVersion"  : 5,
             "self"  true
         },
         {
             "_id"  : 1,
             "name"  "sign-mongo02.wangshibo.cn:27018" ,
             "health"  : 1,
             "state"  : 2,
             "stateStr"  "SECONDARY" ,
             "uptime"  : 367,
             "optime"  : {
                 "ts"  : Timestamp(1511402420, 1),
                 "t"  : NumberLong(3)
             },
             "optimeDate"  : ISODate( "2017-11-23T02:00:20Z" ),
             "lastHeartbeat"  : ISODate( "2017-11-23T02:00:26.306Z" ),
             "lastHeartbeatRecv"  : ISODate( "2017-11-23T02:00:26.309Z" ),
             "pingMs"  : NumberLong(0),
             "syncingTo"  "sign-mongo01.wangshibo.cn:27017" ,
             "configVersion"  : 5
         },
         {
             "_id"  : 3,
             "name"  "sign-mongo03.wangshibo.cn:27019" ,
             "health"  : 1,
             "state"  : 7,
             "stateStr"  "ARBITER" ,
             "uptime"  : 93,
             "lastHeartbeat"  : ISODate( "2017-11-23T02:00:26.306Z" ),
             "lastHeartbeatRecv"  : ISODate( "2017-11-23T02:00:25.306Z" ),
             "pingMs"  : NumberLong(0),
             "configVersion"  : 5
         }
     ],
     "ok"  : 1
}
 
 
至此,添加完成!!
再次测试主备切换。关闭172.16.51.216(primary)中删除服务进程:
[app@sign-mongo01 mongodb]$ pkill -9 mongod
[app@sign-mongo01 mongodb]$  ps  -ef| grep  mongod
app       9664  9398  0 09:50 pts /0     00:00:00  grep  mongod
[app@sign-mongo01 mongodb]$  lsof  -i:27017
[app@sign-mongo01 mongodb]$
 
然后到172.16.51.217:27018(secondary)查看,发现primary已经切换为172.16.51.217
[app@sign-mongo02 ~]$ mongo 172.16.51.217:27018
MongoDB shell version: 3.2.17-34-g4c1bae566c
connecting to: 172.16.51.217:27018 /test
Server has startup warnings:
2017-11-22T21:46:38.417+0800 I CONTROL  [initandlisten]
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] ** WARNING:  /sys/kernel/mm/transparent_hugepage/enabled  is  'always' .
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] **        We suggest setting it to  'never'
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten]
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] ** WARNING:  /sys/kernel/mm/transparent_hugepage/defrag  is  'always' .
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] **        We suggest setting it to  'never'
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten]
rs0:PRIMARY> rs.status()
{
     "set"  "rs0" ,
     "date"  : ISODate( "2017-11-23T02:01:17.762Z" ),
     "myState"  : 1,
     "term"  : NumberLong(4),
     "heartbeatIntervalMillis"  : NumberLong(2000),
     "members"  : [
         {
             "_id"  : 0,
             "name"  "sign-mongo01.wangshibo.cn:27017" ,
             "health"  : 0,
             "state"  : 8,
             "stateStr"  "(not reachable/healthy)" ,
             "uptime"  : 0,
             "optime"  : {
                 "ts"  : Timestamp(0, 0),
                 "t"  : NumberLong(-1)
             },
             "optimeDate"  : ISODate( "1970-01-01T00:00:00Z" ),
             "lastHeartbeat"  : ISODate( "2017-11-23T02:01:17.316Z" ),
             "lastHeartbeatRecv"  : ISODate( "2017-11-23T02:01:04.327Z" ),
             "pingMs"  : NumberLong(0),
             "lastHeartbeatMessage"  "Connection refused" ,
             "configVersion"  : -1
         },
         {
             "_id"  : 1,
             "name"  "sign-mongo02.wangshibo.cn:27018" ,
             "health"  : 1,
             "state"  : 1,
             "stateStr"  "PRIMARY" ,
             "uptime"  : 44080,
             "optime"  : {
                 "ts"  : Timestamp(1511402475, 2),
                 "t"  : NumberLong(4)
             },
             "optimeDate"  : ISODate( "2017-11-23T02:01:15Z" ),
             "infoMessage"  "could not find member to sync from" ,
             "electionTime"  : Timestamp(1511402475, 1),
             "electionDate"  : ISODate( "2017-11-23T02:01:15Z" ),
             "configVersion"  : 5,
             "self"  true
         },
         {
             "_id"  : 3,
             "name"  "sign-mongo03.wangshibo.cn:27019" ,
             "health"  : 1,
             "state"  : 7,
             "stateStr"  "ARBITER" ,
             "uptime"  : 145,
             "lastHeartbeat"  : ISODate( "2017-11-23T02:01:17.315Z" ),
             "lastHeartbeatRecv"  : ISODate( "2017-11-23T02:01:15.316Z" ),
             "pingMs"  : NumberLong(0),
             "configVersion"  : 5
         }
     ],
     "ok"  : 1
}
rs0:PRIMARY> show dbs
local   0.000GB
mydb   0.000GB
 
有上面信息可知,添加仲裁节点后,primary能正常启动切换了!~
 
现在看看arbiter,连接到172.16.51.218:27019
[app@sign-mongo03 ~]$ mongo 172.16.51.218:27019
MongoDB shell version: 3.2.17-34-g4c1bae566c
connecting to: 172.16.51.218:27019 /test
Welcome to the MongoDB shell.
For interactive help,  type  "help" .
For  more  comprehensive documentation, see
     http: //docs .mongodb.org/
Questions? Try the support group
     http: //groups .google.com /group/mongodb-user
Server has startup warnings:
2017-11-23T09:58:34.978+0800 I CONTROL  [initandlisten]
2017-11-23T09:58:34.978+0800 I CONTROL  [initandlisten] ** WARNING:  /sys/kernel/mm/transparent_hugepage/enabled  is  'always' .
2017-11-23T09:58:34.978+0800 I CONTROL  [initandlisten] **        We suggest setting it to  'never'
2017-11-23T09:58:34.978+0800 I CONTROL  [initandlisten]
2017-11-23T09:58:34.978+0800 I CONTROL  [initandlisten] ** WARNING:  /sys/kernel/mm/transparent_hugepage/defrag  is  'always' .
2017-11-23T09:58:34.978+0800 I CONTROL  [initandlisten] **        We suggest setting it to  'never'
2017-11-23T09:58:34.978+0800 I CONTROL  [initandlisten]
rs0:ARBITER> rs.slaveOk();
rs0:ARBITER> db.isMaster()
{
     "hosts"  : [
         "sign-mongo01.wangshibo.cn:27017" ,
         "sign-mongo02.wangshibo.cn:27018"
     ],
     "arbiters"  : [
         "sign-mongo03.wangshibo.cn:27019"
     ],
     "setName"  "rs0" ,
     "setVersion"  : 5,
     "ismaster"  false ,
     "secondary"  false ,
     "primary"  "sign-mongo02.wangshibo.cn:27018" ,
     "arbiterOnly"  true ,
     "me"  "sign-mongo03.wangshibo.cn:27019" ,
     "maxBsonObjectSize"  : 16777216,
     "maxMessageSizeBytes"  : 48000000,
     "maxWriteBatchSize"  : 1000,
     "localTime"  : ISODate( "2017-11-23T02:03:33.874Z" ),
     "maxWireVersion"  : 4,
     "minWireVersion"  : 0,
     "ok"  : 1
}
rs0:ARBITER> show dbs
local   0.000GB
 
arbiter 最为仲裁者,没有数据副本存储在本地,能读取复制集的信息。
-------------------------------------------------------------------------------------------------
在primary主库上,创建locs数据库,该库的用户名为locsopr,密码为locsopr@123
[app@sign-mongo02 ~]$ mongo 172.16.51.217:27018
......
rs0:PRIMARY> use locs
switched to db locs
rs0:PRIMARY> db.createUser({user: "locsopr" , pwd  : "locsopr@123" ,roles:[ "readWrite" ]})
Successfully added user: {  "user"  "locsopr" "roles"  : [  "readWrite"  ] }
rs0:PRIMARY> show  users ;           // 查看当前库下的用户名
{
     "_id"  "locs.locsopr" ,
     "user"  "locsopr" ,
     "db"  "locs" ,
&nbs