MongoDB高可用集群配置的方案

高可用性即HA(High Availability)指的是通過盡量縮短因日常維護操作(計劃)和突發(fā)的系統(tǒng)崩潰(非計劃)所導致的停機時間蝠咆,以提高系統(tǒng)和應用的可用性直秆。

高可用集群的解決方案

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

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

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

(2)服務器高可用

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

(3)存儲高可用

使用軟件或硬件技術(shù)實現(xiàn)存儲的高度可用性昭灵。其主要技術(shù)指標是存儲切換功能,數(shù)據(jù)復制功能伐谈,數(shù)據(jù)快照功能等虎锚。當一臺存儲出現(xiàn)故障時,另一臺備用的存儲可以快速切換衩婚,達一存儲不停機的目的窜护。

MongoDB的高可用集群配置

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

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

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

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

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

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

多臺主機一起工作矾芙,各自運行一個或幾個服務,各為服務定義一個或多個備用主機近上,當某個主機故障時剔宪,運行在其上的服務就可以被其它主機接管。

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

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

image

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

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

(1)主(Master)

可讀可寫格遭,當數(shù)據(jù)有修改的時候,會將oplog同步到所有連接的salve上去留瞳。

(2)從(Slave)

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

特別的她倘,對于Mongodb來說璧微,并不推薦使用Master-Slave架構(gòu),因為Master-Slave其中Master宕機后不能自動恢復硬梁,推薦使用Replica Set前硫,后面會有介紹,除非Replica的節(jié)點數(shù)超過50荧止,才需要使用Master-Slave架構(gòu)屹电,正常情況是不可能用那么多節(jié)點的。

還有一點跃巡,Master-Slave不支持鏈式結(jié)構(gòu)危号,Slave只能直接連接Master。Redis的Master-Slave支持鏈式結(jié)構(gòu)素邪,Slave可以連接Slave外莲,成為Slave的Slave。

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

1)機器環(huán)境
182.48.115.238    master-node
182.48.115.236    slave-node
 
兩臺機器都關(guān)閉防火墻和selinux
mongodb的安裝參考:http://www.reibang.com/p/5ed4ab8f60cc
 
2)主從配置
.............master-node節(jié)點配置.............
[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        //確定自己是主服務器

[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里綁定了本機的ip地址182.48.115.238偷线,所以連接mongodb的時候必須用這個ip地址磨确,不能使用默認的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é)點配置.............
[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               //確定自己是從服務器
 
[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即副本集方式主要有兩個目的淋昭,一個是數(shù)據(jù)冗余做故障恢復使用俐填,當發(fā)生硬件故障或者其它原因造成的宕機時,可以使用副本進行恢復翔忽。

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

1.Primary和Secondary搭建的Replica Set

image

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

(1)主節(jié)點(Primary)

接收所有的寫請求材失,然后把修改同步到所有Secondary痕鳍。一個Replica Set只能有一個Primary節(jié)點喊递,當Primary掛掉后俘种,其他Secondary或者Arbiter節(jié)點會重新選舉出來一個主節(jié)點。默認讀請求也是發(fā)到Primary節(jié)點處理的昧碉,需要轉(zhuǎn)發(fā)到Secondary需要客戶端修改一下連接配置旨别。

(2)副本節(jié)點(Secondary)

與主節(jié)點保持同樣的數(shù)據(jù)集诗赌。當主節(jié)點掛掉的時候,參與選主秸弛。

(3)仲裁者(Arbiter)

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

注意,一個自動failover的Replica Set節(jié)點數(shù)必須為奇數(shù)儿捧,目的是選主投票的時候要有一個大多數(shù)才能進行選主決策荚坞。

(4)選主過程

其中Secondary宕機,不受影響纯命,若Primary宕機西剥,會進行重新選主:

image

2.使用Arbiter搭建Replica Set

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

image

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


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

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

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

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

編寫配置文件咆畏,不同的機器修改bind_ip就可以了

[root@master-node ~]# cat /usr/local/mongodb/mongodb.conf
port=27017
bind_ip = 182.48.115.236                 //這個最好配置成本機的ip地址南捂。否則后面進行副本集初始化的時候可能會失敗旧找!           
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

啟動4個節(jié)點

 /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é)點
客戶端連接master钮蛛、slaver中任意一個節(jié)點mongodb

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

開始配置

> 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是可以任意的名字鞭缭,當然最好不要是mongodb的關(guān)鍵字,conf魏颓,config都可以岭辣。最外層的_id表示replica set的名字,members里包含的是所有節(jié)點的地址以及優(yōu)先級甸饱。優(yōu)先級最高的即成為主節(jié)點沦童,即這里的10.211.55.10:27017。特別注意的是叹话,對于仲裁節(jié)點偷遗,需要有個特別的配置——arbiterOnly:true。這個千萬不能少了驼壶,不然主備模式就不能生效氏豌。

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

 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> 

如果配置正在生效碌嘀,其中會包含如下信息:"stateStr" : "RECOVERING"

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

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

Sharding分片技術(shù)

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

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

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

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

image

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

image

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

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

用來保存數(shù)據(jù),保證數(shù)據(jù)的高可用性和一致性高蜂〈侠瑁可以是一個單獨的mongod實例,也可以是一個副本集备恤。

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

image

B.查詢路由(Query Routers)

路由就是mongos的實例湘纵,客戶端直接連接mongos,由mongos把讀寫請求路由到指定的Shard上去滤淳。

一個Sharding集群梧喷,可以有一個mongos,也可以有多mongos以減輕客戶端請求的壓力脖咐。

C.配置服務器(Config servers)

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

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

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

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

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

1屁擅、MongoDB機器信息

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

端口分配:

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/

所有版本二進制文件,自行下載

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

分別在每臺機器建立conf偿凭、mongos、config派歌、shard1弯囊、shard2、shard3六個目錄胶果,因為mongos不存儲數(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配置服務器

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

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

啟動三臺服務器的config server

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

登錄任意一臺配置服務器蕊连,初始化配置副本集
連接 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"應與配置文件中配置的 replicaction.replSetName 一致,"members" 中的 "host" 為三個節(jié)點的 ip 和 port
響應內(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>

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

//從單個一個
>
//變成了
configs:SECONDARY>

查詢狀態(tài)

configs:SECONDARY> rs.status()

3. 配置分片副本集

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

(三臺機器)設(shè)置第一個分片副本集
配置文件

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

啟動三臺服務器的shard1 server

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

登陸任意一臺服務器尝蠕,初始化副本集(除了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)

響應內(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 }

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

//從單個一個
>
//變成了
shard1:SECONDARY>

查詢狀態(tài)

shard1:SECONDARY> rs.status()

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

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

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

啟動三臺服務器的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)

響應內(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è)置第三個分片副本集

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

啟動三臺服務器的shard3 server

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

登陸任意一臺服務器载庭,初始化副本集(除了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)

響應內(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 配置路由服務器 mongos

(三臺機器)先啟動配置服務器和分片服務器,后啟動路由實例啟動路由實例:

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)聽的配置服務器,只能有1個或者3個 configs為配置服務器的副本集名字
configdb = configs/192.168.252.121:21000,192.168.252.122:21000,192.168.252.123:21000
 
#設(shè)置最大連接數(shù)
maxConns = 20000

啟動三臺服務器的mongos server

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

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

目前搭建了mongodb配置服務器看彼、路由服務器扇谣,各個分片服務器,不過應用程序連接到mongos路由服務器并不能使用分片機制闲昭,還需要在程序里設(shè)置分片配置罐寨,讓分片生效。
登陸任意一臺mongos

mongo --port 20000

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

use  admin

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

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()

響應內(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. 啟用集合分片生效

目前配置服務序矩、路由服務鸯绿、分片服務、副本集服務都已經(jīng)串聯(lián)起來了簸淀,但我們的目的是希望插入數(shù)據(jù)瓶蝴,數(shù)據(jù)能夠自動分片。連接在mongos上租幕,準備讓指定的數(shù)據(jù)庫舷手、指定的集合分片生效。
登陸任意一臺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路由服務器上的shards集合會有數(shù)據(jù)展示贾富,如下圖:


shards數(shù)據(jù)

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


chunks數(shù)據(jù)

我們設(shè)置testdb的 table1 表需要分片,根據(jù) id 或name自動分片到 shard1 颤枪,shard2汗捡,shard3 上面去。要這樣設(shè)置是因為不是所有mongodb 的數(shù)據(jù)庫和表 都需要分片畏纲!
測試分片配置結(jié)果
連接 MongoDB 路由服務

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>

后期運維

參考

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

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

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

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

啟動

mongodb的啟動順序是扇住,先啟動配置服務器,在啟動分片盗胀,最后啟動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

啟動報錯

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)閉時读整,直接killall殺掉所有進程

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 各平臺下載地址:https://www.mongodb.com/download-center#community

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

mongodb高可用具體配置參考:

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末簿训,一起剝皮案震驚了整個濱河市咱娶,隨后出現(xiàn)的幾起案子米间,更是在濱河造成了極大的恐慌,老刑警劉巖膘侮,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屈糊,死亡現(xiàn)場離奇詭異,居然都是意外死亡琼了,警方通過查閱死者的電腦和手機逻锐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門夫晌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人昧诱,你說我怎么就攤上這事晓淀。” “怎么了盏档?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵凶掰,是天一觀的道長。 經(jīng)常有香客問我蜈亩,道長懦窘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任稚配,我火速辦了婚禮畅涂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘道川。我一直安慰自己午衰,他們只是感情好,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布冒萄。 她就那樣靜靜地躺著苇经,像睡著了一般。 火紅的嫁衣襯著肌膚如雪宦言。 梳的紋絲不亂的頭發(fā)上扇单,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機與錄音奠旺,去河邊找鬼蜘澜。 笑死,一個胖子當著我的面吹牛响疚,可吹牛的內(nèi)容都是我干的鄙信。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼忿晕,長吁一口氣:“原來是場噩夢啊……” “哼装诡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起践盼,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤鸦采,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后咕幻,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體渔伯,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年肄程,在試婚紗的時候發(fā)現(xiàn)自己被綠了锣吼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片选浑。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖玄叠,靈堂內(nèi)的尸體忽然破棺而出古徒,到底是詐尸還是另有隱情,我是刑警寧澤读恃,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布描函,位于F島的核電站,受9級特大地震影響狐粱,放射性物質(zhì)發(fā)生泄漏舀寓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一肌蜻、第九天 我趴在偏房一處隱蔽的房頂上張望互墓。 院中可真熱鬧,春花似錦蒋搜、人聲如沸篡撵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽育谬。三九已至,卻和暖如春帮哈,著一層夾襖步出監(jiān)牢的瞬間膛檀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工娘侍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留咖刃,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓憾筏,卻偏偏與公主長得像嚎杨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子氧腰,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345