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

        负载均衡及高可用一直是我们线上服务架构所关注的重点,本文内容,将介绍如何在 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()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容