MongoDB3.6 一键化自动部署方案

Posted 牧梦者

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB3.6 一键化自动部署方案相关的知识,希望对你有一定的参考价值。

1.系统基础配置

下面的命令默认都使用root用户进行操作,操作系统为Centos7,mongodb3.6.x以上版本

1.1 修改系统配置文件/etc/security/limits.conf和/etc/profile

 修改/etc/security/limits.conf持久化设置允许用户/进程打开文件句柄数,这一步需要重启系统,不然不起作用

* soft nofile 1048576

* hard nofile 1048576

* soft nproc 524288

* hard nproc 524288

修改/etc/profile,在最后添加ulimit -s 1024,然后保存并source /etc/profile

1.2 关闭每台机器的防火墙

Centos7以下命令:

chkconfig iptables off && service iptables stop

 

使用命令查看chkconfig --list 是否设置自动启动为关闭

Centos7以上命令:

systemctl stop firewalld

systemctl is-enabled firewalld  

1.3 每台机器修改/etc/hosts和hostname

在/etc/hosts添加集群所有的ip及对应的hostname

注意:配置的ip数与选择的模板相关联

1.4 机器之间配置ssh免密登录

每台机器分别执行下面命令,这里以5台机器为准:

ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa

ssh-copy-id node1

ssh-copy-id node2

ssh-copy-id node3

ssh-copy-id node4

ssh-copy-id node5

1.5 检测自动化部署所需的命令是否可用

ifconfig、ssh需要可用

需要安装numactl,使用rpm -qa | grep numactl查看numactl是否已安装

注意:完成上面5步操作后重启每台机器。重启完毕,使用命令ulimit -a 查看

要保证 open files 对应的值为 1048576

Stack size 对应的值为1024

Max user processes对应的值为 524288

1.6 检查mongodb安装下bin目录和shell目录执行权限

进入到shell目录,执行chmod +x auto*加执行权限

进入mongodb的bin目录,执行chmod +x ./*加执行权限

2.MongoDB 一键化部署

2.1 一键化部署shell文件介绍

shell脚本文件目前放置在mongodb的安装目录下:

⑪config.properties,配置文件,包括mongodb安装目录、mongoCluster集群安装目录、所需主机、数据库等等。如图:

 

上图几个参数可能需要随环境不同而修改。

说明:

ips=192.168.187.201, 192.168.187.202, 192.168.187.203, 192.168.187.204, 192.168.187.205

这里默认192.168.187.201为mongdb集群的节点node1,192.168.187.202为mongdb集群的节点node2,192.168.187.203为mongdb集群的节点node3,192.168.187.204为mongdb集群的节点node4,,192.168.187.205为mongdb集群的节点node5。

template与ips的ip数量对应,ips的ip数为5,则意味着采用5台机器的模板,这里默认为5。

⑬template 目录包括3.conf、4.conf和5.conf,为mongodb3台机器、4台机器和5台机器安装模板,有需要者可以自行修改模板。

3.conf 3台机器分配的mongodb节点模板为

#所有mongo节点
nodes=config,shard1,shard2,shard3,mongos
#机器分配到的mongo节点
node1=mongos,config,shard1,shard2,shard3
node2=mongos,config,shard1,shard2,shard3
node3=mongos,config,shard1,shard2,shard3
#mongo节点分配到的机器,注意shard部分排在第一的为master,第二为secondary,第三位arbitery
config=node1,node2,node3
mongos=node1,node2,node3
shard1=node1,node2,node3
shard2=node2,node3,node1
shard3=node3,node2,node1
#mongo节点端口
config_port=29040
mongos_port=29050
shard1_port=29010
shard2_port=29020
shard3_port=29030

注意:这里的node1、node2、node3不是机器hostname(当然也可以以这种node1、node2方式去命名hostname),只是机器ip的代名称,因为不同开发环境中的ip总是不同的,所以使用node1、node2...去代替变化的ip。这里的node1、node2、node3默认与config.properties中的ips属性对应,即ips中的第一个ip默认为node1,第二个ip默认为node2,第三个ip默认为node3,4.conf和5.conf类同。查看下图,可以清晰看到mongodb分布的节点:

4.conf 4台机器分配mongodb节点的模版为

#所有mongo节点
nodes=config,shard1,shard2,shard3,shard4,mongos
#机器分配到的mongo节点
node1=mongos,shard1,shard3,shard4
node2=mongos,config,shard1,shard2,shard4
node3=mongos,config,shard1,shard2,shard3
node4=config,shard2,shard3,shard4
#mongo节点分配到的机器,注意shard部分排在第一的为master,第二为secondary,第三位arbitery
config=node2,node3,node4
mongos=node1,node2,node3
shard1=node1,node2,node3
shard2=node2,node3,node4
shard3=node3,node4,node1
shard4=node4,node1,node2
#mongo节点端口
config_port=29040
mongos_port=29050
shard1_port=29000
shard2_port=29010
shard3_port=29020
shard4_port=29030

5.conf 5台机器分配mongodb节点的模版为

#所有mongo节点
nodes=config,shard1,shard2,shard3,shard4,shard5,mongos
#机器分配到的mongo节点
node1=mongos,shard1,shard4,shard5
node2=mongos,shard1,shard2,shard5
node3=config,shard1,shard2,shard3
node4=config,shard2,shard3,shard4
node5=config,shard3,shard4,shard5
#mongo节点分配到的机器, 注意shard部分排在第一的为master,第二为secondary,第三位arbitery
config=node3,node4,node5
mongos=node1,node2
shard1=node1,node2,node3
shard2=node2,node3,node4
shard3=node3,node4,node5
shard4=node4,node5,node1
shard5=node5,node1,node2
#mongo节点端口
config_port=29040
mongos_port=29050
shard1_port=29060
shard2_port=29070
shard3_port=29080
shard4_port=29090
shard5_port=29100

模板需要配置的几项内容:

  • mongodb所有节点
  • 每台机器分配的mongodb节点
  • 每个mongodb节点分配的机器
  • mongo节点的端口

如有需要,可自行配置6、7或者更多的机器分配mongo模板

①autoCheckLive.sh脚本为创建所在服务器对应的mongodb的进程存活监控,不存在则自动拉起。

#! /bin/bash

#shell目录的绝对路径
shellPath=$1
configPath=$shellPath/config.properties
#从config.properties文件读取数据出来
clusterPath=`awk -F= -v k=clusterPath \'{ if ( $1 == k ) print $2; }\' $configPath`
template=`awk -F= -v k=template \'{ if ( $1 == k ) print $2; }\' $configPath`
templatePath=$shellPath/template/$template.conf

ips=`awk -F= -v k=ips \'{ if ( $1 == k ) print $2; }\' $configPath`
#ip数组
eval $(echo $ips | awk \'{split($0, arr, ","); for(i in arr) print "ipArray["i"]="arr[i]}\')
#本地ip
localIp=`/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6 | awk \'{print $2}\' | tr -d "addr:"`

suffix=""
#判断linux系统cpu是否为numa架构,如果是则传回_numa,禁用numactl
numaCount=`grep -i numa /var/log/dmesg | wc -l`
nodeCount=`grep -i numa /var/log/dmesg | grep -wi "node" | wc -l`
offCount=`grep -i numa /var/log/dmesg | grep -wi "numa=off" | wc -l`
if [[ ($numaCount -gt 1) && ($nodeCount -gt 1) && ($offCount -eq 0) ]]
then
    suffix="_numa"
fi

#遍历ip数组
for((i=1; i<=${#ipArray[@]}; i++))
do
  #获取本地ip在模板中的代称号,根据本地ip所在ip数组中的下标数字获取
  if [[ $localIp = ${ipArray[i]} ]]
  then
       #获取模板中本地ip对应的代称号所拥有的mongo节点
       mongodbNodes=`awk -F= -v k=node$i \'{ if ( $1 == k ) print $2; }\' $templatePath`
       eval $(echo $mongodbNodes | awk \'{split($0, mongodbArr, ","); for(y in mongodbArr) print "mongodbArray["y"]="mongodbArr[y]}\')
       for n in ${mongodbArray[*]}
       do
         pid=`cat $clusterPath/$n/pid/$n.pid`
         #判断是否存活
         count=`ps -ef | grep $pid | grep -v grep | wc -l`
         #程序挂掉啦,启动
         if [ $count -eq 0 ];then
            cd $shellPath && $shellPath/autoStartUp.sh $n$suffix
         fi
       done
  fi
done

②autoClusterClose.sh脚本为mongodb集群关闭脚本,用法:./autoClusterClose.sh shutdown或者./autoClusterClose.sh kill,这里建议使用shutdown方式关闭。

#! /bin/bash

configPath=config.properties
#mongodb的安装目录
mongodb_home=`awk -F= -v k=mongodbHome \'{ if ( $1 == k ) print $2; }\' $configPath`
#mongodb集群安装目录
clusterPath=`awk -F= -v k=clusterPath \'{ if ( $1 == k ) print $2; }\' $configPath`
#所采用的安装模板
template=`awk -F= -v k=template \'{ if ( $1 == k ) print $2; }\' $configPath`
#模板所在的位置
templatePath=template/$template.conf
user=`awk -F= -v k=user \'{ if ( $1 == k ) print $2; }\' $configPath`
localIp=`/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6 | awk \'{print $2}\' | tr -d "addr:"`

ips=`awk -F= -v k=ips \'{ if ( $1 == k ) print $2; }\' $configPath`
eval $(echo $ips | awk \'{split($0, arr, ","); for(i in arr) print "ipArray["i"]="arr[i]}\')

#获取所有的配置、路由、分片
nodes=`awk -F= -v k=nodes \'{ if ( $1 == k ) print $2; }\' $templatePath`
eval $(echo $nodes | awk \'{split($0, nodeArr, ","); for(i in nodeArr) print "nodeArray["i"]="nodeArr[i]}\')

#查看/etc/crontab是否开启定时任务,有则关闭
for((i=1; i<=${#ipArray[@]}; i++))
do
   if [[ $localIp = ${ipArray[i]} ]]
   then
       #kill本地的mongod、mongos
       echo "*****close ${ipArray[i]} 定时任务:日志切割和mongo进程存活监控*****"
       $mongodb_home/shell/autoConfig.sh removeCronTask
   else
       echo "*****close ${ipArray[i]} 定时任务:日志切割和mongo进程存活监控*****"
       ssh $user@${ipArray[i]} "cd $mongodb_home/shell && $mongodb_home/shell/autoConfig.sh removeCronTask"
    fi
done

if [[ $1 = "kill" ]]
then
  for((i=1; i<=${#ipArray[@]}; i++))
  do
    if [[ $localIp = ${ipArray[i]} ]]
    then
       #kill本地的mongod、mongos
       echo "*****close ${ipArray[i]} mongodb*****"
       ps -ef | grep $clusterPath/conf | grep -v grep | cut -c 9-15 | xargs kill -2
    else
       echo "*****close ${ipArray[i]} mongodb*****"
       ssh $user@${ipArray[i]} "ps -ef | grep $clusterPath/conf | grep -v grep | cut -c 9-15 | xargs kill -2"
    fi
  done
fi

if [[ $1 = "shutdown" ]]
then
  #1.先关闭mongos
  #找到mongos对应的机器节点
  mongoss=`awk -F= -v k=mongos \'{ if ( $1 == k ) print $2; }\' $templatePath`
  eval $(echo $mongoss | awk \'{split($0, mongosArr, ","); for(i in mongosArr) print "mongosArray["i"]="mongosArr[i]}\')
  for mongosNode in ${mongosArray[*]}
  do
    #删除node,保留右边字符。下面两句是根据机器节点的代名称数字找到其对应的ip
    mongosIpNum=${mongosNode#*node}
    mongosIp=${ipArray[$mongosIpNum]}
    if [[ $localIp = $mongosIp ]]
    then
       echo "****************close $mongosIp mongos****************"
       ps -ef | grep $clusterPath/conf/mongos.conf | grep -v grep | cut -c 9-15 | xargs kill -2
    else
       echo "****************close $mongosIp mongos****************"
       ssh $user@$mongosIp "ps -ef | grep $clusterPath/conf/mongos.conf | grep -v grep | cut -c 9-15 | xargs kill -2"
    fi
  done
  
  #2.再关闭configs
  configs=`awk -F= -v k=config \'{ if ( $1 == k ) print $2; }\' $templatePath`
  eval $(echo $configs | awk \'{split($0, configArr, ","); for(i in configArr) print "configArray["i"]="configArr[i]}\')
  #副本集,先关闭仲裁节点、从节点,最后关闭主节点
  for((i=${#configArray[@]}; i>=1; i--))
  do
    configNode=${configArray[i]}
    #删除node,保留右边字符
    configIpNum=${configNode#*node}
    configIp=${ipArray[$configIpNum]}
    if [[ $localIp = $configIp ]]
    then
       echo "****************close $configIp config****************"
       $mongodb_home/bin/mongod -f $clusterPath/conf/config.conf --shutdown
    else
       echo "****************close $configIp config****************"
       ssh $user@$configIp "$mongodb_home/bin/mongod -f $clusterPath/conf/config.conf --shutdown"
    fi
  done

  #3.最后关闭shards
  for node in ${nodeArray[*]}
    do
       if [[ $node =~ "shard"  ]]         
       then
           shards=`awk -F= -v k=$node \'{ if ( $1 == k ) print $2; }\' $templatePath`
           eval $(echo $shards | awk \'{split($0, shardArr, ","); for(i in shardArr) print "shardArray["i"]="shardArr[i]}\')
           #副本集,先关闭仲裁节点、从节点,最后关闭主节点
           for((i=${#shardArray[@]}; i>=1; i--))
           do
              shardNode=${shardArray[i]}
              #删除node,保留右边字符
              shardIpNum=${shardNode#*node}
              shardIp=${ipArray[$shardIpNum]}
              if [[ $localIp = $shardIp ]]
              then
                 echo "****************close $shardIp $node****************"
                 $mongodb_home/bin/mongod -f $clusterPath/conf/$node.conf --shutdown
              else
                 echo "****************close $shardIp $node****************"
                 ssh $user@$shardIp "$mongodb_home/bin/mongod -f $clusterPath/conf/$node.conf --shutdown"
              fi
           done
       fi
    done
fi

③autoClusterIndex.sh脚本为mongodb集群初始化配置文件和修改系统配置、config和shard副本集以及mongos路由启动并初始化、mongodb集群数据库表分片和基础数据初始化的脚本、添加定时任务。用法:./ autoClusterIndex.sh。使用该脚本,可以全自动化安装mongodb

#! /bin/bash

configPath=config.properties
#从config.properties文件读取数据出来
clusterPath=`awk -F= -v k=clusterPath \'{ if ( $1 == k ) print $2; }\' $configPath`
mongodb_home=`awk -F= -v k=mongodbHome \'{ if ( $1 == k ) print $2; }\' $configPath`
ips=`awk -F= -v k=ips \'{ if ( $1 == k ) print $2; }\' $configPath`
localIp=`/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6 | awk \'{print $2}\' | tr -d "addr:"`
user=`awk -F= -v k=user \'{ if ( $1 == k ) print $2; }\' $configPath`
template=`awk -F= -v k=template \'{ if ( $1 == k ) print $2; }\' $configPath`
templatePath=template/$template.conf
#获取所有的配置、路由、分片
nodes=`awk -F= -v k=nodes \'{ if ( $1 == k ) print $2; }\' $templatePath`
eval $(echo $nodes | awk \'{split($0, nodeArr, ","); for(i in nodeArr) print "nodeArray["i"]="nodeArr[i]}\')
eval $(echo $ips | awk \'{split($0, arr, ","); for(i in arr) print "ipArray["i"]="arr[i]}\')

#遍历ip数组
for((i=1; i<=${#ipArray[@]}; i++))
do
  if [[ $localIp = ${ipArray[i]} ]]
  then
     #1.创建mongodbCluster并修改系统配置
     echo "********************************start ${ipArray[i]} autoConfig && autoSystemProperties********************************"
     $mongodb_home/shell/autoConfig.sh && $mongodb_home/shell/autoSystemProperties.sh
  else
     #把远程服务器旧的mongodb安装包删除
     ssh $user@${ipArray[i]} "rm -rf $mongodb_home"
     #把mongodb安装包拷贝到远程服务器
     scp -r $mongodb_home $user@${ipArray[i]}:$mongodb_home
     echo "********************************start ${ipArray[i]} autoConfig && autoSystemProperties********************************"
     ssh $user@${ipArray[i]} "cd $mongodb_home/shell && $mongodb_home/shell/autoConfig.sh && $mongodb_home/shell/autoSystemProperties.sh"
  fi
done

#2.mongodb集群启动config、shard1、shard2、shard3
echo "********************************start mongodb集群启动config、shard1、shard2、shard3********************************"
#不启动mongos,只启动config,shards
$mongodb_home/shell/autoClusterStartUp.sh notmongos

#3.mongodb集群配置、分片的副本集初始化
echo "********************************start mongodb集群分片和副本集初始化********************************"
$mongodb_home/shell/autoClusterInitSvr.sh cs

#4.mongodb集群启动mongos
echo "********************************start mongodb集群mongos********************************"
mongoss=`awk -F= -v k=mongos \'{ if ( $1 == k ) print $2; }\' $templatePath`
eval $(echo $mongoss | awk \'{split($0, mongosArr, ","); for(i in mongosArr) print "mongosArray["i"]="mongosArr[i]}\')
for mongosNode in ${mongosArray[*]}
do
  #删除node,保留右边字符
  mongosIpNum=${mongosNode#*node}
  mongosIp=${ipArray[$mongosIpNum]}
  if [[ $localIp = $mongosIp ]]
  then
      echo "****************start $mongosIp mongos****************"
      $mongodb_home/shell/autoStartUp.sh mongos
  else
      echo "****************start $mongosIp mongos****************"
      ssh $user@$mongosIp "cd $mongodb_home/shell && ./autoStartUp.sh mongos"
  fi
done

#5.mongodb集群mongos初始化
echo "********************************start mongodb集群mongos初始化********************************"
$mongodb_home/shell/autoClusterInitSvr.sh mongos

#6.mongodb集群数据库表分片和初始化
echo "********************************start mongodb集群数据库表分片和初始化********************************"
$mongodb_home/shell/autoClusterShardedAndInitDB.sh

#7.mongodb集群配置定时任务:日志每天切割,保留7天日志/每隔10分钟监控mongo进程是否存活,不存活则自动拉起
for((i=1; i<=${#ipArray[@]}; i++))
do
  if [[ $localIp = ${ipArray[i]} ]]
  then
     echo "******************************** ${ipArray[i]} 添加定时任务:日志切割和mongo存活监控 ********************************"
     $mongodb_home/shell/autoConfig.sh addCronTask    
  else
     echo "******************************** ${ipArray[i]} 添加定时任务:日志切割和mongo存活监控 ********************************"
     ssh $user@${ipArray[i]} "cd $mongodb_home/shell && $mongodb_home/shell/autoConfig.sh addCronTask"
  fi
done

④autoClusterInitSvr.sh脚本为mongodb集群config、shard和mongos初始化脚本。用法:./autoClusterInitSvr.sh cs,初始化config和shard副本集配置;./autoClusterInitSvr.sh mongos,初始化mongos路由配置。

#! /bin/bash

configPath=config.properties

mongodb_home=`awk -F= -v k=mongodbHome \'{ if ( $1 == k ) print $2; }\' $configPath`
template=`awk -F= -v k=template \'{ if ( $1 == k ) print $2; }\' $configPath`
templatePath=template/$template.conf
ips=`awk -F= -v k=ips \'{ if ( $1 == k ) print $2; }\' $configPath`
eval $(echo $ips | awk \'{split($0, arr, ","); for(i in arr) print "ipArray["i"]="arr[i]}\')

#获取所有的配置、路由、分片
nodes=`awk -F= -v k=nodes \'{ if ( $1 == k ) print $2; }\' $templatePath`
eval $(echo $nodes | awk \'{split($0, nodeArr, ","); for(i in nodeArr) print "nodeArray["i"]="nodeArr[i]}\')
param=$1

if [[ $param = "cs" ]]
then    
    #自动化设置配置副本集
    config_numbers=""
    ccount=0
    config_port=`awk -F= -v k=config_port \'{ if ( $1 == k ) print $2; }\' $templatePath`
    configs=`awk -F= -v k=config \'{ if ( $1 == k ) print $2; }\' $templatePath`
    eval $(echo $configs | awk \'{split($0, configArr, ","); for(i in configArr) print "configArray["i"]="configArr[i]}\')
    configMasterNode=${configArray[1]}
    echo "configMasterNode: $configMasterNode"
    #删除node,保留右边字符
    configMasterIpNum=${configMasterNode#*node}
    #echo "configMasterIpNum: $configMasterIpNum"
    configMasterIp=${ipArray[$configMasterIpNum]}
    #echo "configMasterIp: $configMasterIp"
    for((i=1; i<=${#configArray[@]}; i++))
    do
       configNode=${configArray[i]}
       #删除node,保留右边字符
       configIpNum=${configNode#*node}
       config_numbers=$config_numbers"{_id : $ccount, host : \'${ipArray[$configIpNum]}:$config_port\'},"
       ccount=`expr $ccount + 1`
    done
    #删除最后一个,保留左边字符
    echo "********************************设置config副本集********************************"
    config_numbers=${config_numbers%,*}
    echo $config_numbers
    $mongodb_home/bin/mongo $configMasterIp:$config_port/admin << EOF
config = {_id : "configs", members : [ $config_numbers ] };
rs.initiate(config);
EOF

    #自动化设置分片shard副本集
    for node in ${nodeArray[*]}
    do
       if [[ $node =~ "shard"  ]]         
       then
           shard_numbers=""
           shardMasterIp=""
           scount=0
           shard_port=`awk -F= -v k=$node"_port" \'{ if ( $1 == k ) print $2; }\' $templatePath`
           shards=`awk -F= -v k=$node \'{ if ( $1 == k ) print $2; }\' $templatePath`
           eval $(echo $shards | awk \'{split($0, shardArr, ","); for(i in shardArr) print "shardArray["i"]="shardArr[i]}\')
           for((i=1; i<=${#shardArray[@]}; i++))
           do
              shardNode=${shardArray[i]}
              #echo "shardNode: $shardNode"
              #删除node,保留右边字符
              shardIpNum=${shardNode#*node}
              #echo "shardIpNum: $shardIpNum"
              if [[ $scount = 0 ]]
              then
                  shardMasterIp=${ipArray[$shardIpNum]}
                  shard_numbers=$shard_numbers"{_id : $scount, host : \'${ipArray[$shardIpNum]}:$shard_port\', priority : 2},"
              fi
              if [[ $scount = 1 ]]
              then
                  shard_numbers=$shard_numbers"{_id : $scount, host : \'${ipArray[$shardIpNum]}:$shard_port\', priority : 1},"
              fi
              if [[ $scount = 2 ]]
              then
                  shard_numbers=$shard_numbers"{_id : $scount, host : \'${ipArray[$shardIpNum]}:$shard_port\', arbiterOnly : true}"
              fi
              scount=`expr $scount + 1`
           done
              #echo "shard_numbers: $shard_numbers"
              echo "********************************设置$node副本集********************************"
              $mongodb_home/bin/mongo $shardMasterIp:$shard_port/admin << EOF
config = {_id : "$node", members : [ $shard_numbers ] };
rs.initiate(config);
EOF
       fi
    done
fi

if [[ $param = "mongos" ]]
then  
    #自动化设置路由分片
    mongos_numbers=""
    mongos_port=`awk -F= -v k=mongos_port \'{ if ( $1 == k ) print $2; }\' $templatePath`
    mongoss=`awk -F= -v k=mongos \'{ if ( $1 == k ) print $2; }\' $templatePath`
    eval $(echo $mongoss | awk \'{split($0, mongosArr, ","); for(i in mongosArr) print "mongosArray["i"]="mongosArr[i]}\')
    mongosNode=${mongosArray[1]}
    #删除node,保留右边字符
    mongosIpNum=${mongosNode#*node}
    mongosIp=${ipArray[$mongosIpNum]}
    for node in ${nodeArray[*]}
    ansible-playbook一键化部署apache服务

一键自动化部署(定制rpm包,yum仓库)

jenkins+svn+maven+tomcat一键构建部署

jenkins+svn+maven+tomcat一键构建部署

自动化部署

MongoDB3.6 分片集群