欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Docker部署MongoDB分片+副本集集群(实战)

程序员文章站 2022-03-26 20:17:12
引言本次实践部署mongodb集群,主要借鉴于该博客(https://blog.csdn.net/weixin_42104521/article/details/103731266)。一、原理简析Mongodb一共有三种集群搭建的方式:Replica Set(副本集)、Sharding(切片)Master-Slaver(主从)mongoDB目前已不推荐使用主从模式,取而代之的是副本集模式。副本集其实一种互为主从的关系,可...

引言

本次实践部署mongodb集群,
主要借鉴于该博客(https://blog.csdn.net/weixin_42104521/article/details/103731266)。

一、原理简析

Mongodb一共有三种集群搭建的方式:
Replica Set(副本集)、
Sharding(切片)
Master-Slaver(主从)

      mongoDB目前已不推荐使用主从模式,取而代之的是副本集模式。副本集其实一种互为主从的关系,可理解为主主。
      副本集:指将数据复制,多份保存,不同服务器保存同一份数据,在出现故障时自动切换。对应的是数据冗余、备份、镜像、读写分离、高可用性等关键词;
      分片:则指为处理大量数据,将数据分开存储,不同服务器保存不同的数据,它们的数据总和即为整个数据集。追求的是高性能。

本实验模拟的MongoDB集群分以下几个层次或角色

mongos层:请求的入口,是router的角色,相当于监听,负责将请求分发到对应的存储数据的shard上,多副本冗余

config server层:记录了mongos中使用到的元数据,自动向mongos同步最新的集群配置,多副本冗余

shard主节点层:将数据分片,数据库拆分,并将其分散在不同的机器上,原理是将整个数据集合切块
块分散到各个shard中,每个shard只负责总数据的一部分,通过一个均衡器来对各个shard均衡,多副本冗余

shard副本层:是shard的备份,多副本冗余

shard仲裁层:用于仲裁,不存储数据,使用最小的资源,需要基数个仲裁角色,且不能放在同一设备上

主机角色端口规划

本次实践在自建虚拟机进行,有个别需求的同学,可以购买华为云ECS进行部署(当前优惠力度大哦) 华为云-2核4G云主机低至487元/年
Docker部署MongoDB分片+副本集集群(实战)

服务器 192.168.1.32 192.168.1.33 192.168.1.35
服务端口 mongos:27017 mongos:27017 mongos:27017
服务端口 config server:9001 config server:9001 config server:9001
服务端口 shard1 主节点:9005 shard1 副节点:9005 shard1 仲裁节点:9005
服务端口 shard2 仲裁节点:9006 shard2 主节点:9006 shard2 副节点:9006
服务端口 shard3 副节点:9007 shard3 仲裁节点:9007 shard3 主节点:9007

可以看到每台主机上有1个mongos、1个config server、3个分片,三台主机的相同分片之间构成了主、副和仲裁三个角色。

总结

应用请求mongos来操作mongodb的增删改查
配置服务器存储数据库元信息,并且和mongos做同步
数据最终存入在shard(分片)上
为了防止数据丢失同步在副本集中存储了一份
仲裁在数据存储到分片的时候决定存储到哪个节点

二、部署配置服务器

创建挂载目录、配置文件

mkdir /data/mongod/configdata/configsvr -p   //三台主机都执行
mkdir /data/mongod/conf/{configsvr,keyfile} -p   // keyfile在开启用户认证时需要

配置文件

# vim /data/mongod/conf/configsvr/mongod.conf
net:
  bindIpAll: true
replication:
  replSetName: rs_configsvr # 副本集名称,相同副本须使用同一个副本集名称
  
sharding: 
   clusterRole: configsvr   # 定义为mongo配置服务器

启动configsvr

## 三台主机均执行此操作
docker run -d -p 9001:27019 --name configsvr \
  --entrypoint "mongod" \
  -v /data/mongod/configdata/configsvr:/data/configdb \
  -v /data/mongod/conf/keyfile:/data/keyfile \
  -v /data/mongod/conf/configsvr:/data/conf \
  mongo:4.0.21 -f /data/conf/mongod.conf

备注:如果docker ps 没有刚才创建的容器名称,可以使用docker logs <容器id>查看docker 日志

初始化配置服务复制集

# 进入容器中,创建的三个配置服务中随便一个
docker exec -it configsvr bash
 
# 登录mongo
mongo --host 192.168.1.32 --port 9001
 
# 初始化
use admin
rs.initiate({
    _id: "rs_configsvr",
    configsvr: true,
    members: [
            { _id : 0, host : "192.168.1.32:9001" },
            { _id : 1, host : "192.168.1.33:9001" },
            { _id : 2, host : "192.168.1.35:9001" }
        ]
    }
)

rs.status()   //查看状态

三、创建分片副本集

创建分片副本集配置文件、挂载文件

## 创建配置文件、数据目录
mkdir /data/mongod/shard1/{log,db} -p
mkdir /data/mongod/shard2/{log,db} -p
mkdir /data/mongod/shard3/{log,db} -p
chmod -R 777 /data/mongod/shard1
chmod -R 777 /data/mongod/shard2
chmod -R 777 /data/mongod/shard3
mkdir -p /data/mongod/conf/{shard1,shard2,shard3}  

## 三台主机均创建三个配置文件,shard分片名不同即可
#所有用到的文件夹和文件必须在创建的时候给权限,包括重新创建,也需要重新给权限,并且文件夹要提前创建好
# vim /data/mongod/conf/{shard1,shard2,shard3}/mongod.conf   //添加如下配置信息,分片服务名称不一致即可
storage:
  dbPath: /home/mongod/db #分片数据库路径
  journal:
    enabled: true
  directoryPerDB: true

systemLog:
  destination: file
  logAppend: true
  path: /home/mongod/log/mongod.log # 分片日志

net:
  bindIpAll: true

setParameter:
  enableLocalhostAuthBypass: false

replication:
  replSetName: rs_shardsvr1  # 分片服务名称
 
sharding: 
   clusterRole: shardsvr     # 配置为分片服务

注意事项:
1、需要提前建立需要的文件夹。并赋予权限(chmod -R 750 文件夹)。
2、三个分片服务器建立在三个位置,(docker代码 -v 参数即为实际建立需要的文件夹),需要注意对应创建分片配置文件,文件内容一致。
3、注意配置文件中的数据库文件报错路径以及日志文件路径,按需更改。
4、分片服务端口需要映射 27018

shard1 分片

1、mongod分片部署

## 三台主机(192.168.1.32、33、35)执行如下启动命令
docker run --name shardsvr1 -d -p 9005:27018 \
  --entrypoint "mongod" \
  -v /data/mongod/shard1:/home/mongod \
  -v /data/mongod/conf/keyfile/:/data/keyfile/ \
  -v /data/mongod/conf/shard1/:/data/conf/ \
  mongo:4.0.21 -f /data/conf/mongod.conf

2、初始化分片服务器

# 登录进容器中,任意一台
docker exec -it shardsvr1 bash
 
# 登录分片服务器
# 192.168.1.32 主分片节点
# 192.168.1.33 副分片节点
# 192.168.1.35 仲裁分片节点,arbiterOnly:true 表示为仲裁节点

mongo --host 192.168.1.32 --port 9005
use admin
rs.initiate(
    {
        _id : "rs_shardsvr1",
        members: [
            { _id : 0, host : "192.168.1.32:9005",priority:5 },
            { _id : 1, host : "192.168.1.33:9005",priority:3 },
            { _id : 2, host : "192.168.1.35:9005",arbiterOnly:true }
        ]
    }
)
 
#rs.status() 查看状态

shard2 分片

1、mongod分片部署

## 三台主机(192.168.1.32、33、35)执行如下启动命令
docker run --name shardsvr2 -d -p 9006:27018 \
  --entrypoint "mongod" \
  -v /data/mongod/shard2:/home/mongod \
  -v /data/mongod/conf/keyfile/:/data/keyfile/ \
  -v /data/mongod/conf/shard2/:/data/conf/ \
  mongo:4.0.21 -f /data/conf/mongod.conf

2、初始化分片服务器

# 登录进容器中,尽量在主节点执行,否则会报错
docker exec -it shardsvr2 bash

#登录分片服务器
# 192.168.1.32 仲裁分片节点
# 192.168.1.33 主分片节点
# 192.168.1.35 副分片节点

mongo --host 192.168.1.33 --port 9006
use admin
rs.initiate(
    {
        _id : "rs_shardsvr2",
        members: [
            { _id : 0, host : "192.168.1.32:9006",arbiterOnly:true },
            { _id : 1, host : "192.168.1.33:9006",priority:5 },
            { _id : 2, host : "192.168.1.35:9006",priority:3 }
        ]
    }
)
 
#rs.status() 查看状态

shard3 分片

1、mongod分片部署

## 三台主机(192.168.1.32、33、35)执行如下启动命令
docker run --name shardsvr3 -d -p 9007:27018 \
  --entrypoint "mongod" \
  -v /data/mongod/shard3:/home/mongod \
  -v /data/mongod/conf/keyfile/:/data/keyfile/ \
  -v /data/mongod/conf/shard3/:/data/conf/ \
  mongo:4.0.21 -f /data/conf/mongod.conf

2、初始化分片服务器

# 登录进容器中,任意节点
docker exec -it shardsvr3 bash

# 登录分片服务器
# 192.168.1.32 副分片节点
# 192.168.1.33 仲裁分片节点
# 192.168.1.35 主分片节点

mongo --host 192.168.1.35 --port 9007    // 尽量在主节点执行,否则可能会出现报错
use admin
rs.initiate(
    {
        _id : "rs_shardsvr3",
        members: [
            { _id : 0, host : "192.168.1.32:9007",priority:3 },
            { _id : 1, host : "192.168.1.33:9007",arbiterOnly:true },
            { _id : 2, host : "192.168.1.35:9007",priority:5 }
        ]
    }
)
 
#rs.status() 查看状态

四,创建mongos,连接mongos到分片集群

创建mongos配置文件

mkdir /data/mongod/conf/mongos -p   //三台主机都执行

vim /data/mongod/conf/mongos/mongod.conf
## 配置文件
net:
  bindIpAll: true

sharding: 
   configDB: rs_configsvr/192.168.1.32:9001,192.168.1.33:9001,192.168.1.35:9001   # 定义为mongos配置服务器

mongos 部署

1、分片路由部署,三台均执行相同操作

docker run --name mongos -d \
  -p 27017:27017 \
  --entrypoint "mongos" \
  -v /data/mongod/conf/keyfile/:/data/keyfile/ \
  -v /data/mongod/conf/mongos/:/data/conf/ \
  mongo:4.0.21 -f /data/conf/mongod.conf

备注:
rs_configsvr/192.168.1.32:9001,192.168.1.33:9001,192.168.1.35:9001: 配置服务名称/配置服务端口(多个用逗号分隔)

2、初始化mongos

# 进入mongos 容器中
docker exec -it mongos bash
 
# 连接mongos
mongo --host 127.0.0.1 --port 27017
use admin
# 添加分片服务器
sh.addShard("rs_shardsvr1/192.168.1.32:9005,192.168.1.33:9005,192.168.1.35:9005")
sh.addShard("rs_shardsvr2/192.168.1.32:9006,192.168.1.33:9006,192.168.1.35:9006")
sh.addShard("rs_shardsvr3/192.168.1.32:9007,192.168.1.33:9007,192.168.1.35:9007")

sh.status() //查看状态

开启分片功能

## db和collection开启分片功能
虽然数据库采用分片集群的方式部署,但如果db和collection不启用分片的话(默认是不启用的),数据不会分片存储,此时如果向集群中导入一个db,会将整个db随机存储到任意一个分片中,而不是拆分存储到多个分片。
db启用分片:
sh.enableSharding("库名")
sh.enableSharding("<database>")
将上述命令中的“”换成实际的db名。

collection启用分片:
sh.shardCollection("库名.集合名",{"key":1})
sh.shardCollection("<database>.<collection>", { <shard key> : "hashed" } )
上述命令中的“< database >.< collection >”为实际的db名和collection名;“{ < shard key > : “hashed” }”为片键的集合。

五,测试使用

测试使用

# 任意一节点操作
# 进入mongos 容器中
docker exec -it mongos bash
# 连接mongos
mongo --host 127.0.0.1 --port 27017
use admin

#  testdb1开启分片功能
db.runCommand( { enablesharding  : "testdb1"});
db.runCommand( { shardcollection : "testdb1.tab1",key : {id: 1} } )

# 添加数据 
use testdb1;
for(var i=1;i<=20000;i++) db.tab1.save({id:i,"test1":"testval1"});

db.tab1.stats();
exit

# 使用testdb1库
# 循环插入数据到testdb1库的tab1集合中的键id中
# 该库对应的该集合对应的该键被设置成了分片
# 查看分片情况

分别在三个主机上操作配置库、插入测试数据、查看测试数据
验证了副本同步,最后的显示结果看到 “sharded” : true 表示分片也是成功的

六、开启登录认证

设置数据库账号

在任意mongos节点操作
# 进入mongos 容器中
docker exec -it mongos bash
 
# 连接mongos
mongo --host 127.0.0.1 --port 27017
mongos> use admin
switched to db admin    
mongos> show collections


添加两个管理员账号,一个系统管理员:system 一个数据库管理员:administrator
#先添加系统管理员账号,用来管理用户
mongos> db.createUser({user:"system",pwd:"123456",roles:[{role:"root",db:"admin"}]})

# 添加数据库管理员,用来管理所有数据库
mongos> db.createUser({user:'administrator', pwd:'123456', roles:[{ role: 
mongos> db.auth('administrator','123456')    //添加管理员用户认证,认证之后才能管理所有数据库   

# 退出,用刚才创建的账号进行登录
 mongo 192.168.1.33:27017 -u system -p 123456 --authenticationDatabase admin
 mongo 192.168.1.35:27017 -u administrator -p 123456  --authenticationDatabase admin

开启登录验证

mkdir /data/mongod/conf/keyfile -p     //三台主机都执行

# 在192.168.1.32节点服务器上操作
cd /data/mongod/conf/keyfile           //切换到指定目录
openssl rand -base64 756 > key.file    //创建一个 keyfile(使用 openssl 生成 756 位 base64 加密的字符串)   
chmod 600 ./key.file 

# 复制文件到其他主机
scp ./key.file root@192.168.1.33:/data/mongod/conf/keyfile
scp ./key.file root@192.168.1.33:/data/mongod/conf/keyfile

设置配置文件

使用访问控制强制重新启动复制集的每个成员
# 依次在每台机器上的mongod(注意是所有的mongod不是mongos)的配置文件中加入下面一段配置。如我在192.168.1.32上的config server,shard1,shard2,shard3都加入下面的配置文件
security:
  keyFile: /data/keyfile/key.file
  authorization: enabled
  
# 依次在每台机器上的mongos配置文件中加入下面一段配置
security:
  keyFile: /data/keyfile/key.file

重启集群

# 在三台主机执行如下命令
docker ps  |grep mongo |awk -F " " '{print $1}' |xargs -r docker restart

本文地址:https://blog.csdn.net/qq_38008295/article/details/110952401

相关标签: 部署 运维