美文网首页程序员我爱编程
使用 Docker 构建 MongoDB 分片及副本集

使用 Docker 构建 MongoDB 分片及副本集

作者: 魏文弟 | 来源:发表于2018-03-17 17:11 被阅读0次

            负载均衡及高可用一直是我们线上服务架构所关注的重点,本文内容,将介绍如何在 Docker 环境下实现 MongoDB 的副本集及分片。

            在 MongoDB 中,副本集是一组实现了复制功能的服务器,其中一个是主服务器(Primary),用于处理客户端请求;其余为备份服务器(Secondary),用于保存主服务器的副本。如果主服务器出现故障,备份服务器将推举出其中一个成员为主服务器,继续响应请求。分片(Sharding)是将数据拆分并分散存放在不同机器上,这样不需要功能强大的大型计算机就可以存储更多的数据,处理更大的负载。MongoDB 的分片机制允许你创建一个包含许多台机器的集群,将数据子集分散在集群中,每个分片维护着一个数据集合的子集。与单机服务器和副本集相比,集群架构可以使应用程序具有更大的数据处理能力。

            副本集是让多台服务器都拥有同样的数据副本,每一台服务器都是其他服务器的镜像,而每一个分片都拥有和其他分片不同的数据子集。

            分片的目标之一是创建一个拥有5台、500台甚至更多机器的集群,整个集群对应用程序来说就像是一台单机服务器。为了对应用程序隐藏数据库架构的细节,在分片之前要先执行 mongos 进行一次路由过程。这个路由服务器维护着一个“内容列表”,指明了每个分片包含哪些数据内容。应用程序只需要连接到路由服务器,就可以像使用单机服务器一样进行正常的请求了。

            那么是不是在业务刚起步时就进行分片呢?不然。分片不止会增加部署的操作复杂度,还要求做出设计决策,而该决策以后很难再更改,所以不必太早分片,但也不宜在系统运行太久之后分片,因为在一个过载的系统上不停服进行分片是非常困难的。可以参考以下四点来决定何时分片:

                需要增加可用RAM

                增加可用磁盘空间

                减轻单台服务器的负载

                处理单个 mongod 无法承受的吞吐量

            MongoDB 集群包含三个组件:配置服务器、mongos 服务器、mongod 服务器。配置服务器相当于集群的大脑,保存着集群和分片的元数据:集群中有哪些分片、分片的是哪些集合以及数据块的分布等。mongos 需要从配置服务器获取信息,因此配置服务器应先于任何 mongos 进程启动。配置服务器是独立的 mongod 进程,所以可以像启动 mongod 一样启动配置服务器,但在 MongoDB3.4 及以后的版本,配置服务器必须部署为副本集的形式。

    准备环境

    一:初始化宿主机系统

     1.安装程序包

         yum -y install docker vim net-tools psmisc sysstat telnet wget lsof lrzsz

         systemctl enable docker

         setenforce 0

         vim /etc/sysconfig/selinux    修改Selinux为关闭状态

         vim /etc/security/limits.conf    修改文件句柄数

     2.禁止内存过度分配

    echo 1 > /proc/sys/vm/overcommit_memory

    vim /boot/grub2/grub.cfg

        numa=off

    3.禁用zone_reclaim_mode

        cat /proc/sys/vm/zone_reclaim_mode

            0

    4.块设备预读大小

        blockdev --report

        blockdev --setra 16 /dev/sdb1

    5.禁用大内存页面

        if test -f /sys/kernel/mm/transparent_hugepage/enabled; then

        echo never > /sys/kernel/mm/transparent_hugepage/enabled

        fi

        if test -f /sys/kernel/mm/transparent_hugepage/defrag; then

        echo never > /sys/kernel/mm/transparent_hugepage/defrag

        fi

    6.修改文件描述符限制

        nofile 64000

        nproc  64000

    7.时钟同步

        */2 * * * * ntpdate 1.sg.pool.ntp.org

    8.禁用atime,默认relatime

         vim /etc/fstab

         UUID=ef6ba050-6cdc-416a-9380-c14304d0d206 /                       xfs     defaults,noatime        0 0

        noatime,nodiratime 

    9.创建所需目录

    mkdir -p /data/db/rs{1..3}

    mkdir -p /data/db/conf{1..3}

    mkdir -p /data/logs/rs{1..3}

    chown -R mongo.mongo /data

    二:构建镜像

    1.Download Base Image centos7.3

         docker pull docker.io/centos

    2.start centos

         docker run -d -it --name centos7 docker.io/centos /bin/bash

         docker run exec -it centos7  bash

         useradd  mongo

         usermod mongo -u 1021

         groupmod -g 1021 mongo

         mkdir -p /data/db

         mkdir -p /data/logs

         chown -R mongo.mongo /data

         ln -s  /usr/lib64/libsasl2.so.3 /usr/lib64/libsasl2.so.2

         ln -s /home/mongo/mongodb/bin/* /usr/bin/

         su - mongo

         mongo --hlep

         yum install -y crontabs

         su - root

         /usr/sbin/crond

    3.docker commit centos 7 centos7

    4.docker build -t mongod3.2.11 .

    cat Dockerfile

    ####mongod####

    FROM centos7

    MAINTAINER Weiwendi

    USER mongo

    ENTRYPOINT ["/usr/bin/mongod"]

    5.docker build -t mongos3.2.11 . 

    cat Dockerfile

    ####mongos####

    FROM centos7

    MAINTAINER Weiwendi

    USER mongo

    ENTRYPOINT ["/usr/bin/mongos"]

    分发配置文件

    ConfigDB

    -------------------------------------------------------------------

    port            =   37019

    pidfilepath     =   /data/mongodb/configdb/data/mongod.pid

    fork            =   true

    configsvr       =   true

    dbpath          =   /data/mongodb/configdb/data

    logpath         =   /data/mongodb/configdb/logs/mongod.log

    logappend       =   true

    logRotate       =   rename

    journal         =   true

    directoryperdb  =   true

    nohttpinterface =   true

    quiet           =   true

    auth            =   true

    keyFile         =   /data/mongodb/key/mongodb-keyfile

    profile         =   1

    slowms          =   2000

    storageEngine   =   wiredTiger

    wiredTigerDirectoryForIndexes = true

    wiredTigerCacheSizeGB = 100

    replSet         =   cfgdb

    mongos

    -------------------------------------------------------------------

    port            =   47017

    pidfilepath     =   /data/mongodb/mongos/data/mongos.pid

    fork            =   true

    configdb        =   cfgdb/192.168.17.128:37019,192.168.17.129:37019,192.168.17.131:37019

    logpath         =   /data/mongodb/mongos/logs/mongos.log

    logappend       =   true

    logRotate       =   rename

    quiet           =   true

    keyFile        =   /data/mongodb/mongodb-keyfile

    mongod

    -----------------------------------------------------------------

    port            =   27017

    pidfilepath     =   /data/logs/mongod.pid

    fork            =   true

    dbpath          =   /data/db

    logpath         =   /data/logs/rs1.log

    logappend       =   true

    logRotate       =   rename

    journal         =   true

    directoryperdb  =   true

    nohttpinterface =   true

    quiet           =   true

    auth           =   true

    keyFile        =   /data/mongodb/key/mongodb-keyfile

    profile         =   1

    slowms          =   2000

    storageEngine   =   wiredTiger

    wiredTigerDirectoryForIndexes = true

    wiredTigerCollectionBlockCompressor = snappy

    wiredTigerJournalCompressor = snappy

    wiredTigerCacheSizeGB = 60

    replSet       =   rs1

    oplogSize     =   102400

    在三台主机上启动Docker容器

    创建副本集

    172.31.90.39   (副本集1)

    docker run --name rs1_srv1 -p 21117:27017 --restart=always -v /data/db/rs1:/data/db -v /data/logs/rs1:/data/logs -v /data/conf/rs1:/data/conf -v /data/backup:/data/bak -d  registry.newborn-town.com:5000/wtmongodb3.2.11 -f /data/conf/mongodb.conf

    docker run --name rs1_srv2 -p 21217:27017 --restart=always -v /data/db/rs2:/data/db -v /data/logs/rs2:/data/logs -v /data/conf/rs2:/data/conf -v /data/backup:/data/bak -d  registry.newborn-town.com:5000/wtmongodb3.2.11 -f /data/conf/mongodb.conf

    docker run --name rs1_srv3 -p 21317:27017 --restart=always -v /data/db/rs3:/data/db -v /data/logs/rs3:/data/logs -v /data/conf/rs3:/data/conf -v /data/backup:/data/bak -d  registry.newborn-town.com:5000/wtmongodb3.2.11 -f /data/conf/mongodb.conf

    172.31.90.64  (副本集2)

    docker run --name rs2_srv1 -p 21117:27017 --restart=always -v /data/db/rs1:/data/db -v /data/logs/rs1:/data/logs -v /data/conf/rs1:/data/conf -v /data/backup:/data/bak -d  registry.newborn-town.com:5000/wtmongodb3.2.11 -f /data/conf/mongodb.conf

    docker run --name rs2_srv2 -p 21217:27017 --restart=always -v /data/db/rs2:/data/db -v /data/logs/rs2:/data/logs -v /data/conf/rs2:/data/conf -v /data/backup:/data/bak -d  registry.newborn-town.com:5000/wtmongodb3.2.11 -f /data/conf/mongodb.conf

    docker run --name rs2_srv3 -p 21317:27017 --restart=always -v /data/db/rs3:/data/db -v /data/logs/rs3:/data/logs -v /data/conf/rs3:/data/conf -v /data/backup:/data/bak -d  registry.newborn-town.com:5000/wtmongodb3.2.11 -f /data/conf/mongodb.conf

    172.31.90.161  (副本集3)

    docker run --name rs3_srv1 -p 21117:27017 --restart=always -v /data/db/rs1:/data/db -v /data/logs/rs1:/data/logs -v /data/conf/rs1:/data/conf -v /data/backup:/data/bak -d  registry.newborn-town.com:5000/wtmongodb3.2.11 -f /data/conf/mongodb.conf

    docker run --name rs3_srv2 -p 21217:27017 --restart=always -v /data/db/rs2:/data/db -v /data/logs/rs2:/data/logs -v /data/conf/rs2:/data/conf -v /data/backup:/data/bak -d  registry.newborn-town.com:5000/wtmongodb3.2.11 -f /data/conf/mongodb.conf

    docker run --name rs3_srv3 -p 21317:27017 --restart=always -v /data/db/rs3:/data/db -v /data/logs/rs3:/data/logs -v /data/conf/rs3:/data/conf -v /data/backup:/data/bak -d  registry.newborn-town.com:5000/wtmongodb3.2.11 -f /data/conf/mongodb.conf

    配置服务器

    172.31.90.39

        docker run --name cfg1 -p 37017:27017 --restart=always -v /data/db/conf1:/data/db -d registry.newborn-town.com:5000/mongod-3.2.10  --storageEngine wiredTiger --smallfiles --configsvr --dbpath /data/db --port 27017

    172.31.90.64

        docker run --name cfg2 -p 37017:27017 --restart=always -v /data/db/conf2:/data/db -d registry.newborn-town.com:5000/mongod-3.2.10 --storageEngine wiredTiger --smallfiles --configsvr --dbpath /data/db --port 27017

    172.31.90.161

        docker run --name cfg3 -p 37017:27017 --restart=always -v /data/db/conf3:/data/db -d registry.newborn-town.com:5000/mongod-3.2.10  --storageEngine wiredTiger --smallfiles --configsvr --dbpath /data/db --port 27017

    mongos进程

    172.31.90.39

        docker run --name mongos1 -p 27017:27018 --restart=always -v /data/logs/rs1:/data/logs -d registry.newborn-town.com:5000/mongos-3.2.10  --logpath /data/logs/mongos.log --logappend --configdb 172.31.90.39:37017,172.31.90.64:37017,172.31.90.161:37017  --port 27018

    172.31.90.64

        docker run --name mongos2 -p 27017:27018 --restart=always -v /data/logs/rs2:/data/logs -d registry.newborn-town.com:5000/mongos-3.2.10  --logpath /data/logs/mongos.log --logappend --configdb 172.31.90.39:37017,172.31.90.64:37017,172.31.90.161:37017  --port 27018

    172.31.90.161

        docker run --name mongos3 -p 27017:27018 --restart=always -v /data/logs/rs3:/data/logs -d registry.newborn-town.com:5000/mongos-3.2.10  --logpath /data/logs/mongos.log --logappend --configdb 172.31.90.39:37017,172.31.90.64:37017,172.31.90.161:37017  --port 27018

    以上启动Docker容器步骤,可以通过docker compose来管理。

    设置副本集(在mongodb上执行)

    172.31.90.39

    mongo --port 21117

    use admin

    config_rs = {

       "_id":"rs1",

       "members": [

           {"_id":0,"host":"172.31.90.39:21117"},

           {"_id":1,"host":"172.31.90.64:21117"},

           {"_id":2,"host":"172.31.90.161:21117"}

       ]

    }

    rs.initiate(config_rs)

    172.31.90.64

    mongo --port 21217

    use admin

    config_rs = {

       "_id":"rs2",

       "members": [

           {"_id":0,"host":"172.31.90.39:21217"},

           {"_id":1,"host":"172.31.90.64:21217"},

           {"_id":2,"host":"172.31.90.161:21217"}

       ]

    }

    rs.initiate(config_rs)

    172.31.90.161

    mongo --port 21317

    use admin

    config_rs = {

       "_id":"rs3",

       "members": [

           {"_id":0,"host":"172.31.90.39:21317"},

           {"_id":1,"host":"172.31.90.64:21317"},

           {"_id":2,"host":"172.31.90.161:21317"}

       ]

    }

    rs.initiate(config_rs)

    设置分片(mongos上执行)

    use admin

    sh.addShard("rs1/172.31.90.39:21117,172.31.90.64:21117,172.31.90.161:21117")

    sh.addShard("rs2/172.31.90.39:21217,172.31.90.64:21217,172.31.90.161:21217")

    sh.addShard("rs3/172.31.90.39:21317,172.31.90.64:21317,172.31.90.161:21317")

    sh.enableSharding("kittylive")

    use kittylive

    db.user.createIndex({user_id:"hashed"})

    db.bill.createIndex({bill_id:"hashed"})

    db.giftRecord.createIndex({gift_id:"hashed"})

    sh.shardCollection("kittylive.user",{"user_id":"hashed"})

    sh.shardCollection("kittylive.bill",{"bill_id":"hashed"})

    sh.shardCollection("kittylive.giftRecord",{"gift_id":"hashed"})

    设置块迁移窗口期

         use config

         db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "22:00", stop : "02:00" } } }, true )

         sh.getBalancerWindow()

    相关文章

      网友评论

        本文标题:使用 Docker 构建 MongoDB 分片及副本集

        本文链接:https://www.haomeiwen.com/subject/qeyjqftx.html