1. 程式人生 > >MongoDB 3.6 叢集搭建 - 切片+副本集

MongoDB 3.6 叢集搭建 - 切片+副本集

1. 環境準備

在Mongo的官網下載Linux版本安裝包,然後解壓到對應的目錄下;由於資源有限,我們採用Replica Sets + Sharding方式來配置高可用。結構圖如下所示:

 

 

這裡我說明下這個圖所表達的意思:

Shard伺服器:使用Replica Sets確保每個資料節點都具有備份、自動容錯轉移、自動恢復的能力。

  • 配置伺服器:使用3個配置伺服器確保元資料完整性。
  • 路由程序:使用3個路由程序實現平衡,提高客戶端接入效能
  • 副本集1:Shard11,Shard12,Shard13組成一個副本集,提供Sharding中shard1的功能;
  • 副本集2:Shard21,Shard22,Shard23組成一個副本集,提供Sharding中shard2的功能;
  • 副本集3:Shard31,Shard32,Shard33組成一個副本集,提供Sharding中shard3的功能;
  • 3個配置伺服器程序和3個路由器程序。
  •  Arbiter仲裁者,是副本集中的一個MongoDB例項, 它並不儲存資料。仲裁節點使用最小的資源並且不要求硬體裝置。為了確保複製集中有奇數的投票成員(包括primary),需要新增仲裁節點作為投票,否則primary不能執行時不會自動切換primary。

構建一個mongoDB Sharding Cluster需要三種角色:shard伺服器(ShardServer)、配置伺服器(config Server)、路由程序(Route Process)

Shard 伺服器

Shard伺服器即儲存實際資料的分片,每個shard可以是一個mongod例項,也可以是一組mongod例項構成的Replica Sets。為了實現每個Shard內部的故障自動轉換,MongoDB官方建議每個shard為一組Replica Sets。

配置伺服器

為了將一個特定的collection儲存在多個shard中,需要為該collection指定一個shard key,決定該條記錄屬於哪個chunk,配置伺服器可以儲存以下資訊,每個shard節點的配置資訊,每個chunk的shard key範圍,chunk在各shard的分佈情況,叢集中所有DB和collection的sharding配置資訊。

路由程序

它是一個前段路由,客戶端由此接入,首先詢問配置伺服器需要到哪個shard上查詢或儲存記錄,然後連線相應的shard執行操作,最後將結果返回給客戶端,客戶端只需要將原本發給mongod的查詢或更新請求原封不動地發給路由程序,而不必關心所操作的記錄儲存在哪個shard上。

按照架構圖,理論上是需要15臺機器的,由於資源有限,用目錄來替代物理機,下面給出配置表格:

192.168.187.201

192.168.187.202

192.168.187.203

Shard11:10011 主節點

Shard12:10012 副節點

Shard13:10013 仲裁點

Shard21:10021 仲裁點

Shard22:10022 主節點

Shard32:10023 副節點

Shard31:10031 副節點

Shard32:10032 仲裁點

Shard33:10033 主節點

ConfigSvr:10041

ConfigSvr:10042

ConfigSvr:10043

Mongos:10051

Mongos:10052

Mongos:10053

 

2.  配置Shard + Replica Sets

2.1系統配置

Linux作業系統引數

系統全域性允許分配的最大檔案控制代碼數:

sysctl -w fs.file-max=2097152

sysctl -w fs.nr_open=2097152

echo 2097152 > /proc/sys/fs/nr_open

允許當前會話/程序開啟檔案控制代碼數:

ulimit -n 1048576

修改 ‘fs.file-max’ 設定到 /etc/sysctl.conf 檔案:

fs.file-max = 1048576

修改/etc/security/limits.conf 持久化設定允許使用者/程序開啟檔案控制代碼數

* soft nofile 1048576

* hard nofile 1048576

* soft nproc 524288

* hard nproc 524288

TCP 協議棧網路引數

併發連線 backlog 設定:

sysctl -w net.core.somaxconn=32768

sysctl -w net.ipv4.tcp_max_syn_backlog=16384

sysctl -w net.core.netdev_max_backlog=16384

可用知名埠範圍:

sysctl -w net.ipv4.ip_local_port_range=80 65535'

TCP Socket 讀寫 Buffer 設定:

sysctl -w net.core.rmem_default=262144

sysctl -w net.core.wmem_default=262144

sysctl -w net.core.rmem_max=16777216

sysctl -w net.core.wmem_max=16777216

sysctl -w net.core.optmem_max=16777216

sysctl -w net.ipv4.tcp_rmem='1024 4096 16777216'

sysctl -w net.ipv4.tcp_wmem='1024 4096 16777216'

TCP 連線追蹤設定(Centos7以下才有,以上版本則不用):

sysctl -w net.nf_conntrack_max=1000000

sysctl -w net.netfilter.nf_conntrack_max=1000000

sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30

2.2 安裝

統一分別在三臺機器的/opt/app/mongoCluster369部署mongodb叢集。

在linux官網下載mongodb的安裝包,目前所用安裝包為:mongodb-linux-x86_64-rhel70-3.6.9.tgz

現在以192.168.31.231機器上操作為例:

使用命令tar -zxvf mongodb-linux-x86_64-rhel70-3.6.9.tgz 解壓mongodb

 

解壓後檢視如下:

 

把mongodb-linux-x86_64-rhel70-3.6.9移動到指定目錄,當前指定目錄為/opt/app/,並改名為mongodb

 

在該臺機器上mongodbCluster369目錄中建立conf(配置檔案)、mongos(路由)、config(配置)、shard1、shard2、shard3(三個切片)六個目錄,因為mongos不儲存資料,只需要建立日誌檔案即可。

mkdir -p /opt/app/mongodbCluster369/conf

mkdir -p /opt/app/mongodbCluster369/mongos/log

mkdir -p /opt/app/mongodbCluster369/mongos/pid

mkdir -p /opt/app/mongodbCluster369/config/data

mkdir -p /opt/app/mongodbCluster369/config/log

mkdir -p /opt/app/mongodbCluster369/config/pid

mkdir -p /opt/app/mongodbCluster369/shard1/data

mkdir -p /opt/app/mongodbCluster369/shard1/log

mkdir -p /opt/app/mongodbCluster369/shard1/pid

mkdir -p /opt/app/mongodbCluster369/shard2/data

mkdir -p /opt/app/mongodbCluster369/shard2/log

mkdir -p /opt/app/mongodbCluster369/shard2/pid

mkdir -p /opt/app/mongodbCluster369/shard3/data

mkdir -p /opt/app/mongodbCluster369/shard3/log

mkdir -p /opt/app/mongodbCluster369/shard3/pid

 

配置環境變數

vi /etc/profile

並新增如下內容:

export MONGODB_HOME=/opt/app/mongodb

export PATH=$PATH:$MONGODB_HOME/bin

 

source /etc/profile

使立即生效

2.3 配置分片副本集

設定第一個分片副本集

配置檔案

vi /opt/app/mongodbCluster369/conf/shard1.conf

 

配置檔案內容為:

#配置檔案內容

dbpath=/opt/app/mongodbCluster369/shard1/data

logpath=/opt/app/mongodbCluster369/shard1/log/shard1.log

pidfilepath=/opt/app/mongodbCluster369/shard1/pid/shard1.pid

directoryperdb=true

logappend=true

bind_ip=192.168.187.201

port=10011

oplogSize=10000

fork=true

noprealloc=true

#副本集名稱

replSet=shard1

#declare this is a shard db of a cluster

shardsvr=true

#設定最大連線數

maxConns=20000

設定第二個分片副本集

vi /opt/app/mongodbCluster369/conf/shard2.conf

 

# 配置檔案內容

dbpath=/opt/app/mongodbCluster369/shard2/data

logpath=/opt/app/mongodbCluster369/shard2/log/shard2.log

pidfilepath=/opt/app/mongodbCluster369/shard2/pid/shard2.pid

directoryperdb=true

logappend=true

bind_ip=192.168.187.201

port=10021

oplogSize=10000

fork=true

noprealloc=true

#副本集名稱

replSet=shard2

#declare this is a shard db of a cluster

shardsvr=true

#設定最大連線數

maxConns=20000

設定第三個分片副本集

vi /opt/app/mongodbCluster369/conf/shard3.conf

 

# 配置檔案內容

dbpath=/opt/app/mongodbCluster369/shard3/data

logpath=/opt/app/mongodbCluster369/shard3/log/shard3.log

pidfilepath=/opt/app/mongodbCluster369/shard3/pid/shard3.pid

directoryperdb=true

logappend=true

bind_ip=192.168.187.201

port=10031

oplogSize=10000

fork=true

noprealloc=true

#副本集名稱

replSet=shard3

#declare this is a shard db of a cluster

shardsvr=true

#設定最大連線數

maxConns=20000

2.4 config server配置伺服器

vi /opt/app/mongodbCluster369/conf/config.conf

 

# 配置檔案內容

dbpath=/opt/app/mongodbCluster369/config/data

logpath=/opt/app/mongodbCluster369/config/log/config.log

pidfilepath=/opt/app/mongodbCluster369/config/pid/config.pid

directoryperdb=true

logappend=true

bind_ip=192.168.187.201

port=10041

oplogSize=10000

fork=true

#副本集名稱

replSet=configs

#declare this is a shard db of a cluster

configsvr=true

#設定最大連線數

maxConns=20000

2.5 配置路由伺服器mongos

vi /opt/app/mongodbCluster369/conf/mongos.conf

 

# 配置檔案內容

logpath=/opt/app/mongodbCluster369/mongos/log/mongos.log

pidfilepath=/opt/app/mongodbCluster369/mongos/pid/mongos.pid

logappend=true

bind_ip=192.168.187.201

port=10051

fork=true

#監聽的配置伺服器,只能有1個或3個  configs為配置伺服器的副本集名字

configdb=configs/192.168.187.201:10041,192.168.187.202:10042,192.168.187.203:10043

#設定最大連線數

maxConns=20000

 

引數說明:

dbpath:資料存放目錄

logpath:日誌存放路徑

pidfilepath:程序檔案,方便停止mongodb

logappend:以追加的方式記錄日誌

directoryperdb:為每一個數據庫按照資料庫名建立資料夾

replSet:replica set的名字

bind_ip:mongodb所繫結的ip地址

port:mongodb程序所使用的埠號,預設為27017

fork:以後臺方式執行程序

oplogSize:mongodb操作日誌檔案的最大大小。單位為Mb,預設為硬碟剩餘空間的5%

shardsvr:分片節點

configsvr:配置服務節點

configdb:配置config節點到route節點

journal:寫日誌

smallfiles:當提示空間不夠時新增此引數

noprealloc:預分配方式,使用預分配方式來保證寫入效能的穩定,預分配在後臺執行,並且每個預分配的檔案都用0進行填充。這會讓MongoDB始終保持額外的空間和空餘的資料檔案,從而避免了資料增長過快而帶來的分配磁碟空間引起的阻塞。設定noprealloc=true來禁用預分配的資料檔案,會縮短啟動時間,但在正常操作過程中,可能會導致效能顯著下降。

2.6 分別把/opt/app/mongodb安裝包和/opt/app/mongodbCluster369配置資訊複製到其他兩臺機器上

使用命令scp -r /opt/app/mongodb [email protected]:/opt/app 複製mongodb到第二節點:

 

使用命令scp -r /opt/app/mongodbCluster369 [email protected]:/opt/app複製mongodbCluster369叢集資訊到第二節點:

 

使用root使用者登入192.168.187.202第二節點,

然後配置環境變數

vi /etc/profile

並新增如下內容:

export MONGODB_HOME=/opt/app/mongodb

export PATH=$PATH:$MONGODB_HOME/bin

 

source /etc/profile

使立即生效

 

cd /opt/app/mongodbCluster369/conf修改切片、副本集、配置、路由5個配置檔案裡面的IP和埠:

Shard1.conf修改ip:

 

Shard2.conf修改ip:

 

Shard3.conf修改ip:

 

Config.conf修改ip:

 

Mongos.conf修改ip:

 

 

使用命令scp -r /opt/app/mongodb [email protected]:/opt/app 複製mongodb到第三節點:

 

使用命令scp -r /opt/app/mongodbCluster369 [email protected]03:/opt/app複製mongodbCluster369叢集資訊到第三節點:

 

使用root使用者登入192.168.187.203第三節點,

然後配置環境變數

vi /etc/profile

並新增如下內容:

export MONGODB_HOME=/opt/app/mongodb

export PATH=$PATH:$MONGODB_HOME/bin

 

source /etc/profile

使立即生效

 

cd /opt/app/mongodbCluster369/conf中修改切片、副本集、配置、路由5個配置檔案裡面的IP和埠:

Shard1.conf修改ip:

 

Shard2.conf修改ip:

 

Shard3.conf修改ip:

 

Config.conf修改ip:

 

Mongos.conf修改ip:

 

2.7 啟動mongodb叢集

先啟動配置伺服器和分片伺服器,後啟動路由例項(三臺伺服器)。

2.7.1啟動配置伺服器

啟動三臺伺服器的config server

進入mongodb的安裝包目錄/opt/app/mongodb,使用如下命令啟動:

cd /opt/app/mongodb/bin

./mongod -f /opt/app/mongodbCluster369/conf/config.conf

 

登入任意一臺伺服器,初始化配置副本集

登入連線命令:./mongo 192.168.187.201:10041/admin

 

配置如下內容:

> config = {

...      _id : "configs",

...      members : [

...         {_id : 0, host : "192.168.187.201:10041"},

...         {_id : 1, host : "192.168.187.202:10042"},

...         {_id : 2, host : "192.168.187.203:10043"}

...      ]

... }

 

初始化副本集

> rs.initiate(config)

其中,“_id” : “configs” 應與配置檔案中配置的replSet一致,“members”中的“host”為三個節點的ip和port

2.7.2 啟動分片伺服器

啟動三臺伺服器的shard1 server

進入mongodb的安裝包目錄/opt/app/mongodb,使用如下命令啟動:

cd /opt/app/mongodb/bin

./mongod -f /opt/app/mongodbCluster369/conf/shard1.conf

 

登入192.168.187.201一臺伺服器(192.168.187.203設定為仲裁節點,不能使用該節點登入),初始化分片副本集

登入連線命令:./mongo 192.168.187.201:10011/admin

 

配置如下內容:

> config = {

...      _id : "shard1",

...      members : [

...         {_id : 0, host : "192.168.187.201:10011",priority:2},

...         {_id : 1, host : "192.168.187.202:10012",priority:1},

...         {_id : 2, host : "192.168.187.203:10013", arbiterOnly : true}

...      ]

... }

 

初始化副本集

> rs.initiate(config)

 

第三個節點的“arbiterOnly”:true代表其為仲裁節點。

使用exit命令退出mongo的shell操作介面

啟動三臺伺服器的shard2 server

進入mongodb的安裝包目錄/opt/app/mongodb,使用如下命令啟動:

cd /opt/app/mongodb/bin

./mongod -f /opt/app/mongodbCluster369/conf/shard2.conf

 

登入192.168.187.202一臺伺服器(因為192.168.187.201設定為仲裁節點,不能使用該節點登入),初始化分片副本集

登入連線命令:./mongo 192.168.187.202:10022/admin

 

配置如下內容:

> config = {

...      _id : "shard2",

...      members : [

...         {_id : 0, host : "192.168.187.201:10021", arbiterOnly : true },

...         {_id : 1, host : "192.168.187.202:10022",priority:2},

...         {_id : 2, host : "192.168.187.203:10023",priority:1}

...      ]

... }

 

初始化副本集

> rs.initiate(config)

 

第一個節點的“arbiterOnly”:true代表其為仲裁節點。

使用exit命令退出mongo的shell操作介面

啟動三臺伺服器的shard3 server

進入mongodb的安裝包目錄/opt/app/mongodb,使用如下命令啟動:

cd /opt/app/mongodb/bin

./mongod -f /opt/app/mongodbCluster369/conf/shard3.conf

 

登入192.168.187.201一臺伺服器(192.168.187.202設定為仲裁節點,不能使用該節點登入),初始化分片副本集

登入連線命令:./mongo 192.168.187.201:10031/admin

 

配置如下內容:

> config = {

...      _id : "shard3",

...      members : [

...         {_id : 0, host : "192.168.187.201:10031",priority:1},

...         {_id : 1, host : "192.168.187.202:10032", arbiterOnly : true },

...         {_id : 2, host : "192.168.187.203:10033",priority:2}

...      ]

... }

 

初始化副本集

> rs.initiate(config)

 

第二個節點的“arbiterOnly”:true代表其為仲裁節點。

使用exit命令退出mongo的shell操作介面

2.7.3啟動路由例項

啟動三臺伺服器的mongos server

       使用如下命令

進入mongodb的安裝包目錄/opt/app/mongodb,使用如下命令啟動:

cd /opt/app/mongodb/bin

./mongos -f /opt/app/mongodbCluster369/conf/mongos.conf

 

2.8 啟用分片

目前搭建了mongodb配置伺服器、路由伺服器、各個分片伺服器,不過應用程式連線到mongos路由伺服器並不能使用分片機制,還需要在程式裡設定分片配置,讓分片生效。

登入任意一臺mongos,這裡以192.168.187.201:10051為例:

登入連線命令:./mongo 192.168.187.201:10051/admin

 

配置如下內容,串聯路由伺服器與切片副本集:

sh.addShard("shard1/192.168.187.201:10011,192.168.187.202:10012,192.168.187.203:10013")

sh.addShard("shard2/192.168.187.201:10021,192.168.187.202:10022,192.168.187.203:10023")

sh.addShard("shard3/192.168.187.201:10031,192.168.187.202:10032,192.168.187.203:10033")

 

檢視叢集狀態:

sh.status()

2.9 指定資料庫與集合分片生效

目前配置服務、路由服務、分片服務、副本集服務都已經串聯起來了,但是我們的目的是希望插入資料、資料能夠自動分片。連線在mongos上,準備讓指定的資料庫、指定的集合分片生效。

接著上面2.6的步驟,不用退出mongos的操作介面

指定資料庫分片生效:

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

 

指定資料庫裡需要分片的集合collection和片鍵,一般是_id:

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

 

我們設定testdb的table1表需要分片,根據id自動分片到shard1、shard2、shard3上面去。要這樣設定是因為不是所有mongodb的資料庫和表都需要分片!

2.10 測試分片配置結果

登入任意一臺mongos,這裡以192.168.187.201:10051為例:

登入連線命令:./mongo 192.168.187.201:10051/admin

切換資料庫:

use testdb

輸入如下命令:

for (var i = 1; i <= 5000; i++){ db.table1.insert({id:i,text:"hello world"}) }

 

檢視分配狀態:

db.table1.stats()

如下圖所示:shard1總數:1664條

 

Shard2總數:1684條

 

Shard3總數:1652條

 

可以看到資料分到3個分片。已經成功了。

3. 後期運維

mongodbd的啟動順序是,先啟動配置伺服器,再啟動分片,最後啟動mongos。

mongod -f /opt/app/mongodbCluster369/conf/config.conf

mongod -f /opt/app/mongodbCluster369/conf/shard1.conf

mongod -f  /opt/app/mongodbCluster369/conf/shard2.conf

mongod -f /opt/app/mongodbCluster369/conf/shard3.conf

mongos -f /opt/app/mongodbCluster369/conf/mongos.conf

關閉時,直接killall殺掉所有程序

killall mongod
killall mongos

4. 問題發現:

問題一:--maxConnx過高

 

這與linux預設程序能開啟最大檔案數有關,可以通過ulimit解決.mongodb最大連線是20000

解決:ulimit -n 30000

問題二:報錯is not electable under the new configuration version 1

 

解決:如果你設定的第一個節點是仲裁節點的話,那麼設定登入設定節點狀態的哪個客戶端不能是仲裁節點,簡單做法 換一個節點

 

參考資料:

http://www.ityouknow.com/mongodb/2017/08/05/mongodb-cluster-setup.html

https://www.cnblogs.com/smartloli/p/4305739.html

https://blog.csdn.net/caofeiliju/article/details/80193997