MongoDB高可用集群配置的方案

高可用性即HA(High Availability)指的是通過盡量縮短因日常維護(hù)操作(計(jì)劃)和突發(fā)的系統(tǒng)崩潰(非計(jì)劃)所導(dǎo)致的停機(jī)時(shí)間,以提高系統(tǒng)和應(yīng)用的可用性。

高可用集群的解決方案

計(jì)算機(jī)系統(tǒng)的高可用在不同的層面上有不同的表現(xiàn):

(1)網(wǎng)絡(luò)高可用

由于網(wǎng)絡(luò)存儲(chǔ)的快速發(fā)展,網(wǎng)絡(luò)冗余技術(shù)被不斷提升,提高IT系統(tǒng)的高可用性的關(guān)鍵應(yīng)用就是網(wǎng)絡(luò)高可用性,網(wǎng)絡(luò)高可用性與網(wǎng)絡(luò)高可靠性是有區(qū)別的,網(wǎng)絡(luò)高可用性是通過匹配冗余的網(wǎng)絡(luò)設(shè)備實(shí)現(xiàn)網(wǎng)絡(luò)設(shè)備的冗余,達(dá)到高可用的目的。
比如冗余的交換機(jī),冗余的路由器等

(2)服務(wù)器高可用

服務(wù)器高可用主要使用的是服務(wù)器集群軟件或高可用軟件來實(shí)現(xiàn)。

(3)存儲(chǔ)高可用

使用軟件或硬件技術(shù)實(shí)現(xiàn)存儲(chǔ)的高度可用性。其主要技術(shù)指標(biāo)是存儲(chǔ)切換功能,數(shù)據(jù)復(fù)制功能,數(shù)據(jù)快照功能等。當(dāng)一臺(tái)存儲(chǔ)出現(xiàn)故障時(shí),另一臺(tái)備用的存儲(chǔ)可以快速切換,達(dá)一存儲(chǔ)不停機(jī)的目的。

MongoDB的高可用集群配置

高可用集群,即High Availability Cluster,簡稱HA Cluster。
集群(cluster)就是一組計(jì)算機(jī),它們作為一個(gè)整體向用戶提供一組網(wǎng)絡(luò)資源。
這些單個(gè)的計(jì)算機(jī)系統(tǒng) 就是集群的節(jié)點(diǎn)(node)。
搭建高可用集群需要合理的配置多臺(tái)計(jì)算機(jī)之間的角色,數(shù)據(jù)恢復(fù),一致性等,主要有以下幾種方式:

(1)主從方式 (非對稱方式)

主機(jī)工作,備機(jī)處于監(jiān)控準(zhǔn)備狀況;當(dāng)主機(jī)宕機(jī)時(shí),備機(jī)接管主機(jī)的一切工作,待主機(jī)恢復(fù)正常后,按使用者的設(shè)定以自動(dòng)或手動(dòng)方式將服務(wù)切換到主機(jī)上運(yùn)行,數(shù)據(jù)的一致性通過共享存儲(chǔ)系統(tǒng)解決。

(2)雙機(jī)雙工方式(互備互援)

兩臺(tái)主機(jī)同時(shí)運(yùn)行各自的服務(wù)工作且相互監(jiān)測情況,當(dāng)任一臺(tái)主機(jī)宕機(jī)時(shí),另一臺(tái)主機(jī)立即接管它的一切工作,保證工作實(shí)時(shí),應(yīng)用服務(wù)系統(tǒng)的關(guān)鍵數(shù)據(jù)存放在共享存儲(chǔ)系統(tǒng)中。

(3)集群工作方式(多服務(wù)器互備方式)

多臺(tái)主機(jī)一起工作,各自運(yùn)行一個(gè)或幾個(gè)服務(wù),各為服務(wù)定義一個(gè)或多個(gè)備用主機(jī),當(dāng)某個(gè)主機(jī)故障時(shí),運(yùn)行在其上的服務(wù)就可以被其它主機(jī)接管。

MongoDB集群配置的幾種方案也遵循了這幾種解決辦法。

Master-Slave主從結(jié)構(gòu)

image

主從架構(gòu)一般用于備份或者做讀寫分離。一般有一主一從設(shè)計(jì)和一主多從設(shè)計(jì)。

由兩種角色構(gòu)成:

(1)主(Master)

可讀可寫,當(dāng)數(shù)據(jù)有修改的時(shí)候,會(huì)將oplog同步到所有連接的salve上去。

(2)從(Slave)

只讀不可寫,自動(dòng)從Master同步數(shù)據(jù)。

特別的,對于Mongodb來說,并不推薦使用Master-Slave架構(gòu),因?yàn)镸aster-Slave其中Master宕機(jī)后不能自動(dòng)恢復(fù),推薦使用Replica Set,后面會(huì)有介紹,除非Replica的節(jié)點(diǎn)數(shù)超過50,才需要使用Master-Slave架構(gòu),正常情況是不可能用那么多節(jié)點(diǎn)的。

還有一點(diǎn),Master-Slave不支持鏈?zhǔn)浇Y(jié)構(gòu),Slave只能直接連接Master。Redis的Master-Slave支持鏈?zhǔn)浇Y(jié)構(gòu),Slave可以連接Slave,成為Slave的Slave。

下面為主從配置高可用方案搭建過程(此高可用方案不推薦使用,只做參考):

1)機(jī)器環(huán)境
182.48.115.238    master-node
182.48.115.236    slave-node
 
兩臺(tái)機(jī)器都關(guān)閉防火墻和selinux
mongodb的安裝參考:http://www.itdecent.cn/p/5ed4ab8f60cc
 
2)主從配置
.............master-node節(jié)點(diǎn)配置.............
[root@master-node ~]# vim /usr/local/mongodb/mongodb.conf
port=27017
bind_ip = 182.48.115.238
dbpath=/usr/local/mongodb/data
logpath=/usr/local/mongodb/log/mongo.log
logappend=true
journal = true
fork = true
master = true        //確定自己是主服務(wù)器

[root@master-node ~]# nohup /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf &
 
[root@master-node ~]# ps -ef|grep mongodb
root     15707 15514 23 16:45 pts/2    00:00:00 /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf
root     15736 15514  0 16:45 pts/2    00:00:00 grep mongodb
[root@master-node ~]# lsof -i:27017
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mongod  15707 root    7u  IPv4 153114      0t0  TCP 182.48.115.238:27017 (LISTEN)
 
由于mongodb.conf里綁定了本機(jī)的ip地址182.48.115.238,所以連接mongodb的時(shí)候必須用這個(gè)ip地址,不能使用默認(rèn)的127.0.0.1,也就是說:
[root@master-node ~]# mongo 182.48.115.238:27017     //這樣才能連接mongodb
[root@master-node ~]# mongo 或者 mongodb 127.0.0.1:27017    // 這樣不能連接mongodb

.............slave-node節(jié)點(diǎn)配置.............
[root@slave-node ~]# vim /usr/local/mongodb/mongodb.conf
port=27017
dbpath=/usr/local/mongodb/data
logpath=/usr/local/mongodb/log/mongo.log
logappend=true
journal = true
fork = true
bind_ip = 182.48.115.236            //確定主數(shù)據(jù)庫端口
source = 182.48.115.238:27017      //確定主數(shù)據(jù)庫端口
slave = true               //確定自己是從服務(wù)器
 
[root@slave-node ~]# nohup /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf &
 
[root@slave-node ~]# ps -ef|grep mongo
root     26290 26126  8 16:47 pts/0    00:00:00 /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf
root     26316 26126  0 16:47 pts/0    00:00:00 grep mongo
[root@slave-node ~]# lsof -i:27017
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mongod  26290 root    7u  IPv4 663904      0t0  TCP slave-node1:27017 (LISTEN)
mongod  26290 root   25u  IPv4 663917      0t0  TCP slave-node1:51060->slave-node2:27017 (ESTABLISHED)

Relica Set副本集方式

Mongodb的Replica Set即副本集方式主要有兩個(gè)目的,一個(gè)是數(shù)據(jù)冗余做故障恢復(fù)使用,當(dāng)發(fā)生硬件故障或者其它原因造成的宕機(jī)時(shí),可以使用副本進(jìn)行恢復(fù)。

另一個(gè)是做讀寫分離,讀的請求分流到副本上,減輕主(Primary)的讀壓力。

1.Primary和Secondary搭建的Replica Set

image

Replica Set是mongod的實(shí)例集合,它們有著同樣的數(shù)據(jù)內(nèi)容。包含三類角色:

(1)主節(jié)點(diǎn)(Primary)

接收所有的寫請求,然后把修改同步到所有Secondary。一個(gè)Replica Set只能有一個(gè)Primary節(jié)點(diǎn),當(dāng)Primary掛掉后,其他Secondary或者Arbiter節(jié)點(diǎn)會(huì)重新選舉出來一個(gè)主節(jié)點(diǎn)。默認(rèn)讀請求也是發(fā)到Primary節(jié)點(diǎn)處理的,需要轉(zhuǎn)發(fā)到Secondary需要客戶端修改一下連接配置。

(2)副本節(jié)點(diǎn)(Secondary)

與主節(jié)點(diǎn)保持同樣的數(shù)據(jù)集。當(dāng)主節(jié)點(diǎn)掛掉的時(shí)候,參與選主。

(3)仲裁者(Arbiter)

不保有數(shù)據(jù),不參與選主,只進(jìn)行選主投票。使用Arbiter可以減輕數(shù)據(jù)存儲(chǔ)的硬件需求,Arbiter跑起來幾乎沒什么大的硬件資源需求,但重要的一點(diǎn)是,在生產(chǎn)環(huán)境下它和其他數(shù)據(jù)節(jié)點(diǎn)不要部署在同一臺(tái)機(jī)器上。

注意,一個(gè)自動(dòng)failover的Replica Set節(jié)點(diǎn)數(shù)必須為奇數(shù),目的是選主投票的時(shí)候要有一個(gè)大多數(shù)才能進(jìn)行選主決策。

(4)選主過程

其中Secondary宕機(jī),不受影響,若Primary宕機(jī),會(huì)進(jìn)行重新選主:

image

2.使用Arbiter搭建Replica Set

偶數(shù)個(gè)數(shù)據(jù)節(jié)點(diǎn),加一個(gè)Arbiter構(gòu)成的Replica Set方式:

image

Relica Set副本集方式整體大概如圖:


下面為副本集高可用方案搭建過程(此高可用方案也不推薦使用,只做參考):
1)機(jī)器環(huán)境
182.48.115.236 master-node(主節(jié)點(diǎn))
182.48.115.237 slave-node1(從節(jié)點(diǎn))
182.48.115.238 slave-node2(從節(jié)點(diǎn))

MongoDB 安裝目錄:/usr/local/mongodb
MongoDB 數(shù)據(jù)庫目錄:/usr/local/mongodb/data
MongoDB 日志目錄:/usr/local/mongodb/log/mongo.log
MongoDB 配置文件:/usr/local/mongodb/mongodb.conf

對以上三臺(tái)服務(wù)器部署Mongodb的副本集功能,定義副本集名稱為:hqmongodb
關(guān)閉三臺(tái)服務(wù)器的iptables防火墻和selinux

2)確保三臺(tái)副本集服務(wù)器上的配置文件完全相同(即三臺(tái)機(jī)器的mongodb.conf配置一樣,除了配置文件中綁定的ip不一樣)。下面操作在三臺(tái)節(jié)點(diǎn)機(jī)上都要執(zhí)行:

編寫配置文件,不同的機(jī)器修改bind_ip就可以了

[root@master-node ~]# cat /usr/local/mongodb/mongodb.conf
port=27017
bind_ip = 182.48.115.236                 //這個(gè)最好配置成本機(jī)的ip地址。否則后面進(jìn)行副本集初始化的時(shí)候可能會(huì)失敗!           
dbpath=/usr/local/mongodb/data
logpath=/usr/local/mongodb/log/mongo.log
pidfilepath=/usr/local/mongodb/mongo.pid
fork=true
logappend=true
shardsvr=true
directoryperdb=true
oplogSize=10000
noprealloc=true
#auth=true
#keyFile =/usr/local/mongodb/keyfile
replSet =shard002

........................具體配置........................

  # master.conf
  dbpath=/opt/mongodb/data/master
  logpath=/opt/mongodb/logs/master.log
  pidfilepath=/opt/mongodb/logs/master.pid
  directoryperdb=true
  logappend=true
  replSet=ynzw
  bind_ip=10.211.55.10
  port=27017
  oplogSize=10000
  fork=true
  noprealloc=true


  # slaver1.conf
  dbpath=/opt/mongodb/data/slaver1
  logpath=/opt/mongodb/logs/slaver1.log
  pidfilepath=/opt/mongodb/logs/slaver1.pid
  directoryperdb=true
  logappend=true
  replSet=ynzw
  bind_ip=10.211.55.10
  port=27018
  oplogSize=10000
  fork=true
  noprealloc=true


  # slaver2.conf
  dbpath=/opt/mongodb/data/slaver2
  logpath=/opt/mongodb/logs/slaver2.log
  pidfilepath=/opt/mongodb/logs/slaver2.pid
  directoryperdb=true
  logappend=true
  replSet=ynzw
  bind_ip=10.211.55.10
  port=27019
  oplogSize=10000
  fork=true
  noprealloc=true


  # arbiter.conf
  dbpath=/opt/mongodb/data/arbiter
  logpath=/opt/mongodb/logs/arbiter.log
  pidfilepath=/opt/mongodb/logs/arbiter.pid
  directoryperdb=true
  logappend=true
  replSet=ynzw
  bind_ip=10.211.55.10
  port=27020
  oplogSize=10000
  fork=true
  noprealloc=true

啟動(dòng)4個(gè)節(jié)點(diǎn)

 /opt/mongodb/bin/mongod -f /opt/mongodb/conf/master.conf
 /opt/mongodb/bin/mongod -f /opt/mongodb/conf/slaver1.conf
 /opt/mongodb/bin/mongod -f /opt/mongodb/conf/slaver2.conf
 /opt/mongodb/bin/mongod -f /opt/mongodb/conf/arbiter.conf

配置主,備,仲裁節(jié)點(diǎn)
客戶端連接master、slaver中任意一個(gè)節(jié)點(diǎn)mongodb

/opt/mongodb/bin/mongo 10.211.55.10:27017  #ip和port是某個(gè)節(jié)點(diǎn)的地址

開始配置

> use admin
> cfg = {_id: "ynzw",members:[{_id: 0,host: '10.211.55.10:27017',priority: 3},{_id: 1,host: '10.211.55.10:27018',priority: 2},{_id: 2,host: '10.211.55.10:27019',priority: 1},{_id: 3,host: '10.211.55.10:27020',arbiterOnly: true}]};
> rs.initiate(cfg)    #使配置生效

cfg是可以任意的名字,當(dāng)然最好不要是mongodb的關(guān)鍵字,conf,config都可以。最外層的_id表示replica set的名字,members里包含的是所有節(jié)點(diǎn)的地址以及優(yōu)先級。優(yōu)先級最高的即成為主節(jié)點(diǎn),即這里的10.211.55.10:27017。特別注意的是,對于仲裁節(jié)點(diǎn),需要有個(gè)特別的配置——arbiterOnly:true。這個(gè)千萬不能少了,不然主備模式就不能生效。

檢驗(yàn)
配置的生效時(shí)間根據(jù)不同的機(jī)器配置會(huì)有長有短,配置不錯(cuò)的話基本上十幾秒內(nèi)就能生效,有的配置需要一兩分鐘。如果生效了,執(zhí)行rs.status()命令會(huì)看到如下信息:

 ynzw:SECONDARY> rs.status()
  {
          "set" : "ynzw",
          "date" : ISODate("2017-05-26T06:47:32.069Z"),
          "myState" : 1,
          "term" : NumberLong(8),
          "heartbeatIntervalMillis" : NumberLong(2000),
          "members" : [
                  {
                          "_id" : 0,
                          "name" : "10.211.55.10:27017",
                          "health" : 1,
                          "state" : 1,
                          "stateStr" : "PRIMARY",
                          "uptime" : 24,
                          "optime" : {
                                  "ts" : Timestamp(1495781239, 2),
                                  "t" : NumberLong(8)
                          },
                          "optimeDate" : ISODate("2017-05-26T06:47:19Z"),
                          "electionTime" : Timestamp(1495781239, 1),
                          "electionDate" : ISODate("2017-05-26T06:47:19Z"),
                          "configVersion" : 1,
                          "self" : true
                  },
                  {
                          "_id" : 1,
                          "name" : "10.211.55.10:27018",
                          "health" : 1,
                          "state" : 2,
                          "stateStr" : "SECONDARY",
                          "uptime" : 18,
                          "optime" : {
                                  "ts" : Timestamp(1495781239, 2),
                                  "t" : NumberLong(8)
                          },
                          "optimeDate" : ISODate("2017-05-26T06:47:19Z"),
                          "lastHeartbeat" : ISODate("2017-05-26T06:47:31.424Z"),
                          "lastHeartbeatRecv" : ISODate("2017-05-26T06:47:31.247Z"),
                          "pingMs" : NumberLong(0),
                          "syncingTo" : "10.211.55.10:27017",
                          "configVersion" : 1
                  },
                  {
                          "_id" : 2,
                          "name" : "10.211.55.10:27019",
                          "health" : 1,
                          "state" : 2,
                          "stateStr" : "SECONDARY",
                          "uptime" : 18,
                          "optime" : {
                                  "ts" : Timestamp(1495781239, 2),
                                  "t" : NumberLong(8)
                          },
                          "optimeDate" : ISODate("2017-05-26T06:47:19Z"),
                          "lastHeartbeat" : ISODate("2017-05-26T06:47:31.424Z"),
                          "lastHeartbeatRecv" : ISODate("2017-05-26T06:47:31.734Z"),
                          "pingMs" : NumberLong(0),
                          "syncingTo" : "10.211.55.10:27018",
                          "configVersion" : 1
                  },
                  {
                          "_id" : 3,
                          "name" : "10.211.55.10:27020",
                          "health" : 1,
                          "state" : 7,
                          "stateStr" : "ARBITER",
                          "uptime" : 18,
                          "lastHeartbeat" : ISODate("2017-05-26T06:47:31.424Z"),
                          "lastHeartbeatRecv" : ISODate("2017-05-26T06:47:30.437Z"),
                          "pingMs" : NumberLong(0),
                          "configVersion" : 1
                  }
          ],
          "ok" : 1
  }
  ynzw:PRIMARY> 

如果配置正在生效,其中會(huì)包含如下信息:"stateStr" : "RECOVERING"

附錄
mongodb配置文件具體屬性解釋

 dbpath:數(shù)據(jù)存放目錄
 logpath:日志存放路徑
 pidfilepath:進(jìn)程文件,方便停止mongodb
 directoryperdb:為每一個(gè)數(shù)據(jù)庫按照數(shù)據(jù)庫名建立文件夾存放
 logappend:以追加的方式記錄日志
 replSet:replica set的名字
 bind_ip:mongodb所綁定的ip地址
 port:mongodb進(jìn)程所使用的端口號,默認(rèn)為27017
 oplogSize:mongodb操作日志文件的最大大小。單位為Mb,默認(rèn)為硬盤剩余空間的5%
 fork:以后臺(tái)方式運(yùn)行進(jìn)程
 noprealloc:不預(yù)先分配存儲(chǔ)

Sharding分片技術(shù)

當(dāng)數(shù)據(jù)量比較大的時(shí)候,我們需要把數(shù)據(jù)分片運(yùn)行在不同的機(jī)器中,以降低CPU、內(nèi)存和IO的壓力,Sharding就是數(shù)據(jù)庫分片技術(shù)。

MongoDB分片技術(shù)類似MySQL的水平切分和垂直切分,數(shù)據(jù)庫主要由兩種方式做Sharding:垂直擴(kuò)展和橫向切分。

垂直擴(kuò)展的方式就是進(jìn)行集群擴(kuò)展,添加更多的CPU,內(nèi)存,磁盤空間等。

橫向切分則是通過數(shù)據(jù)分片的方式,通過集群統(tǒng)一提供服務(wù):

image

(1)MongoDB的Sharding架構(gòu)

image

(2)MongoDB分片架構(gòu)中的角色

A.數(shù)據(jù)分片(Shards)

用來保存數(shù)據(jù),保證數(shù)據(jù)的高可用性和一致性??梢允且粋€(gè)單獨(dú)的mongod實(shí)例,也可以是一個(gè)副本集。

在生產(chǎn)環(huán)境下Shard一般是一個(gè)Replica Set,以防止該數(shù)據(jù)片的單點(diǎn)故障。所有Shard中有一個(gè)PrimaryShard,里面包含未進(jìn)行劃分的數(shù)據(jù)集合:

image

B.查詢路由(Query Routers)

路由就是mongos的實(shí)例,客戶端直接連接mongos,由mongos把讀寫請求路由到指定的Shard上去。

一個(gè)Sharding集群,可以有一個(gè)mongos,也可以有多mongos以減輕客戶端請求的壓力。

C.配置服務(wù)器(Config servers)

保存集群的元數(shù)據(jù)(metadata),包含各個(gè)Shard的路由規(guī)則。

Sharding分片技術(shù)(混合模式)高可用方案的大體架構(gòu)圖:

Sharding分片技術(shù)(混合模式)高可用方案架構(gòu)下向mongodb寫數(shù)據(jù)的流程圖:

Sharding分片技術(shù)(混合模式)高可用方案架構(gòu)下向mongodb讀數(shù)據(jù)的流程圖:

下面為Sharding分片高可用方案搭建過程(推薦使用此方案):

1、MongoDB機(jī)器信息

192.168.252.121 192.168.252.122 192.168.252.123
mongos mongos mongos
config server config server config server
shard server1 主節(jié)點(diǎn) shard server1 副節(jié)點(diǎn) shard server1 仲裁
shard server2 仲裁 shard server2 主節(jié)點(diǎn) shard server2 副節(jié)點(diǎn)
shard server3 副節(jié)點(diǎn) shard server3 仲裁 shard server3 主節(jié)點(diǎn)

端口分配:

mongos:20000
config:21000
shard1:27001
shard2:27002
shard3:27003

下載并且安裝

wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-amazon-3.6.2.tgz
tar -xzvf mongodb-linux-x86_64-amazon-3.6.2.tgz  -C /usr/local/

所有版本二進(jìn)制文件,自行下載

https://www.mongodb.org/dl/win32/x86_64-2008plus-ssl?_ga=2.87139544.1567998244.1517190032-1153843332.1517190032&_gac=1.204211492.1517212002.EAIaIQobChMI44v9_9b82AIV1AcqCh0lcABIEAAYASAAEgKI1_D_BwE

改名

cd /usr/local/
mv  mongodb-linux-x86_64-amazon-3.6.2 mongodb

分別在每臺(tái)機(jī)器建立conf、mongos、config、shard1、shard2、shard3六個(gè)目錄,因?yàn)閙ongos不存儲(chǔ)數(shù)據(jù),只需要建立日志文件目錄即可。

mkdir -p /usr/local/mongodb/conf \
mkdir -p /usr/local/mongodb/mongos/log \
mkdir -p /usr/local/mongodb/config/data \
mkdir -p /usr/local/mongodb/config/log \
mkdir -p /usr/local/mongodb/shard1/data \
mkdir -p /usr/local/mongodb/shard1/log \
mkdir -p /usr/local/mongodb/shard2/data \
mkdir -p /usr/local/mongodb/shard2/log \
mkdir -p /usr/local/mongodb/shard3/data \
mkdir -p /usr/local/mongodb/shard3/log

配置環(huán)境變量

vi /etc/profile
# MongoDB 環(huán)境變量內(nèi)容
export MONGODB_HOME=/usr/local/mongodb
export PATH=$MONGODB_HOME/bin:$PATH

使立即生效

source /etc/profile

2、config server配置服務(wù)器

mongodb3.4以后要求配置服務(wù)器也創(chuàng)建副本集,不然集群搭建不成功。
(三臺(tái)機(jī)器)添加配置文件

vi /usr/local/mongodb/conf/config.conf

## 配置文件內(nèi)容
pidfilepath = /usr/local/mongodb/config/log/configsrv.pid
dbpath = /usr/local/mongodb/config/data
logpath = /usr/local/mongodb/config/log/congigsrv.log
logappend = true
 
bind_ip = 0.0.0.0
port = 21000
fork = true
 
#declare this is a config db of a cluster;
configsvr = true

#副本集名稱
replSet = configs
 
#設(shè)置最大連接數(shù)
maxConns = 20000

啟動(dòng)三臺(tái)服務(wù)器的config server

mongod -f /usr/local/mongodb/conf/config.conf

登錄任意一臺(tái)配置服務(wù)器,初始化配置副本集
連接 MongoDB

mongo --port 21000

config 變量

config = {
    _id : "configs",
    members : [
    {_id : 0, host : "192.168.252.121:21000" },
    {_id : 1, host : "192.168.252.122:21000" },
    {_id : 2, host : "192.168.252.123:21000" }
    ]
}

初始化副本集

rs.initiate(config)

其中,"_id" : "configs"應(yīng)與配置文件中配置的 replicaction.replSetName 一致,"members" 中的 "host" 為三個(gè)節(jié)點(diǎn)的 ip 和 port
響應(yīng)內(nèi)容如下

> config = {
... _id : "configs",
... members : [
... {_id : 0, host : "192.168.252.121:21000" },
... {_id : 1, host : "192.168.252.122:21000" },
... {_id : 2, host : "192.168.252.123:21000" }
... ]
... }
{
    "_id" : "configs",
    "members" : [
        {
            "_id" : 0,
            "host" : "192.168.252.121:21000"
        },
        {
            "_id" : 1,
            "host" : "192.168.252.122:21000"
        },
        {
            "_id" : 2,
            "host" : "192.168.252.123:21000"
        }
    ]
}
> rs.initiate(config);
{
    "ok" : 1,
    "operationTime" : Timestamp(1517369899, 1),
    "$gleStats" : {
        "lastOpTime" : Timestamp(1517369899, 1),
        "electionId" : ObjectId("000000000000000000000000")
    },
    "$clusterTime" : {
        "clusterTime" : Timestamp(1517369899, 1),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}
configs:SECONDARY>

此時(shí)會(huì)發(fā)現(xiàn)終端上的輸出已經(jīng)有了變化。

//從單個(gè)一個(gè)
>
//變成了
configs:SECONDARY>

查詢狀態(tài)

configs:SECONDARY> rs.status()

3. 配置分片副本集

3.1 設(shè)置第一個(gè)分片副本集

(三臺(tái)機(jī)器)設(shè)置第一個(gè)分片副本集
配置文件

vi /usr/local/mongodb/conf/shard1.conf

#配置文件內(nèi)容
#——————————————–
pidfilepath = /usr/local/mongodb/shard1/log/shard1.pid
dbpath = /usr/local/mongodb/shard1/data
logpath = /usr/local/mongodb/shard1/log/shard1.log
logappend = true

bind_ip = 0.0.0.0
port = 27001
fork = true
 
#副本集名稱
replSet = shard1
 
#declare this is a shard db of a cluster;
shardsvr = true
 
#設(shè)置最大連接數(shù)
maxConns = 20000

啟動(dòng)三臺(tái)服務(wù)器的shard1 server

mongod -f /usr/local/mongodb/conf/shard1.conf

登陸任意一臺(tái)服務(wù)器,初始化副本集(除了192.168.252.123)
連接 MongoDB

mongo --port 27001

使用admin數(shù)據(jù)庫

use admin

定義副本集配置

config = {
    _id : "shard1",
     members : [
         {_id : 0, host : "192.168.252.121:27001" },
         {_id : 1, host : "192.168.252.122:27001" },
         {_id : 2, host : "192.168.252.123:27001" , arbiterOnly: true }
     ]
 }

初始化副本集配置

rs.initiate(config)

響應(yīng)內(nèi)容如下

> use admin
switched to db admin
> config = {
...     _id : "shard1",
...      members : [
...          {_id : 0, host : "192.168.252.121:27001" },
...          {_id : 1, host : "192.168.252.122:27001" },
...          {_id : 2, host : "192.168.252.123:27001" , arbiterOnly: true }
...      ]
...  }
{
    "_id" : "shard1",
    "members" : [
        {
            "_id" : 0,
            "host" : "192.168.252.121:27001"
        },
        {
            "_id" : 1,
            "host" : "192.168.252.122:27001"
        },
        {
            "_id" : 2,
            "host" : "192.168.252.123:27001",
            "arbiterOnly" : true
        }
    ]
}
> rs.initiate(config)
{ "ok" : 1 }

此時(shí)會(huì)發(fā)現(xiàn)終端上的輸出已經(jīng)有了變化。

//從單個(gè)一個(gè)
>
//變成了
shard1:SECONDARY>

查詢狀態(tài)

shard1:SECONDARY> rs.status()

3.2 設(shè)置第二個(gè)分片副本集

設(shè)置第二個(gè)分片副本集
配置文件

vi /usr/local/mongodb/conf/shard2.conf

#配置文件內(nèi)容
#——————————————–
pidfilepath = /usr/local/mongodb/shard2/log/shard2.pid
dbpath = /usr/local/mongodb/shard2/data
logpath = /usr/local/mongodb/shard2/log/shard2.log
logappend = true

bind_ip = 0.0.0.0
port = 27002
fork = true
 
#副本集名稱
replSet=shard2
 
#declare this is a shard db of a cluster;
shardsvr = true
 
#設(shè)置最大連接數(shù)
maxConns=20000

啟動(dòng)三臺(tái)服務(wù)器的shard2 server

mongod -f /usr/local/mongodb/conf/shard2.conf

連接 MongoDB

mongo --port 27002

使用admin數(shù)據(jù)庫

use admin

定義副本集配置

config = {
    _id : "shard2",
     members : [
         {_id : 0, host : "192.168.252.121:27002"  , arbiterOnly: true },
         {_id : 1, host : "192.168.252.122:27002" },
         {_id : 2, host : "192.168.252.123:27002" }
     ]
 }

初始化副本集配置

rs.initiate(config)

響應(yīng)內(nèi)容如下

> use admin
switched to db admin
> config = {
...     _id : "shard2",
...      members : [
...          {_id : 0, host : "192.168.252.121:27002"  , arbiterOnly: true },
...          {_id : 1, host : "192.168.252.122:27002" },
...          {_id : 2, host : "192.168.252.123:27002" }
...      ]
...  }
{
    "_id" : "shard2",
    "members" : [
        {
            "_id" : 0,
            "host" : "192.168.252.121:27002",
            "arbiterOnly" : true
        },
        {
            "_id" : 1,
            "host" : "192.168.252.122:27002"
        },
        {
            "_id" : 2,
            "host" : "192.168.252.123:27002"
        }
    ]
}
> rs.initiate(config)
{ "ok" : 1 }
shard2:SECONDARY> rs.status()

3.3 設(shè)置第三個(gè)分片副本集

vi /usr/local/mongodb/conf/shard3.conf

#配置文件內(nèi)容
#——————————————–
pidfilepath = /usr/local/mongodb/shard3/log/shard3.pid
dbpath = /usr/local/mongodb/shard3/data
logpath = /usr/local/mongodb/shard3/log/shard3.log
logappend = true

bind_ip = 0.0.0.0
port = 27003
fork = true

#副本集名稱
replSet=shard3
 
#declare this is a shard db of a cluster;
shardsvr = true
 
#設(shè)置最大連接數(shù)
maxConns=20000

啟動(dòng)三臺(tái)服務(wù)器的shard3 server

mongod -f /usr/local/mongodb/conf/shard3.conf

登陸任意一臺(tái)服務(wù)器,初始化副本集(除了192.168.252.121)

mongo --port 27003

使用admin數(shù)據(jù)庫

use admin

定義副本集配置

config = {
    _id : "shard3",
     members : [
         {_id : 0, host : "192.168.252.121:27003" },
         {_id : 1, host : "192.168.252.122:27003" , arbiterOnly: true},
         {_id : 2, host : "192.168.252.123:27003" }
     ]
 }

初始化副本集配置

rs.initiate(config)

響應(yīng)內(nèi)容如下

> use admin
switched to db admin
> config = {
...     _id : "shard3",
...      members : [
...          {_id : 0, host : "192.168.252.121:27003" },
...          {_id : 1, host : "192.168.252.122:27003" , arbiterOnly: true},
...          {_id : 2, host : "192.168.252.123:27003" }
...      ]
...  }
{
    "_id" : "shard3",
    "members" : [
        {
            "_id" : 0,
            "host" : "192.168.252.121:27003"
        },
        {
            "_id" : 1,
            "host" : "192.168.252.122:27003",
            "arbiterOnly" : true
        },
        {
            "_id" : 2,
            "host" : "192.168.252.123:27003"
        }
    ]
}
> rs.initiate(config)
{ "ok" : 1 }
shard3:SECONDARY> rs.status()

3.4 配置路由服務(wù)器 mongos

(三臺(tái)機(jī)器)先啟動(dòng)配置服務(wù)器和分片服務(wù)器,后啟動(dòng)路由實(shí)例啟動(dòng)路由實(shí)例:

vi /usr/local/mongodb/conf/mongos.conf

#內(nèi)容
pidfilepath = /usr/local/mongodb/mongos/log/mongos.pid
logpath = /usr/local/mongodb/mongos/log/mongos.log
logappend = true

bind_ip = 0.0.0.0
port = 20000
fork = true

#監(jiān)聽的配置服務(wù)器,只能有1個(gè)或者3個(gè) configs為配置服務(wù)器的副本集名字
configdb = configs/192.168.252.121:21000,192.168.252.122:21000,192.168.252.123:21000
 
#設(shè)置最大連接數(shù)
maxConns = 20000

啟動(dòng)三臺(tái)服務(wù)器的mongos server

mongos -f /usr/local/mongodb/conf/mongos.conf

4. 串聯(lián)路由服務(wù)器

目前搭建了mongodb配置服務(wù)器、路由服務(wù)器,各個(gè)分片服務(wù)器,不過應(yīng)用程序連接到mongos路由服務(wù)器并不能使用分片機(jī)制,還需要在程序里設(shè)置分片配置,讓分片生效。
登陸任意一臺(tái)mongos

mongo --port 20000

使用admin數(shù)據(jù)庫

use  admin

串聯(lián)路由服務(wù)器與分配副本集

sh.addShard("shard1/192.168.252.121:27001,192.168.252.122:27001,192.168.252.123:27001");
sh.addShard("shard2/192.168.252.121:27002,192.168.252.122:27002,192.168.252.123:27002");
sh.addShard("shard3/192.168.252.121:27003,192.168.252.122:27003,192.168.252.123:27003");

查看集群狀態(tài)

sh.status()

響應(yīng)內(nèi)容如下

mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
    "_id" : 1,
    "minCompatibleVersion" : 5,
    "currentVersion" : 6,
    "clusterId" : ObjectId("5a713a37d56e076f3eb47acf")
  }
  shards:
        {  "_id" : "shard1",  "host" : "shard1/192.168.252.121:27001,192.168.252.122:27001",  "state" : 1 }
        {  "_id" : "shard2",  "host" : "shard2/192.168.252.122:27002,192.168.252.123:27002",  "state" : 1 }
        {  "_id" : "shard3",  "host" : "shard3/192.168.252.121:27003,192.168.252.123:27003",  "state" : 1 }
  active mongoses:
        "3.6.2" : 3
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours: 
                No recent migrations
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }

mongos>

5. 啟用集合分片生效

目前配置服務(wù)、路由服務(wù)、分片服務(wù)、副本集服務(wù)都已經(jīng)串聯(lián)起來了,但我們的目的是希望插入數(shù)據(jù),數(shù)據(jù)能夠自動(dòng)分片。連接在mongos上,準(zhǔn)備讓指定的數(shù)據(jù)庫、指定的集合分片生效。
登陸任意一臺(tái)mongos

mongo --port 20000

使用admin數(shù)據(jù)庫

use  admin

指定testdb分片生效,如下圖:

db.runCommand( { enablesharding :"testdb"});

或

mongos> sh.enablesharding("testdb")
sh.enablesharding("testdb")

指定數(shù)據(jù)庫里需要分片的集合和片鍵,哈希name分片,如下圖:

db.runCommand( { shardcollection : "testdb.table1",key : {"name": "hashed"} } );

或

mongos> sh.shardcollection("testdb.table1", {"name": "hashed"})
sh.shardcollection("testdb.table1", {"name": "hashed"})

通過命令查看mongodb路由服務(wù)器上的shards集合會(huì)有數(shù)據(jù)展示,如下圖:


shards數(shù)據(jù)

通過命令查看mongodb路由服務(wù)器上的chunks集合會(huì)有數(shù)據(jù)展示,如下圖:


chunks數(shù)據(jù)

我們設(shè)置testdb的 table1 表需要分片,根據(jù) id 或name自動(dòng)分片到 shard1 ,shard2,shard3 上面去。要這樣設(shè)置是因?yàn)椴皇撬衜ongodb 的數(shù)據(jù)庫和表 都需要分片!
測試分片配置結(jié)果
連接 MongoDB 路由服務(wù)

mongo  127.0.0.1:20000

切換到 testdb 數(shù)據(jù)庫

use  testdb;

插入測試數(shù)據(jù)

for(i=1;i<=100000;i++){db.table1.insert({"id":i,"name":"penglei"})};

總條數(shù)

db.table1.aggregate([{$group : {_id : "$name", totle : {$sum : 1}}}])

查看分片情況如下

  • shard1: "count": 33755

  • shard2: "count": 33143,

  • shard3: "count": 33102

結(jié)論數(shù)據(jù)基本均勻

db.table1.stats();
mongos> db.table1.stats();
{
    "sharded": true,
    "capped": false,
    "ns": "testdb.table1",
    "count": 100000,
    "size": 5200000,
    "storageSize": 1519616,
    "totalIndexSize": 3530752,
    "indexSizes": {
        "_id_": 892928,
        "id_hashed": 2637824
    },
    "avgObjSize": 52,
    "nindexes": 2,
    "nchunks": 6,
    "shards": {
        "shard1": {
            "ns": "testdb.table1",
            "size": 1755260,
            "count": 33755,
            "avgObjSize": 52,
            "storageSize": 532480,
            "capped": false,
            "wiredTiger": {
            ...省略很多
            }
        },
        "shard2": {
            "ns": "testdb.table1",
            "size": 1723436,
            "count": 33143,
            "avgObjSize": 52,
            "storageSize": 479232,
            "capped": false,
            "wiredTiger": {
            ...省略很多
            }
        },
        "shard3": {
            "ns": "testdb.table1",
            "size": 1721304,
            "count": 33102,
            "avgObjSize": 52,
            "storageSize": 507904,
            "capped": false,
            "wiredTiger": {
            ...省略很多
            }
        }
    },
    "ok": 1,
    "$clusterTime": {
        "clusterTime": Timestamp(1517488062, 350),
        "signature": {
            "hash": BinData(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId": NumberLong(0)
        }
    },
    "operationTime": Timestamp(1517488062, 350)
}
mongos> 

分組查看總數(shù)量是:100000

mongos> db.table1.aggregate([{$group : {_id : "$name", totle : {$sum : 1}}}])
{ "_id" : "penglei", "totle" : 100000 }
mongos>

后期運(yùn)維

參考

手把手教你 MongoDB 的安裝與詳細(xì)使用(一)

http://www.ymq.io/2018/01/26/MongoDB-1/

手把手教你 MongoDB 的安裝與詳細(xì)使用(二)

http://www.ymq.io/2018/01/29/MongoDB-2/

創(chuàng)建索引

db.table1.createIndex({"name":1})
db.table1.getIndexes()

image.png
image.png
image.png

啟動(dòng)

mongodb的啟動(dòng)順序是,先啟動(dòng)配置服務(wù)器,在啟動(dòng)分片,最后啟動(dòng)mongos.

mongod -f /usr/local/mongodb/conf/config.conf
mongod -f /usr/local/mongodb/conf/shard1.conf
mongod -f /usr/local/mongodb/conf/shard2.conf
mongod -f /usr/local/mongodb/conf/shard3.conf
mongod -f /usr/local/mongodb/conf/mongos.conf

啟動(dòng)報(bào)錯(cuò)

about to fork child process, waiting until server is ready for connections.
forked process: 1303
child process started successfully, parent exiting
[root@node1 ~]# mongod -f /usr/local/mongodb/conf/shard1.conf
about to fork child process, waiting until server is ready for connections.
forked process: 1384

刪除 mongod.lock

cd /usr/local/mongodb/shard1/data
rm -rf mongod.lock

關(guān)閉

#debian、ubuntu系統(tǒng)下:

apt-get install psmisc

#centos或、rhel系統(tǒng)下:

yum install psmisc

關(guān)閉時(shí),直接killall殺掉所有進(jìn)程

killall mongod
killall mongos

參考:

百度百科-高可用集群

MongoDB 教程

https://www.cnblogs.com/binyue/p/5901328.html

Runoob 教程:http://www.runoob.com/mongodb/mongodb-tutorial.html

MongoDB 官網(wǎng)地址:https://www.mongodb.com

MongoDB 官方英文文檔:https://docs.mongodb.com/manual

MongoDB 各平臺(tái)下載地址:https://www.mongodb.com/download-center#community

MongoDB 安裝 https://docs.mongodb.com/manual/tutorial/install-mongodb-enterprise-on-ubuntu

mongodb高可用具體配置參考:

Mongodb主從復(fù)制 及 副本集+分片集群梳理:
https://www.cnblogs.com/nulige/p/7613721.html

搭建 MongoDB分片(sharding) / 分區(qū) / 集群環(huán)境:http://www.itdecent.cn/p/66e7ba201545

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容