MongoDB 3.6.9 集群搭建 - 切片+副本集


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

 

配置文件內容為:

#配置文件內容

systemLog:
  destination: file
  path: /opt/app/mongodbCluster369/shard1/log/shard1.log
  logAppend: true
processManagement:
  fork: true
  pidFilePath: /opt/app/mongodbCluster369/shard1/pid/shard1.pid
net:
  bindIp: 192.168.187.201
  port: 10011
  maxIncomingConnections: 20000
storage:
  dbPath: /opt/app/mongodbCluster369/shard1/data
  journal: 
    enabled: true
    commitIntervalMs: 500
  directoryPerDB: true
  syncPeriodSecs: 300
  engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 103
      statisticsLogDelaySecs: 0
      journalCompressor: snappy
      directoryForIndexes: false
    collectionConfig:
      blockCompressor: snappy
    indexConfig:
      prefixCompression: true
replication:
  oplogSizeMB: 10000
  replSetName: shard1
sharding:
  clusterRole: shardsvr

設置第二個分片副本集

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

 

# 配置文件內容

systemLog:
  destination: file
  path: /opt/app/mongodbCluster369/shard2/log/shard2.log
  logAppend: true
processManagement:
  fork: true
  pidFilePath: /opt/app/mongodbCluster369/shard2/pid/shard2.pid
net:
  bindIp: 192.168.187.201
  port: 10021
  maxIncomingConnections: 20000
storage:
  dbPath: /opt/app/mongodbCluster369/shard2/data
  journal: 
    enabled: true
    commitIntervalMs: 500
  directoryPerDB: true
  syncPeriodSecs: 300
  engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 103
      statisticsLogDelaySecs: 0
      journalCompressor: snappy
      directoryForIndexes: false
    collectionConfig:
      blockCompressor: snappy
    indexConfig:
      prefixCompression: true
replication:
  oplogSizeMB: 10000
  replSetName: shard2
sharding:
  clusterRole: shardsvr

設置第三個分片副本集

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

 

# 配置文件內容

 

systemLog:
  destination: file
  path: /opt/app/mongodbCluster369/shard3/log/shard3.log
  logAppend: true
processManagement:
  fork: true
  pidFilePath: /opt/app/mongodbCluster369/shard3/pid/shard3.pid
net:
  bindIp: 192.168.187.201
  port: 10031
  maxIncomingConnections: 20000
storage:
  dbPath: /opt/app/mongodbCluster369/shard3/data
  journal: 
    enabled: true
    commitIntervalMs: 500
  directoryPerDB: true
  syncPeriodSecs: 300
  engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 103
      statisticsLogDelaySecs: 0
      journalCompressor: snappy
      directoryForIndexes: false
    collectionConfig:
      blockCompressor: snappy
    indexConfig:
      prefixCompression: true
replication:
  oplogSizeMB: 10000
  replSetName: shard3
sharding:
  clusterRole: shardsvr

 

2.4 config server配置服務器

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

 

# 配置文件內容

systemLog:
  destination: file
  path: /opt/app/mongodbCluster369/config/log/config.log
  logAppend: true 
processManagement:
  fork: true
  pidFilePath: /opt/app/mongodbCluster369/config/pid/config.pid
net:
  bindIp: 192.168.187.201
  port: 10041
  maxIncomingConnections: 20000
storage:
  dbPath: /opt/app/mongodbCluster369/config/data
  journal:
    enabled: true
    commitIntervalMs: 500
  directoryPerDB: true
  syncPeriodSecs: 300
  engine: wiredTiger
replication:
  oplogSizeMB: 10000
  replSetName: configs
sharding:
  clusterRole: configsvr

2.5 配置路由服務器mongos

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

 

# 配置文件內容

systemLog:
  destination: file
  path: /opt/app/mongodbCluster369/mongos/log/mongos.log
  logAppend: true
processManagement:
  fork: true
  pidFilePath: /opt/app/mongodbCluster369/mongos/pid/mongos.pid
net:
  bindIp: 192.168.187.201
  port: 10051
  maxIncomingConnections: 20000
sharding:
  configDB: configs/192.168.187.201:10041,192.168.187.202:10042,192.168.187.203:10043

參數說明:

dbpath:數據存放目錄

logpath:日志存放路徑

pidfilepath:進程文件,方便停止mongodb

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

directoryperdb:為每一個數據庫按照數據庫名建立文件夾

replSet:replica set的名字

bindIp: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 root@192.168.187.202:/opt/app 復制mongodb到第二節點:

 

使用命令scp -r /opt/app/mongodbCluster369 root@192.168.187.202:/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 root@192.168.187.203:/opt/app 復制mongodb到第三節點:

 

使用命令scp -r /opt/app/mongodbCluster369 root@192.168.187.203:/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

mongodb副本+分片集群添加用戶認證密碼

https://blog.csdn.net/uncle_david/article/details/78713551

http://www.mongoing.com/docs/tutorial/convert-secondary-into-arbiter.html (從節點切換仲裁節點)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM