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 (从节点切换仲裁节点)

 

posted @ 2018-12-03 01:18  牧梦者  阅读(3105)  评论(1编辑  收藏  举报