OS:CentOS Linux release 7.9.2009 (Core)
场景:
需要半自动化或者自动化部署MongoDB集群时,可用此脚本。提高交付效率。
脚本实现架构图:
脚本:
check_clear_host.sh #此脚本有2个功能及是检查 资源规格和清理资源上的MognoDB 实全,清理动作禁止在生产或者重要的环境执行。
powershell
#!/bin/bash
without=$(python cluster_mongodb_mutil.py 'argument') #获取IP地址和密码
ips=$(echo $without|cut -d'|' -f1|cut -d':' -f2)
sshpassword=$(echo $without|cut -d'|' -f2|cut -d':' -f2)
sshuser='root'
/usr/bin/which sshpass ;if [[ "$?" != "0" ]];then yum -y install sshpass ;fi
operation=1 # 1检查机器资源配置 0删除mongodb集群(生产环境禁止使用)
function mongo_clear(){
IFS='|' read -ra elements <<< "$1"
for ip in "${elements[@]}"; do
pid=$(sshpass -p $2 ssh $3@${ip} -o StrictHostKeyChecking=no "ps -ef|grep mongo|grep -vE 'grep'|awk -F' ' '{print \$2}'")
if [ -n "$pid" ]; then
sshpass -p $2 ssh $3@${ip} -o StrictHostKeyChecking=no "kill -9 $pid"
fi
echo $ip
sshpass -p $2 ssh $3@${ip} -o StrictHostKeyChecking=no "userdel mongodb"
sshpass -p $2 ssh $3@${ip} -o StrictHostKeyChecking=no "rm -fr /data/*"
sshpass -p $2 ssh $3@${ip} -o StrictHostKeyChecking=no "cd /usr/local/ && unlink mongodb"
sshpass -p $2 ssh $3@${ip} -o StrictHostKeyChecking=no "rm -fr /opt/mongodb-linux-x86_64-rhel70-4.4.18"
done
}
function mongo_check(){
IFS='|' read -ra elements <<< "$1"
for ip in "${elements[@]}"; do
{
cpu=$(sshpass -p $2 ssh $3@${ip} -o StrictHostKeyChecking=no "cat /proc/cpuinfo | grep 'process'|wc -l")
sshpass -p $2 ssh $3@${ip} -o StrictHostKeyChecking=no "df -h|grep data"
fre=$(sshpass -p $2 ssh $3@${ip} -o StrictHostKeyChecking=no "free -m|sed -n 2p|awk -F' ' '{print \$2}'")
dik=$(sshpass -p $2 ssh $3@${ip} -o StrictHostKeyChecking=no "df -h|awk -F' ' '{print \$2}' |grep G|cut -d'G' -f1|awk '{if(NR == 1) {max = \$1} else {if(\$1 > max) {max = \$1}}} END {print max}'")
dik_free=$(sshpass -p $2 ssh $3@${ip} -o StrictHostKeyChecking=no "df -h|grep ${dik}|awk -F' ' '{print \$4}'")
echo ${ip}': '${cpu}'c,'${fre}m,${dik}g,'磁盘可用'$dik_free
} &
done
wait
}
ipss=`echo $ips|sed 's/ /|/g'`
if [ "$operation" == 0 ];then
mongo_clear ${ipss} ${sshpassword} ${sshuser}
elif [ "$operation" == 1 ];then
mongo_check $ipss $sshpassword $sshuser
fi
dbenvset_mult.sh
powershell
#!/bin/bash
sshuser='root'
without=$(python cluster_mongodb_mutil.py 'argument') #获取IP地址和密码
ips=$(echo $without|cut -d'|' -f1|cut -d':' -f2)
sshpassword=$(echo $without|cut -d'|' -f2|cut -d':' -f2)
for ip in $ips
do
{
ipp=$(ip a|grep 'inet 172'|awk -F' ' '{print $2}'|cut -d'/' -f1)
if [ "$ipp" == "$ip" ];then
sh dbenvset.sh /data 0 0
elif [ "$ipp" != "$ip" ];then
/usr/bin/sshpass -p ${sshpassword} scp dbenvset.sh root@${ip}:${dataroot}
sshpass -p $sshpassword ssh ${sshuser}@${ip} -o StrictHostKeyChecking=no "sh dbenvset.sh /data 0 0" # /data为你的数据挂载盘,请根据实际情况修改
fi
} &
done
wait
powershell
#!/bin/sh
addcmd(){
addText=$1
file=$2
#判断 file.sh 文件中是否存在该字符串
if ! grep -q "$addText" $file
then
#不存在,添加字符串
echo "$addText" >> $file
else
#存在,不做处理
echo "$addText"" exist in "$file
fi
}
if [ $# -ne 3 ];then
echo "Error: please use $0 datadir ishdd ispm"
fi
datadir=$1 #数据目录,当前规范/data
ishdd=$2 #机械硬盘为1,ssd为0
ispm=$3 #物理机1,虚机0,容器2
#source /etc/profile
if [ $ispm -ne 2 ];then
systemctl stop tuned
systemctl disable tuned
fi
if [ $ispm -eq 1 ];then
systemctl enable cpupower.service
systemctl restart cpupower.service
fi
yum install -y libaio wget telnet net-tools strace gdb lsof sysstat bc numactl grubby ntp traceroute s3cmd zstd jq
sudo systemctl stop firewalld.service
sudo systemctl disable firewalld.service
if [ $ispm -ne 2 ];then
if [ $ishdd -eq 1 ];then
#机械盘
#数据盘禁用atime
awk '$2=="'$datadir'"{$4="defaults,noatime"}1' /etc/fstab > tmp && mv tmp /etc/fstab -f
mount -o remount,noatime $datadir
#内核设置存储介质的 I/O 调度器
grubby --update-kernel=ALL --args="elevator=deadline"
else
#ssd
#数据盘禁用atime,discard for ssd del data
awk '$2=="'$datadir'"{$4="defaults,noatime,discard"}1' /etc/fstab > tmp && mv tmp /etc/fstab -f
mount -o remount,noatime,discard $datadir
grubby --update-kernel=ALL --args="elevator=noop"
fi
fi
#设置当前不限制输出corefile,打开文件数,用户打开线程数
ulimit -c unlimited
ulimit -n 1048576
ulimit -u 1024000
#设置不限制输出corefile,打开文件数,用户打开线程数永久生效
addcmd '* soft core unlimited' /etc/security/limits.conf
addcmd '* hard core unlimited' /etc/security/limits.conf
addcmd '* soft nofile 1048576' /etc/security/limits.conf
addcmd '* hard nofile 1048576' /etc/security/limits.conf
addcmd '* soft nproc 1024000' /etc/security/limits.conf
addcmd '* hard nproc 1024000' /etc/security/limits.conf
addcmd '* soft stack 32768' /etc/security/limits.conf
addcmd '* hard stack 32768' /etc/security/limits.conf
#修改当前的内核配置立即关闭透明大页
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
#内核关闭透明大页
grubby --args="transparent_hugepage=never" --update-kernel `grubby --default-kernel`
#设置操作系统预读扇区readahead(主要为了优化mongodb),/为数据盘目录,预读64个扇区为32k(网上资料说mongodb针对32k预读有优化,暂未从官方文档查实),对应随机读多的应用较小预读可以提升性能。
blockdev --setra 64 `df | grep -w $datadir | awk '{print $1}'`
cat > /etc/systemd/system.conf << EOF
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See systemd-system.conf(5) for details.
[Manager]
#LogLevel=info
#LogTarget=journal-or-kmsg
#LogColor=yes
#LogLocation=no
DumpCore=yes
#CrashShell=no
#ShowStatus=yes
#CrashChVT=1
#CtrlAltDelBurstAction=reboot-force
#CPUAffinity=1 2
#JoinControllers=cpu,cpuacct net_cls,net_prio
#RuntimeWatchdogSec=0
#ShutdownWatchdogSec=10min
#CapabilityBoundingSet=
#SystemCallArchitectures=
#TimerSlackNSec=
#DefaultTimerAccuracySec=1min
#DefaultStandardOutput=journal
#DefaultStandardError=inherit
#DefaultTimeoutStartSec=90s
#DefaultTimeoutStopSec=90s
#DefaultRestartSec=100ms
#DefaultStartLimitInterval=10s
#DefaultStartLimitBurst=5
#DefaultEnvironment=
#DefaultCPUAccounting=no
#DefaultBlockIOAccounting=no
#DefaultMemoryAccounting=no
#DefaultTasksAccounting=no
#DefaultTasksMax=
#DefaultLimitCPU=
#DefaultLimitFSIZE=
#DefaultLimitDATA=
#DefaultLimitSTACK=
#DefaultLimitCORE=
#DefaultLimitRSS=
DefaultLimitNOFILE=1048576
#DefaultLimitAS=
DefaultLimitNPROC=1024000
#DefaultLimitMEMLOCK=
#DefaultLimitLOCKS=
#DefaultLimitSIGPENDING=
#DefaultLimitMSGQUEUE=
#DefaultLimitNICE=
#DefaultLimitRTPRIO=
#DefaultLimitRTTIME=
EOF
systemctl daemon-reexec
cat > /etc/sysctl.conf << EOF
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
#表示内核允许分配所有的物理内存,而不管当前的内存状态如何
vm.overcommit_memory = 1
fs.file-max = 6553560
#关闭系统swap
vm.swappiness = 0
#服务端所能accept即处理数据的最大客户端数量,即完成连接上限,默认值是128
net.core.somaxconn=32768
#服务端所能接受SYN同步包的最大客户端数量,即半连接上限,默认值是128
net.core.netdev_max_backlog=16384
#处于SYN_RECV的TCP最大连接数,SYN_RECV状态的TCP连接数超过该值后丢弃后续的SYN报文
net.ipv4.tcp_max_syn_backlog=16384
#表示关闭SYN Cookies。避免不使用SYN半连接队列的情况下成功建立连接
net.ipv4.tcp_syncookies = 0
#为TCP socket预留用于接收缓冲的内存缺省值(以字节为单位)
net.core.rmem_default=262144
#为TCP socket预留用于发送缓冲的内存缺省值(以字节为单位)
net.core.wmem_default=262144
#为TCP socket预留用于接收缓冲的内存最大值
net.core.rmem_max=16777216
#为TCP socket预留用于发送缓冲的内存最大值
net.core.wmem_max=16777216
#表示每个套接字所允许的最大缓冲区的大小
net.core.optmem_max=16777216
#表示用于向外连接的端口范围.缺省情况下过窄:32768到61000,改为1024到65535
net.ipv4.ip_local_port_range=1024 65535
#自动调优所使用的接收缓冲区的值,最少字节数/默认值/最大字节数
net.ipv4.tcp_rmem=1024 4096 16777216
#自动调优所使用的发送缓冲区的值
net.ipv4.tcp_wmem=1024 4096 16777216
#不设0可能大量丢包
#net.ipv4.tcp_tw_recycle = 0
EOF
sysctl -p
swapoff -a
cluster_mongodb_mutil.py
python
#!/usr/bin/python
#! _*_ coding:utf-8 _*_
import os,re
import sys
import time
import random,string
import subprocess
passw='xxx'
account_verify = 1 # Cluster validation start ,0 关闭验证(Turn off validation) / 1开启验证(Enable verification)
#mongos IP, port:30000
iplist_so = '''
1x2.x1.2x8.160
1x2.x1.2x8.5
1x2.x1.2x8.35
'''
#config IP,port:27017
iplist_co = '''
1x2.x1.2x8.177
1x2.x1.2x8.139
1x2.x1.2x8.95
'''
#shard IP shard are separated by '|',port 40001-4000n
iplisto = '''
1x2.x1.2x8.186
1x2.x1.2x8.127
1x2.x1.2x8.151
|
1x2.x1.2x8.117
1x2.x1.2x8.181
1x2.x1.2x8.193
|
1x2.x1.2x8.197
1x2.x1.2x8.58
1x2.x1.2x8.178
'''
def ip_handle_shard(ip_list):#shard副本集的ip串处理函数
slist = []
slistz = []
for s in ip_list.split('|'):
slist.append(s.strip().replace("\n", " "))
slistz.append(slist)
slist = []
return slistz
def ip_handle_sc(ip_list):#mongos/config的ip串处理函数
slist = []
for s in ip_list.split('\n'):
slist.append(s.strip())
clean_iplist = [item for item in slist if item]
clean_iplist_clsp = ' '.join(clean_iplist)
iplist_ss = []
iplist_ss.append(clean_iplist_clsp)
return iplist_ss
iplist_s = ip_handle_sc(iplist_so)
iplist_c = ip_handle_sc(iplist_co)
iplist = ip_handle_shard(iplisto)
def main(argv): #外部程序调入逻辑,获取密码和ip地址串
if len(argv) < 2:
return argv
argument = argv[1]
ts = ' '
sip = ''
for shad_ip in iplist:
if shad_ip != iplist[-1]:
sip = sip + shad_ip[0] + ts
else:
sip = sip + shad_ip[0]
ipsc = iplist_s[0] + ' ' + iplist_c[0] + ' ' + sip
print('ips:'+ipsc+'|sshpassword:'+passw)
sys.exit(1)
if __name__ == "__main__":
main(sys.argv)
os.system('/usr/bin/which sshpass;if [[ "$?" != "0" ]];then yum -y install sshpass ;fi')
# update your ip search location
num = string.ascii_letters+string.digits
password = "".join(random.sample(num,12))
if os.path.exists('create_user.js'):
os.remove('create_user.js')
file = open('create_user.js', 'a')
file.write('db.createUser({user:"admin", pwd:"%s", roles:[{role:"userAdminAnyDatabase",db:"admin"}]});\n' %(password))
file.write('db.createUser({user: "root",pwd: "%s",roles:[{role: "root", db: "admin"}]});\n' %(password))
file.close()
#检实例安装结果函数
def function_psef(ip,passw):
# 执行命令
command = "sshpass -p\'%s\' ssh root@%s -o StrictHostKeyChecking=no 'netstat -tnlp|grep mongo'"%(passw,ip)
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# 等待命令执行完成
stdout, stderr = process.communicate()
# 检查命令是否执行成功
if process.returncode == 0:
return 'successful_install'
else:
return "failure_install"
#检副本集是否已经选举出 PRIMARY-函数
def function_primary(ip,passw,port):
command = 'sshpass -p\'%s\' ssh root@%s -o StrictHostKeyChecking=no "echo \'rs.status()\'|/usr/local/mongodb/bin/mongo %s:%s|grep PRIMARY"'%(passw,ip,ip,port)
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
if process.returncode == 0:
return 'PRIMARY'
else:
return 'SECONDARY'
os.system('openssl rand -base64 753 > keyFile;chmod 400 keyFile')
shardname='rsshd'
shards = 0
# extype部署类型 1.mongod 2.config 3.mongos
extype = 1
port = 40000
add_user_ip = []
for ips in iplist:
shards += 1
shardnamez = shardname+str(shards)
ip1=ips[0].split(' ')[0]
add_user_ip.append(ip1)
#1.1 副本集批量安装
#传送副本集IP组给脚本安装副本集
os.system("sh mongo_mutil.sh \'%s\' %s %s %s" %(ips[0],extype,passw,shards))
#判断副本集实例都安装成功
while True:
successfuls = []
for ip in ips[0].split(' '):
example_ps = function_psef(ip,passw)
successfuls.append(example_ps)
for n in range(60):
time.sleep(n)
if successfuls.count('successful_install') == len(ips[0].split()) and list(set(successfuls))[0] == 'successful_install':
pd = 'successful_install'
break
else:
pd = ''
if n == 30:#判断sharding副本集节点部署没有全部成功,退出脚本
print('安装副本集'+ips[0]+'失败!')
exit()
break
if pd == 'successful_install':
print('副本集 '+ips[0]+' 实例安装成功!')
break
#1.2. 副本集初始化命令拼接
rsinit_head = 'rs.initiate({\\"_id\\": \\"%s\\",\\"members\\" :[' %(shardnamez)
rsinit_tail = ']})'
port = port + 1
# 副本集IP拼接
st = ','
ipstr = ''
for i in range(len(ips[0].split(' '))):
print(i)
ip=ips[0].split(' ')[i]
print ip
if ip != ips[0].split(' ')[-1]:
ipst = '{\\"_id\\": %s,\\"host\\" : \\"%s:%s\\"}'%(i,ip,port)
ipstr = ipstr + ipst + st
elif ip == ips[0].split(' ')[-1]:
ipst = '{\\"_id\\": %s,\\"host\\" : \\"%s:%s\\"}'%(i,ip,port)
ipstr = ipstr + ipst
rsinit_coun = rsinit_head + ipstr + rsinit_tail
time.sleep(3)
# 1.3 副本集初始化操作
print('副本集 '+ips[0]+' 初始化开始......')
os.system('sshpass -p\'%s\' ssh root@%s -o StrictHostKeyChecking=no "echo \'%s\'|/usr/local/mongodb/bin/mongo %s:%s"' %(passw,ip1,rsinit_coun,ip1,port))
#判断shard的副本集是否产生主节点
while True:
primary_node = function_primary(ip1,passw,port)
for n in range(60):
time.sleep(n)
if primary_node == 'PRIMARY':
pd = 'PRIMARY'
# 获取副本集主节点IP地址
ip_str = os.popen('sshpass -p\'%s\' ssh root@%s -o StrictHostKeyChecking=no "echo \'rs.status()\'|/usr/local/mongodb/bin/mongo localhost:%s|grep -E \'name|stateStr\'|sed \'N;s/\\n//\'|grep PRIMARY"'%(passw,ip1,port)).read().strip().split(':')[1].replace('"','')
ipList = re.findall( r'[0-9]+(?:\.[0-9]+){3}',ip_str)[0]
os.system('sshpass -p %s scp %s root@%s:/root/' %(passw,'create_user.js',ipList))
#副本集主节点创建管理账号
os.system('sshpass -p\'%s\' ssh root@%s -o StrictHostKeyChecking=no "/usr/local/mongodb/bin/mongo %s:%s/admin < create_user.js"' %(passw,ipList,ipList,port))
break
else:
pd = ''
if n == 30:#判断副本集在30秒内没有选举出primary,退出脚本
print('安装sharding副本集'+ips[0]+'在30秒内没有选举出primary,退出脚本.')
exit()
break
if pd == 'PRIMARY':
break
#// 2、 config节点部署
extype = 2
# 2.1 config节点复制集部署
os.system("sh mongo_mutil.sh \'%s\' %s %s" %(iplist_c[0],extype,passw))
replSetName = "rscnf" #config复制集名
rsinit_head = 'rs.initiate({\\"_id\\": \\"%s\\",\\"members\\" :[' %(str(replSetName))
rsinit_tail = ']})'
ip1=iplist_c[0].split(' ')[0]
#检查config副本集实例安装结果
while True:
successfuls = []
for ip in iplist_c[0].split(' '):
example_ps = function_psef(ip,passw)
successfuls.append(example_ps)
for n in range(60):
time.sleep(n)
if successfuls.count('successful_install') == len(iplist_c[0].split()) and list(set(successfuls))[0] == 'successful_install':
print('config副本集'+iplist_c[0]+'实例部署成功!')
pd = 'successful_install'
break
else:
pd = ''
if n == 30:#判断副本集节点部署没有全部成功,退出脚本
print('安装config副本集'+iplist_c[0]+'失败!,退出脚本.')
exit()
break
if pd == 'successful_install':
print('副本集 '+iplist_c[0]+' 实例安装成功!')
break
# config副本集IP拼接
st = ','
ipstr = ''
ipstc = ''
portc = '27017'
for i in range(len(iplist_c[0].split(' '))):
print i
ip=iplist_c[0].split(' ')[i]
print ip
if ip != iplist_c[0].split(' ')[-1]:
ipst = '{\\"_id\\": %s,\\"host\\" : \\"%s:%s\\"}'%(i,ip,portc)
ipsc = ip + ':' + portc
ipstc = ipstc + ipsc + st
ipstr = ipstr + ipst + st
elif ip == iplist_c[0].split(' ')[-1]:
ipst = '{\\"_id\\": %s,\\"host\\" : \\"%s:%s\\"}'%(i,ip,portc)
ipsc = ip + ':' + portc
ipstc = ipstc + ipsc
ipstr = ipstr + ipst
rsinit_coun = rsinit_head + ipstr + rsinit_tail
# 2.2 config副本集初始化
os.system('sshpass -p \'%s\' ssh root@%s -o StrictHostKeyChecking=no "echo \'%s\'|/usr/local/mongodb/bin/mongo %s:%s"' %(passw,ip1,rsinit_coun,ip1,portc))
#判断config的副本集是否已产生主节点
while True:
primary_node = function_primary(ip,passw,portc)
for n in range(60):
time.sleep(n)
if primary_node == 'PRIMARY':
pd = 'PRIMARY'
break
else:
pd = ''
if n == 30:#判断config副本集在30秒内没有选举出primary,退出脚本
print('初始化config副本集'+iplist_c[0]+'在30秒内没有选举出primary,退出脚本.')
exit()
break
if pd == 'PRIMARY':
break
# 获取副本集主节点IP地址
ip_str = os.popen('sshpass -p\'%s\' ssh root@%s -o StrictHostKeyChecking=no "echo \'rs.status()\'|/usr/local/mongodb/bin/mongo %s:%s|grep -E \'name|stateStr\'|sed \'N;s/\\n//\'|grep PRIMARY"' %(passw,ip1,ip1,portc)).read().strip().split(':')[1].replace('"','')
ipList = re.findall( r'[0-9]+(?:\.[0-9]+){3}',ip_str)[0]
#副本集主节点创建管理账号
os.system('sshpass -p %s scp %s root@%s:/root/' %(passw,'create_user.js',ipList))
time.sleep(1)
os.system('sshpass -p\'%s\' ssh root@%s -o StrictHostKeyChecking=no "/usr/local/mongodb/bin/mongo %s:%s/admin < create_user.js"' %(passw,ipList,ipList,portc))
time.sleep(1)
#// 3、 mongos节点部署
extype = 3
cfdbs = ' configDB: '+replSetName+'/'+ipstc
print('开始部署mongos......')
os.system('sed -i "s|`grep configDB mongos_install.sh`|%s|g" mongos_install.sh'%(cfdbs))
#// 3.1 安装mongos节点
os.system("sh mongo_mutil.sh \'%s\' %s %s" %(iplist_s[0],extype,passw))
while True:
successfuls = []
for ip in ips[0].split(' '):
example_ps = function_psef(ip,passw)
successfuls.append(example_ps)
for n in range(60):
print(n)
time.sleep(n)
if successfuls.count('successful_install') == 3 and list(set(successfuls))[0] == 'successful_install':
print('mongos实例节点部署成功!')
pd = 'successful_install'
break
else:
pd = ''
if n == 30:#判断安装mongos在30秒内没有选举出primary,退出脚本
print('安装mongos'+iplist_s[0]+'失败!,退出脚本.')
exit()
break
if pd == 'successful_install':
print('mongos '+iplist_s[0]+' 实例安装成功!')
break
time.sleep(3)
shardn = 0
port = 40000
# 3.2 添加集群分片
for ips in iplist:
shardn += 1
port = port + 1
addshard_head = 'sh.addShard(\\"'
# 添加分片的副本集ip串拼接
ipsts = ''
st= ','
for i in range(len(ips[0].split(' '))):
print(i)
ip=ips[0].split(' ')[i]
print ip
if ip != ips[0].split(' ')[-1]:
ipss = ip+':'+str(port)
ipsts = ipsts + ipss + st
elif ip == ips[0].split(' ')[-1]:
ipss = ip+':'+str(port)
ipsts = ipsts + ipss
addshard = shardname+str(shardn)+'/'+ipsts
addshard_tail = '\\")'
addshardc = addshard_head + addshard + addshard_tail
shows = 'sh.status()'
os.system('sshpass -p \'%s\' ssh root@%s -o StrictHostKeyChecking=no "echo \'%s\'|/usr/local/mongodb/bin/mongo localhost:30000"' %(passw,iplist_s[0].split(' ')[0],addshardc))
time.sleep(3)
#将密码写入日志中,方便后续查看
file = open('/data/mongodb/logs/mongo_route.log','a')
file.write('%s mongodb_password: %s \n' %(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()),password))
file.close()
#把mognodb集群信息记录到集群config库的mongodb_configs集合中
os.system("echo 'db.mongodb_configs.insert({\"mongos_30000\" : \"%s\",\"config_%s\" : \"%s\",\"shards_40001-%s\":\"%s\"})'|/usr/local/mongodb/bin/mongo localhost:30000/config" %(iplist_s,portc,iplist_c,port,iplist))
# 获取IP
mongos = os.popen("echo 'db.mongodb_configs.find({},{\"mongos_30000\":1, \"_id\":0})'|/usr/local/mongodb/bin/mongo localhost:30000/config|grep mongos_30000|grep -Po '(?<=\[).*?(?=\])'|tail -n1").read().strip()
config = os.popen("echo 'db.mongodb_configs.find({},{\"config_27017\":1, \"_id\":0})'|/usr/local/mongodb/bin/mongo localhost:30000/config|grep config_27017|grep -Po '(?<=\[).*?(?=\])'|tail -n1").read().strip()
shards = os.popen("echo 'db.mongodb_configs.find({},{\"shards_40001-%s\":1, \"_id\":0})'|/usr/local/mongodb/bin/mongo localhost:30000/config|grep shards_40001|grep -Po '(?<=\"\[).*?(?=\]\")'|grep -Po '(?<=\[).*?(?=\])'" %(port)).read().strip().replace("\n", " ")
all_ip = mongos + ' ' + config + ' ' + shards
print all_ip
# Closing remarks
n = 1
for i in range(20,14,-1):
print(' '*i+'*'*n)
n = n + 2
n = 11
for i in range(15,19):
print(' '*i+'*'*n)
n = n - 2
for i in range(3):
print(' '*19+'*'*1+' '+'*'*1)
print(' '*20+'*'*1)
s = "[ MongoDB ]"
x = '★★★'
print('\033[1;33;40m%s\033[0m''分片集群已经部署完成''\033[1;34;40m%s\033[0m''~ 集群重启中~' %(s,x))
print('MongoDB集群密码在日志里-_- mongodb_password')
if account_verify == 1:
os.system("sh cluster_add_security_key.sh \'%s\' \'%s\' \'%s\' \'%s\' %s " %(mongos,config,shards,all_ip,passw))
elif account_verify == 0:
exit()
mongo_mutil.sh
powershell
#!/bin/bash
#shardid=1
vers='4.4.18'
dataroot='/data'
passw=$3
function install_shard(){
IFS='|' read -ra elements <<< "$1"
for ip in "${elements[@]}"; do
{
ipp=$(ping `hostname` -c 1|grep PING|grep -Po '(?<=\().*?(?=\))'|grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}"|head -n 1)
if [ "$ipp" == "$ip" ];then
sh mongodb_install.sh $2 $3 $4
elif [ "$ipp" != "$ip" ];then
shardnamen='rsshd'$4
shardnamey=$(grep replSetName mongodb_install.sh|cut -d':' -f2|grep -Po '(?<=\").*?(?=\")'|tail -n1)
sed -i "s|$shardnamey|$shardnamen|g" mongodb_install.sh
sshpass -p $5 ssh root@${ip} -o StrictHostKeyChecking=no "if [ ! -d $2 ];then mkdir $2;fi"
sshpass -p $5 scp mongodb_install.sh mongodb-linux-x86_64-rhel70-$3.tgz root@${ip}:$2
echo '副本集节点传入shards '$4
sshpass -p $5 ssh root@${ip} -o StrictHostKeyChecking=no "cd $2;sh mongodb_install.sh $2 $3 $4"
fi
echo 'install mongod ......'
} &
done
wait
}
function install_config(){
IFS='|' read -ra elements <<< "$1"
for ip in "${elements[@]}"; do
{
ipp=$(ping `hostname` -c 1|grep PING|grep -Po '(?<=\().*?(?=\))'|grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}"|head -n 1)
if [ "$ipp" == "$ip" ];then
sh config_install.sh $2 $3
elif [ "$ipp" != "$ip" ];then
sshpass -p $4 ssh root@${ip} -o StrictHostKeyChecking=no "if [ ! -d $2 ];then mkdir $2;fi"
sshpass -p $4 scp config_install.sh mongodb-linux-x86_64-rhel70-$3.tgz root@${ip}:$2
sshpass -p $4 ssh root@${ip} -o StrictHostKeyChecking=no "cd $2;sh config_install.sh $2 $3"
fi
echo 'install config ......'
} &
done
wait
}
function install_mongos(){
IFS='|' read -ra elements <<< "$1"
for ip in "${elements[@]}"; do
{
ipp=$(ping `hostname` -c 1|grep PING|grep -Po '(?<=\().*?(?=\))'|grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}"|head -n 1)
if [ "$ipp" == "$ip" ];then
sh mongos_install.sh $2 $3
elif [ "$ipp" != "$ip" ];then
sshpass -p $4 ssh root@${ip} -o StrictHostKeyChecking=no "if [ ! -d $2 ];then mkdir $2;fi"
sshpass -p $4 scp mongos_install.sh mongodb-linux-x86_64-rhel70-${vers}.tgz root@${ip}:$2
sshpass -p $4 ssh root@${ip} -o StrictHostKeyChecking=no "cd $2;sh mongos_install.sh $2 $3"
fi
echo 'install mongos ......'
} &
done
wait
}
if [ "$2" == 1 ];then # mongod
ips=`echo $1|sed 's/ /|/g'`
rss=$4
install_shard $ips ${dataroot} ${vers} ${rss} ${passw}
elif [ "$2" == 2 ];then # config
ips=`echo $1|sed 's/ /|/g'`
install_config $ips ${dataroot} ${vers} ${passw}
elif [ "$2" == 3 ];then # mongos
ips=`echo $1|sed 's/ /|/g'`
install_mongos $ips ${dataroot} ${vers} ${passw}
fi
mongodb_install.sh
powershell
#!/bin/bash
# /data/mongodb /{data,logs,conf}
dataroot=$1
ver=$2
shardid=$3
setip='0.0.0.0'
if [ $# -ne 3 ];then
echo "Error: please use $0 dataroot ver shardid"
exit 1
fi
addcmd(){
addText=$1
file=$2
#判断 file.sh 文件中是否存在该字符串 # Check whether the character string exists in the file.sh file
if ! grep "$addText" $file >/dev/null
then
#不存在,添加字符串 # Does not exist, add a string
echo $addText >> $file
else
#存在,不做处理
echo $addText" exist in "$file
fi
}
#wget mongodb-linux-x86_64-rhel70-4.4.18.tgz
tar xzvf mongodb-linux-x86_64-rhel70-$ver.tgz -C /opt
ln -snf /opt/mongodb-linux-x86_64-rhel70-$ver /usr/local/mongodb
basedir='/usr/local/mongodb'
datadir=$dataroot'/mongodb/data'
logdir=$dataroot'/mongodb/logs'
# rm $datadir/* -rf
mkdir -p $logdir
mkdir ${dataroot}/mongodb/conf
addcmd 'export PATH=$PATH:/usr/local/mongodb/bin' ~/.bash_profile
source ~/.bash_profile
groupadd mongodb
useradd -g mongodb mongodb
cat > /usr/lib/systemd/system/mongod_multiple_mongod@.service << EOF
[Unit]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network-online.target
Wants=network-online.target
[Service]
User=mongodb
Group=mongodb
#EnvironmentFile=-$basedir/etc/default/mongod
ExecStart=$basedir/bin/mongod --config ${dataroot}/mongodb/conf/mongo_shard%i.yml
ExecStop=$basedir/bin/mongod --config ${dataroot}/mongodb/conf/mongo_shard%i.yml --shutdown
PIDFile=$datadir/%i/mongo_%i.pid
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for mongod as specified in
# https://docs.mongodb.com/manual/reference/ulimit/#recommended-ulimit-settings
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
i=$shardid
#for ((i=1; i<=j; i++))
#do
mkdir -p $datadir/shard$i
if [ ! -f $basedir/conf/mongo_shard$i.yml ]; then
touch ${dataroot}/mongodb/conf/mongo_shard$i.yml
fi
port=`expr $i + 40000`
cat > ${dataroot}/mongodb/conf/mongo_shard$i.yml << EOF
systemLog:
destination: file
path: "$logdir/mongo_shard$i.log"
logAppend: true
logRotate: rename
storage:
journal:
enabled: true
commitIntervalMs: 162
dbPath: "$datadir/shard$i"
syncPeriodSecs: 67
engine: wiredTiger
wiredTiger:
engineConfig:
cacheSizeGB: 6
processManagement:
fork: false
net:
bindIp: $setip
#注意修改端口 # Notice Modifying the port
port: $port
setParameter:
enableLocalhostAuthBypass: true
replication:
#复制集名称 # Replication set name
replSetName: "rsshd3"
oplogSizeMB: 24576
sharding:
#作为分片服务 # As a shard service
clusterRole: shardsvr
#security:
# keyFile: "/data/mongodb/conf/keyFile"
# authorization: enabled
EOF
sed -i "s|`grep cacheSizeGB ${dataroot}/mongodb/conf/mongo_shard$i.yml|sed 's/^[ \t]*//g'`|cacheSizeGB: "$(echo `free -m|grep Mem|awk -F' ' '{print $4}'`*0.85/1000|bc|cut -d'.' -f1)"|g" ${dataroot}/mongodb/conf/mongo_shard$i.yml
chown -R mongodb:mongodb $dataroot/mongodb
chown -R mongodb:mongodb $basedir
cd $basedir
rpath=`pwd -P`
chown -R mongodb:mongodb $rpath
systemctl restart mongod_multiple_mongod@$i.service
systemctl enable mongod_multiple_mongod@$i.service
#done
config_install.sh
powershell
#!/bin/bash
# config install
# /data/mongodb /{data,logs,conf}
dataroot=$1
ver=$2
setip='0.0.0.0'
addcmd(){
addText=$1
file=$2
#判断 file.sh 文件中是否存在该字符串
#Check whether the character string exists in the file.sh file
if ! grep "$addText" $file >/dev/null
then
#不存在,添加字符串
# Does not exist, add a string
echo $addText >> $file
else
#存在,不做处理
#Exist, do not process
echo $addText" exist in "$file
fi
}
#wget mongodb-linux-x86_64-rhel70-4.4.18.tgz
tar xzvf mongodb-linux-x86_64-rhel70-$ver.tgz -C /opt
ln -snf /opt/mongodb-linux-x86_64-rhel70-$ver /usr/local/mongodb
basedir='/usr/local/mongodb'
datadir=$dataroot'/mongodb'
logdir=$dataroot'/mongodb/logs'
# rm $datadir/* -rf
mkdir -p $logdir
#mkdir -p ${dataroot}/mongodb/config
mkdir ${dataroot}/mongodb/{conf,config}
addcmd 'export PATH=$PATH:/usr/local/mongodb/bin' ~/.bash_profile
source ~/.bash_profile
groupadd mongodb
useradd -g mongodb mongodb
cat > /usr/lib/systemd/system/mongod_multiple_config@.service << EOF
[Unit]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network-online.target
Wants=network-online.target
[Service]
User=mongodb
Group=mongodb
#EnvironmentFile=-$basedir/etc/default/mongod
ExecStart=$basedir/bin/mongod --config ${dataroot}/mongodb/conf/mongo_config.yml
ExecStop=$basedir/bin/mongod --config ${dataroot}/mongodb/conf/mongo_config.yml --shutdown
PIDFile=$datadir/%i/mongo_%i.pid
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for mongod as specified in
# https://docs.mongodb.com/manual/reference/ulimit/#recommended-ulimit-settings
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
if [ ! -f $basedir/conf/mongo_config.yml ]; then
touch ${dataroot}/mongodb/conf/mongo_config.yml
fi
cat > ${dataroot}/mongodb/conf/mongo_config.yml << EOF
systemLog:
destination: file
#注意修改路径
#Note the modification path
path: "$logdir/mongo_config.log"
logAppend: true
storage:
journal:
enabled: true
#注意修改路径
#Note the modification path
dbPath: "$datadir/config"
engine: wiredTiger
wiredTiger:
engineConfig:
cacheSizeGB: 1
processManagement:
fork: false
net:
bindIp: 0.0.0.0
#注意修改端口
#Notice Modifying the port
port: 27017
setParameter:
enableLocalhostAuthBypass: true
replication:
#复制集名称
#Replication set name
replSetName: "rscnf"
sharding:
#作为配置服务
#As configuration service
clusterRole: configsvr
#security:
# keyFile: "/data/mongodb/conf/keyFile"
# authorization: enabled
EOF
sed -i "s|`grep cacheSizeGB ${dataroot}/mongodb/conf/mongo_config.yml|sed 's/^[ \t]*//g'`|cacheSizeGB: "$(echo `free -m|grep Mem|awk -F' ' '{print $4}'`*0.85/1000|bc|cut -d'.' -f1)"|g" ${dataroot}/mongodb/conf/mongo_config.yml
chown -R mongodb:mongodb $dataroot/mongodb
chown -R mongodb:mongodb $basedir
cd $basedir
rpath=`pwd -P`
chown -R mongodb:mongodb $rpath
systemctl restart mongod_multiple_config@1.service
systemctl enable mongod_multiple_config@1.service
mongos_install.sh
powershell
#!/bin/bash
# config install
# /data/mongodb /{data,logs,conf}
dataroot=$1
ver=$2
setip='0.0.0.0'
addcmd(){
addText=$1
file=$2
#判断 file.sh 文件中是否存在该字符串 # Check whether the character string exists in the file.sh file
if ! grep "$addText" $file >/dev/null
then
#不存在,添加字符串 # Does not exist, add a string
echo $addText >> $file
else
#存在,不做处理 # Exist, do not process
echo $addText" exist in "$file
fi
}
#wget mongodb-linux-x86_64-rhel70-4.4.18.tgz
tar xzvf mongodb-linux-x86_64-rhel70-$ver.tgz -C /opt
ln -snf /opt/mongodb-linux-x86_64-rhel70-$ver /usr/local/mongodb
basedir='/usr/local/mongodb'
datadir=$dataroot'/mongodb'
logdir=$dataroot'/mongodb/logs'
# rm $datadir/* -rf
mkdir -p $logdir
#mkdir -p ${dataroot}/mongodb/config
mkdir ${dataroot}/mongodb/conf
addcmd 'export PATH=$PATH:/usr/local/mongodb/bin' ~/.bash_profile
source ~/.bash_profile
groupadd mongodb
useradd -g mongodb mongodb
cat > /usr/lib/systemd/system/mongod_multiple_mongos@.service << EOF
[Unit]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network-online.target
Wants=network-online.target
[Service]
User=mongodb
Group=mongodb
#EnvironmentFile=-$basedir/etc/default/mongod
ExecStart=$basedir/bin/mongos --config ${dataroot}/mongodb/conf/mongo_route.yml
ExecStop=$basedir/bin/mongos --config ${dataroot}/mongodb/conf/mongo_route.yml --shutdown
PIDFile=$datadir/%i/mongo_%i.pid
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for mongod as specified in
# https://docs.mongodb.com/manual/reference/ulimit/#recommended-ulimit-settings
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
if [ ! -f $basedir/conf/mongo_route.yml ]; then
touch ${dataroot}/mongodb/conf/mongo_route.yml
fi
cat > ${dataroot}/mongodb/conf/mongo_route.yml << EOF
systemLog:
destination: file
# 注意修改路径 # Note the modification path
path: "/data/mongodb/logs/mongo_route.log"
logAppend: true
processManagement:
fork: false
net:
bindIp: 0.0.0.0
# 注意修改端口 # Notice Modifying the port
port: 30000
setParameter:
enableLocalhostAuthBypass: true
replication:
localPingThresholdMs: 15
sharding:
# 关联配置服务 # Associated configuration service
configDB: rscnf/1x2.x1.2x8.177:27017,1x2.x1.2x8.139:27017,1x2.x1.2x8.95:27017
#security:
# keyFile: "/data/mongodb/conf/keyFile"
EOF
cat > /root/.mongorc.js << EOF
//host=db.serverStatus().host;
host=\``hostname`\`
cmdCount=1;
prompt=function(){
return db+"@"+host+" "+(cmdCount++) +">";
}
function showDate(){
var today = new Date();
var year = today.getFullYear() + "年";
var month = (today.getMonth() +1) + "月";
var date = today.getDate() + "日";
var week = '星期' + today.getDay();
var quarter = "一年中的第" + Math.floor((today.getMonth() +3) / 3) + "个季度";
var text = "[ 欢迎回来,今天是" + year + month + date + week +"," + quarter + "。]";
print(text);
}
showDate();
EOF
chown -R mongodb:mongodb $dataroot/mongodb
chown -R mongodb:mongodb $basedir
cd $basedir
rpath=`pwd -P`
chown -R mongodb:mongodb $rpath
systemctl restart mongod_multiple_mongos@1.service
systemctl enable mongod_multiple_mongos@1.service
部署效果:
本文章为原创,github地址 https://github.com/gg2038/mongo-sharding-install