mongo4.4.17副本集半自动化实现

52 阅读5分钟

一、简介




二、准备与规划

1个primary, 2个secondary

图片.png




三、工具

primary节点的安装

vim deploy_mongodb-1.0.sh

#!/bin/bash

## 以下参数需要根据实际情况调整
mongoDBPort=$1
mongoDBBaseDir=/data/mongodb/$mongoDBPort
mongoDBReplsetName=$2
#mongoDBFilekey=$3
mongoDBOSGroup=mongodb
mongoDBOSUser=mongodb
mongoDBPackageDir=/data
mongoDBPackage="mongodb-linux-x86_64-rhel70-4.4.17.tgz"
mongoDBPackageMD5="4407189e0db16104a37114254cd30ba8"

CheckPackageExists(){
  echo "检查MongoDB软件包是否存在"
  if [ -e "$mongoDBPackageDir" ]
  then
    if [ ! -f $mongoDBPackageDir/$mongoDBPackage ]
    then
    echo "MongoDB安装包不存在"
    exit 1
    elif [ `md5sum $mongoDBPackageDir/$mongoDBPackage|awk '{print $1}'` == ${mongoDBPackageMD5} ]
    then
        echo "MongoDB安装介质完整性校验通过"
    else
        echo "MongoDB安装包校验失败,请检查安装介质是否损坏"
        exit
    fi
  else
    echo "MongoDB安装介质目录不存在"
    exit 1
  fi 
}

OptimizeMongodbRuntimeEnvironment(){
    echo "安装操作系统依赖包及MongoDB运行用户/组"
    yum -y install logrotate unzip sysstat net-snmp

    echo "关闭系统透明大页功能"
    echo 'never' >/sys/kernel/mm/transparent_hugepage/enabled 
    echo 'never' >/sys/kernel/mm/transparent_hugepage/defrag
    
    mkdir /etc/tuned/no-thp
    cat > /etc/tuned/no-thp/tuned.conf <<EOF
[main]
include=virtual-guest
[vm]
transparent_hugepages=never
EOF
    tuned-adm profile no-thp

    cat >> /etc/rc.d/rc.local << EOF
echo 'never' > /sys/kernel/mm/transparent_hugepage/enabled
echo 'never' > /sys/kernel/mm/transparent_hugepage/defrag
EOF
    
    echo "配置用户ulimit资源限制"
    cat > /etc/security/limits.d/mongodb.conf <<EOF 
mongodb soft nofile 65535 
mongodb hard nofile 65535 
mongodb soft nproc 65535 
mongodb hard nproc 65535 
mongodb soft memlock unlimited 
mongodb hard memlock unlimited 
EOF
    
    echo "swap分区权重配置"
    sysctl vm.swappiness=1
    echo "vm.swappiness = 1" >>/etc/sysctl.conf
}

CreateMongodbUserAndDir(){
    echo "创建MongoDB运行的用户和用户组"
    ## Create MongoDB User Group
    egrep "^$mongoDBOSGroup" /etc/group >& /dev/null
    if [ $? -ne 0 ]
    then
        echo "创建mongodb用户组"
        groupadd $mongoDBOSGroup
    else
        echo "mongodb组已存在"
    fi

    ## Create MongoDB User
    egrep "^$mongoDBOSUser" /etc/passwd >& /dev/null
    if [ $? -ne 0 ]
    then
        echo "创建mongodb用户"
        useradd -r -g $mongoDBOSGroup -s /bin/false $mongoDBOSUser
    else 
        echo "mongodb用户已存在"
        id mongodb
    fi

    echo "创建MongoDB软件安装目录"
    mkdir -p ${mongoDBBaseDir}

    echo "创建MongoDB数据/日志/备份/配置等目录"
    mkdir -p ${mongoDBBaseDir}/{data,conf,log,backup,bin}
}

UnPackMongodbAndChangeOwner(){
    echo "安装MongoDB软件包,请稍后..."
    mkdir -p ${mongoDBPackageDir}/tmp
    tar xzf ${mongoDBPackageDir}/${mongoDBPackage} --strip-components=1 -C ${mongoDBPackageDir}/tmp
    mv ${mongoDBPackageDir}/tmp/bin/* ${mongoDBBaseDir}/bin
    rm -rf ${mongoDBPackageDir}/tmp

    echo "安装完成至${mongoDBBaseDir}/bin目录"
}

SetPathEnvironmentVariable(){
    echo "配置MySQL环境变量"
    cat >> /etc/profile <<EOF
export MONGODB_HOME=${mongoDBBaseDir}
export PATH=$MONGODB_HOME/bin:$PATH 
EOF

source /etc/profile
}

GenerateMongodbConfAndKeyfile(){
    echo "生成MongoDB配置文件"
cat > ${mongoDBBaseDir}/conf/mongod.conf << EOF 
systemLog:
    destination: file
    path: "${mongoDBBaseDir}/log/mongod.log"
    logAppend: true
    logRotate: rename
    timeStampFormat: ctime
storage:
    dbPath: "${mongoDBBaseDir}/data"
    directoryPerDB: true
    journal:
        enabled: true
        commitIntervalMs: 100
    wiredTiger:
        engineConfig:
            cacheSizeGB: 1
operationProfiling:
    slowOpThresholdMs: 200
    mode: slowOp
    slowOpSampleRate: 100
processManagement:
    fork: true
    pidFilePath: "${mongoDBBaseDir}/mongod.pid"
net:
    port: ${mongoDBPort}
    bindIpAll: true
replication:
   oplogSizeMB: 25000
   replSetName: ${mongoDBReplsetName}
   enableMajorityReadConcern: true
security:
    authorization: enabled
    keyFile: "${mongoDBBaseDir}/conf/keyfile"
EOF

    echo "生成keyfile"
cd ${mongoDBBaseDir}/conf
echo $mongoDBReplsetName |openssl md5|awk -F ' ' '{print $2}' >keyfile
chmod 400 keyfile
}

MongodbLogRotateConfig(){
    echo "配置MongoDB日志轮转策略"
cat >/etc/logrotate.d/mongod.${mongoDBPort} <<EOF
${mongoDBBaseDir}/log/mongod.log
{
    weekly
    rotate 10
    olddir ${mongoDBBaseDir}/log/
    missingok
    dateext
    minsize 104857600
    copytruncate
    notifempty
    compress
    create 0644 mongodb mongodb
}
EOF
}

EnsureMongodbDirPermissions(){
    chown -R mongodb:mongodb ${mongoDBBaseDir}
}

MongodbStartScriptConfig(){
    echo "创建MongoDB启动脚本"
cat > /etc/systemd/system/mongod_${mongoDBPort}.service <<EOF
[Unit] 
Description=MongoDB Database Server 
Documentation=https://docs.mongodb.com/ 
After=network.target 
After=syslog.target 
[Service] 
## MongoDB运行的用户和组,根据实际情况调整 
LimitFSIZE=infinity
LimitCPU=infinity
LimitAS=infinity
LimitMEMLOCK=infinity
LimitNOFILE=64000
LimitNPROC=64000

User=${mongoDBOSUser}
Group=${mongoDBOSGroup}
Type=forking 
## MongoDB运行的pid文件路径 
PIDFile=${mongoDBBaseDir}/mongod.pid 
TimeoutSec=0 
## 启动命令,根据实际情况调整 
ExecStart=${mongoDBBaseDir}/bin/mongod --config ${mongoDBBaseDir}/conf/mongod.conf 
## 保持默认即可,自动识别pid 
ExecReload=/bin/kill -s HUP $MAINPID 
## 关闭脚本,根据实际情况调整 
ExecStop=${mongoDBBaseDir}/bin/mongod --config ${mongoDBBaseDir}/conf/mongod.conf --shutdown 
# 守护,意外的停止会被重启 
Restart=on-failure 
#设置安全退出码,不会被自动重启 
RestartPreventExitStatus=1 
[Install] 
WantedBy=multi-user.target
EOF
    echo "加载MongoDB启动脚本"
    systemctl daemon-reload

    sed -i 's/ctime/iso8601-local/g' /data/mongodb/27017/conf/mongod.conf
    #echo "overwirte filekey value"
    #echo $mongoDBFilekey > /data/mongodb/27017/conf/keyfile

    echo "启动MongoDB"
    systemctl start mongod_${mongoDBPort}

    echo "查看MongoDB状态"
    systemctl status mongod_${mongoDBPort}
}

PrintMongodbInstallInformation(){
    echo ""
    echo "MongoDB 软件安装目录  : $mongoDBBaseDir"
    echo "MongoDB 数据存放目录  : $mongoDBBaseDir/data"
    echo "MongoDB 备份存放目录  : $mongoDBBaseDir/backup"
    echo "MongoDB 日志存放目录  : $mongoDBBaseDir/log"
    echo "MongoDB 运行用户     : $mongoDBOSUser"
    echo "MongoDB 运行端口     : $mongoDBPort"
    echo "MongoDB Version     : $mongoDBPackage"
    echo "MongoDB 副本集名称    : $mongoDBReplsetName"
    echo "============> 你可以使用 $mongoDBBaseDir/bin/mongo localhost:${mongoDBPort} 登录数据库执行创建用户和副本集初始化等操作"
}

if [ $# -lt 1 ];then
    echo ''
    echo -e "\033[31mUsage: sh $0 MongoDB_Port \033[0m"
    echo ''
    echo -e "\033[32mSample: sh $0 30000 \033[0m"
    echo ''
    exit
fi

Main(){
    CheckPackageExists
    OptimizeMongodbRuntimeEnvironment
    CreateMongodbUserAndDir
    UnPackMongodbAndChangeOwner
    SetPathEnvironmentVariable
    GenerateMongodbConfAndKeyfile
    EnsureMongodbDirPermissions
    MongodbLogRotateConfig
    MongodbStartScriptConfig
    PrintMongodbInstallInformation
}
Main

secondary节点的安装

vim deploy_mongodb_with_filekey-1.0.sh

#!/bin/bash

## 以下参数需要根据实际情况调整
mongoDBPort=$1
mongoDBBaseDir=/data/mongodb/$mongoDBPort
mongoDBReplsetName=$2
mongoDBFilekey=$3
mongoDBOSGroup=mongodb
mongoDBOSUser=mongodb
mongoDBPackageDir=/data
mongoDBPackage="mongodb-linux-x86_64-rhel70-4.4.17.tgz"
mongoDBPackageMD5="4407189e0db16104a37114254cd30ba8"

CheckPackageExists(){
  echo "检查MongoDB软件包是否存在"
  if [ -e "$mongoDBPackageDir" ]
  then
    if [ ! -f $mongoDBPackageDir/$mongoDBPackage ]
    then
    echo "MongoDB安装包不存在"
    exit 1
    elif [ `md5sum $mongoDBPackageDir/$mongoDBPackage|awk '{print $1}'` == ${mongoDBPackageMD5} ]
    then
        echo "MongoDB安装介质完整性校验通过"
    else
        echo "MongoDB安装包校验失败,请检查安装介质是否损坏"
        exit
    fi
  else
    echo "MongoDB安装介质目录不存在"
    exit 1
  fi 
}

OptimizeMongodbRuntimeEnvironment(){
    echo "安装操作系统依赖包及MongoDB运行用户/组"
    yum -y install logrotate unzip sysstat net-snmp

    echo "关闭系统透明大页功能"
    echo 'never' >/sys/kernel/mm/transparent_hugepage/enabled 
    echo 'never' >/sys/kernel/mm/transparent_hugepage/defrag
    
    mkdir /etc/tuned/no-thp
    cat > /etc/tuned/no-thp/tuned.conf <<EOF
[main]
include=virtual-guest
[vm]
transparent_hugepages=never
EOF
    tuned-adm profile no-thp

    cat >> /etc/rc.d/rc.local << EOF
echo 'never' > /sys/kernel/mm/transparent_hugepage/enabled
echo 'never' > /sys/kernel/mm/transparent_hugepage/defrag
EOF
    
    echo "配置用户ulimit资源限制"
    cat > /etc/security/limits.d/mongodb.conf <<EOF 
mongodb soft nofile 65535 
mongodb hard nofile 65535 
mongodb soft nproc 65535 
mongodb hard nproc 65535 
mongodb soft memlock unlimited 
mongodb hard memlock unlimited 
EOF
    
    echo "swap分区权重配置"
    sysctl vm.swappiness=1
    echo "vm.swappiness = 1" >>/etc/sysctl.conf
}

CreateMongodbUserAndDir(){
    echo "创建MongoDB运行的用户和用户组"
    ## Create MongoDB User Group
    egrep "^$mongoDBOSGroup" /etc/group >& /dev/null
    if [ $? -ne 0 ]
    then
        echo "创建mongodb用户组"
        groupadd $mongoDBOSGroup
    else
        echo "mongodb组已存在"
    fi

    ## Create MongoDB User
    egrep "^$mongoDBOSUser" /etc/passwd >& /dev/null
    if [ $? -ne 0 ]
    then
        echo "创建mongodb用户"
        useradd -r -g $mongoDBOSGroup -s /bin/false $mongoDBOSUser
    else 
        echo "mongodb用户已存在"
        id mongodb
    fi

    echo "创建MongoDB软件安装目录"
    mkdir -p ${mongoDBBaseDir}

    echo "创建MongoDB数据/日志/备份/配置等目录"
    mkdir -p ${mongoDBBaseDir}/{data,conf,log,backup,bin}
}

UnPackMongodbAndChangeOwner(){
    echo "安装MongoDB软件包,请稍后..."
    mkdir -p ${mongoDBPackageDir}/tmp
    tar xzf ${mongoDBPackageDir}/${mongoDBPackage} --strip-components=1 -C ${mongoDBPackageDir}/tmp
    mv ${mongoDBPackageDir}/tmp/bin/* ${mongoDBBaseDir}/bin
    rm -rf ${mongoDBPackageDir}/tmp

    echo "安装完成至${mongoDBBaseDir}/bin目录"
}

SetPathEnvironmentVariable(){
    echo "配置MySQL环境变量"
    cat >> /etc/profile <<EOF
export MONGODB_HOME=${mongoDBBaseDir}
export PATH=$MONGODB_HOME/bin:$PATH 
EOF

source /etc/profile
}

GenerateMongodbConfAndKeyfile(){
    echo "生成MongoDB配置文件"
cat > ${mongoDBBaseDir}/conf/mongod.conf << EOF 
systemLog:
    destination: file
    path: "${mongoDBBaseDir}/log/mongod.log"
    logAppend: true
    logRotate: rename
    timeStampFormat: ctime
storage:
    dbPath: "${mongoDBBaseDir}/data"
    directoryPerDB: true
    journal:
        enabled: true
        commitIntervalMs: 100
    wiredTiger:
        engineConfig:
            cacheSizeGB: 1
operationProfiling:
    slowOpThresholdMs: 200
    mode: slowOp
    slowOpSampleRate: 100
processManagement:
    fork: true
    pidFilePath: "${mongoDBBaseDir}/mongod.pid"
net:
    port: ${mongoDBPort}
    bindIpAll: true
replication:
   oplogSizeMB: 25000
   replSetName: ${mongoDBReplsetName}
   enableMajorityReadConcern: true
security:
    authorization: enabled
    keyFile: "${mongoDBBaseDir}/conf/keyfile"
EOF

    echo "生成keyfile"
cd ${mongoDBBaseDir}/conf
echo $mongoDBReplsetName |openssl md5|awk -F ' ' '{print $2}' >keyfile
chmod 400 keyfile
}

MongodbLogRotateConfig(){
    echo "配置MongoDB日志轮转策略"
cat >/etc/logrotate.d/mongod.${mongoDBPort} <<EOF
${mongoDBBaseDir}/log/mongod.log
{
    weekly
    rotate 10
    olddir ${mongoDBBaseDir}/log/
    missingok
    dateext
    minsize 104857600
    copytruncate
    notifempty
    compress
    create 0644 mongodb mongodb
}
EOF
}

EnsureMongodbDirPermissions(){
    chown -R mongodb:mongodb ${mongoDBBaseDir}
}

MongodbStartScriptConfig(){
    echo "创建MongoDB启动脚本"
cat > /etc/systemd/system/mongod_${mongoDBPort}.service <<EOF
[Unit] 
Description=MongoDB Database Server 
Documentation=https://docs.mongodb.com/ 
After=network.target 
After=syslog.target 
[Service] 
## MongoDB运行的用户和组,根据实际情况调整 
LimitFSIZE=infinity
LimitCPU=infinity
LimitAS=infinity
LimitMEMLOCK=infinity
LimitNOFILE=64000
LimitNPROC=64000

User=${mongoDBOSUser}
Group=${mongoDBOSGroup}
Type=forking 
## MongoDB运行的pid文件路径 
PIDFile=${mongoDBBaseDir}/mongod.pid 
TimeoutSec=0 
## 启动命令,根据实际情况调整 
ExecStart=${mongoDBBaseDir}/bin/mongod --config ${mongoDBBaseDir}/conf/mongod.conf 
## 保持默认即可,自动识别pid 
ExecReload=/bin/kill -s HUP $MAINPID 
## 关闭脚本,根据实际情况调整 
ExecStop=${mongoDBBaseDir}/bin/mongod --config ${mongoDBBaseDir}/conf/mongod.conf --shutdown 
# 守护,意外的停止会被重启 
Restart=on-failure 
#设置安全退出码,不会被自动重启 
RestartPreventExitStatus=1 
[Install] 
WantedBy=multi-user.target
EOF
    echo "加载MongoDB启动脚本"
    systemctl daemon-reload

    echo "overwirte filekey value"
    echo $mongoDBFilekey > /data/mongodb/27017/conf/keyfile

    echo "启动MongoDB"
    systemctl start mongod_${mongoDBPort}

    echo "查看MongoDB状态"
    systemctl status mongod_${mongoDBPort}
}

PrintMongodbInstallInformation(){
    echo ""
    echo "MongoDB 软件安装目录  : $mongoDBBaseDir"
    echo "MongoDB 数据存放目录  : $mongoDBBaseDir/data"
    echo "MongoDB 备份存放目录  : $mongoDBBaseDir/backup"
    echo "MongoDB 日志存放目录  : $mongoDBBaseDir/log"
    echo "MongoDB 运行用户     : $mongoDBOSUser"
    echo "MongoDB 运行端口     : $mongoDBPort"
    echo "MongoDB Version     : $mongoDBPackage"
    echo "MongoDB 副本集名称    : $mongoDBReplsetName"
    echo "============> 你可以使用 $mongoDBBaseDir/bin/mongo localhost:${mongoDBPort} 登录数据库执行创建用户和副本集初始化等操作"
}

if [ $# -lt 1 ];then
    echo ''
    echo -e "\033[31mUsage: sh $0 MongoDB_Port \033[0m"
    echo ''
    echo -e "\033[32mSample: sh $0 30000 \033[0m"
    echo ''
    exit
fi

Main(){
    CheckPackageExists
    OptimizeMongodbRuntimeEnvironment
    CreateMongodbUserAndDir
    UnPackMongodbAndChangeOwner
    SetPathEnvironmentVariable
    GenerateMongodbConfAndKeyfile
    EnsureMongodbDirPermissions
    MongodbLogRotateConfig
    MongodbStartScriptConfig
    PrintMongodbInstallInformation
}
Main

副本集初始化脚本

vim init_mongo_replicaset.sh

#!/bin/bash

# 定义MongoDB节点地址
NODE1="172.21.27.35:27017"
NODE2="172.21.27.36:27017"
NODE3="172.21.27.37:27017"

# 初始化副本集
mongo <<EOF
var cfg = {
  "_id": "demo_sun",
  "members": [
    { "_id" : 0, "host" : "$NODE1" , "priority":2, votes: 1},
    { "_id" : 1, "host" : "$NODE2" , "priority":1, votes: 1},
    { "_id" : 2, "host" : "$NODE3" , "priority":1, votes: 1}
  ]
};

rs.initiate(cfg);
EOF

# 等待副本集初始化完成
sleep 15

# 为admin数据库添加管理员账号
mongo <<EOF
use admin
db.createUser({
  user: "admin",
  pwd: "admin",
  roles: [ { role: "root", db: "admin" } ]
})
EOF

# 为业务库添加业务账号
mongo "mongodb://admin:admin@172.21.27.35/admin" <<EOF
use yumchina
db.createUser({
  user: "dbuser",
  pwd: "Asdf1234",
  roles: [ { role: "dbOwner", db: "yumchina" } ]
});
db.createCollection("fosun");
db.fosun.insert({'000':'000'});
EOF

## 配置副本集成员为只读
#mongo <<EOF
#use admin
#db.runCommand({ configureFailPoint: "setReadonly", mode: "alwaysOn", data: { secondaryThrottle: true, writeThrottle: false } })
#db.runCommand({ configureFailPoint: "setReadonly", mode: "alwaysOn", data: { secondaryThrottle: false, writeThrottle: true } })
#EOF

echo "MongoDB replica set initialized with admin user and business user."



四、结合CICD

图片.png




五、相关mongo命令

# 获取mongodb的 md5值,不需要路径
md5sum mongodb-linux-x86_64-rhel70-4.4.17.tgz



# ###
# 初始化 mongo副本集, demo_sun mongo 演练资源
# ###
config = {
...     _id : "demo_sun",
...      members : [
...          {_id : 0, host : "172.21.27.35:27017", "priority":2, votes: 1},
...          {_id : 1, host : "172.21.27.36:27017", "priority":1, votes: 1},
...          {_id : 2, host : "172.21.27.37:27017", "priority":1, votes: 1}
...      ]
... };

# 执行初始化
rs.initiate(config)

# admin 
db.createUser({ user: "admin", pwd: "admin", roles: [ { role: "root", db: "admin"} ]})


db.auth("admin","admin")



# 创建fosun集合
db.createCollection("fosun")
# 插入文档
db.fosun.insert({'000':'000'}) 


# 查询刚插入的信息
db.fosun.find()
db.fosun.find({1:'1'})
db.getCollection("fosun").find({'1':'1'});




# 创建db
use sorder
# 创建业务账号,统一账号YumDBuser,密码6位大小写字母
db.createUser({ user: "root", pwd: "root@Yumc", roles: [ { role: "dbOwner", db: "sorder"} ]})

rs.status().members

# 查看配置
rs.conf()



mongo --port 27017 --authenticationDatabase admin -u admin -p 'admin'  --host 172.21.27.35


mongo --port 27017  --host 172.21.27.35
mongo --port 27017  --host 172.21.27.36
mongo --port 27017  --host 172.21.27.37


ansible -i hosts all -m shell -a "systemctl stop mongod_27017"
ansible -i hosts all -m shell -a "rm -rf /data/mongodb/27017/data/*"
ansible -i hosts all -m shell -a "rm -rf /data/mongodb/27017/log/*"
ansible -i hosts all -m shell -a "systemctl restart  mongod_27017"






六、补充