MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)

MongoDB集群搭建与管理

  • MongoDB集群搭建与管理
    • MongoDB集群搭建与管理
      • MongoDB集群简介
        • 主从备份(Master - Slave)模式
        • 副本集(Replica Set)模式
        • 分片(Sharding)模式
          • 什么是副本集
          • 副本集架构
          • Primary选举
      • 搭建副本集群
        • 准备工作
        • 操作容器
        • 主从复制测试
        • 主从切换测试
        • 扩缩容
      • MongoDB分片搭建
        • 分片介绍
        • 集群中数据分布
        • chunk分裂及迁移
        • 数据分片
        • 什么情况下使用分片
      • 数据分片
        • 分片案例
        • 开启分片
      • 扩缩容
        • 扩容
        • 缩容
    • Mongo分片高可用集群搭建
      • 高可用集群整体架构
        • 基础环境准备
        • 搭建ConfigServer副本集
        • 搭建Shard分片组
        • 搭建Mongos
      • Docker-compose方式搭建
        • 启动服务

MongoDB集群搭建与管理

MongoDB集群搭建与管理

MongoDB集群简介

mongodb 集群搭建的方式有三种:

主从备份(Master - Slave)模式

主从(Master-Slaver) ,或者叫主从复制模式。
因为官方已经不推荐使用,并且已经在MongoDB3.6以后慢慢废弃了,这里不过多的介绍了
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第1张图片
工作原理:主机工作,备机处于监控准备状况;当主机宕机时,备机接管主机的一切工作,待主机恢复正常后,按使用者的设定以自动或手动方式将服务切换到主机上运行,数据的一致性通过共享存储系统解决

副本集(Replica Set)模式

副本集(Replica Set)
简单来说就是集群当中包含了多份数据,保证主节点挂掉了,备节点能继续提供数据服务,提供的前提就是数据需要和主节点一致
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第2张图片
默认设置下,主节点提供所有增删查改服务,备节点不提供任何服务。但是可以通过设置使备节点提供查询服务,这样就可以减少主节点的压力,当客户端进行数据查询时,请求自动转到备节点上。这个设置叫做Read Preference Modes。
副本集特点

  • N个节点的集群
  • 任何节点可作为主节点(除了仲裁节点)
  • 所有写操作都在主节点上
  • 自动故障迁移
  • 自动恢复

分片(Sharding)模式

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第3张图片
Sharding和Replica Set类似,都需要一个仲裁节点,但是Sharding还需要配置节点和路由节点。就三种集群搭建方式来说,这种是最复杂的。
为什么Sharding会需要配置Replica Set。其实想想也能明白,多个节点的数据肯定是相关联的,如果不配一个Replica Set,怎么标识是同一个集群的呢。配置方式和之前所说的一样,定一个cfg,然后初始化配置。

什么是副本集

一组Mongodb复制集,就是一组mongod进程,这些进程维护同一个数据集合。复制集提供了数据冗余和高等级的可靠性,这是生产部署的基础。
MongoDB 副本集是将数据同步在多个服务器的过程,复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性,同时还允许从硬件故障和服务中断中恢复数据。

副本集的目的
保证数据在生产部署时的冗余和可靠性,通过在不同的机器上保存副本来保证数据不会因为单点损坏而丢失。能够随时应对数据丢失、机器损坏带来的风险。
换一句话来说,还能提高读取能力,用户的读取服务器和写入服务器在不同的地方,而且,由不同的服务器为不同的用户提供服务,提高整个系统的负载。

副本集工作原理
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第4张图片
一组复制集就是一组mongod实例掌管同一个数据集,实例可以在不同的机器上面。实例中包含一个主导,接受客户端所有的写入操作,其他都是副本实例,从主服务器上获得数据并保持同步。
  主服务器很重要,包含了所有的改变操作(写)的日志。但是副本服务器集群包含所有的主服务器数据,因此当主服务器挂掉了,就会在副本服务器上重新选取一个成为主服务器。
  每个复制集还有一个仲裁者,仲裁者不存储数据,只是负责通过心跳包来确认集群中集合的数量,并在主服务器选举的时候作为仲裁决定结果。

副本集架构

基本的架构由3台服务器组成,一个三成员的复制集,由三个有数据,或者两个有数据,一个作为仲裁者。
没有仲裁节点
具有三个存储数据的成员的复制集有:

  • 一个主库;
  • 两个从库

主库宕机时,这两个从库都可以被选为主库。
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第5张图片
当主库宕机后,两个从库都会进行竞选,其中一个变为主库,当原主库恢复后,作为从库加入当前的复制集群即可。
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第6张图片
当存在仲裁节点
在三个成员的复制集中,有两个正常的主从,及一台arbiter节点:

  • 一个主库
  • 一个从库,可以在选举中成为主库
  • 一个aribiter节点,在选举中,只进行投票,不能成为主库
    MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第7张图片
    说明:
    由于arbiter节点没有复制数据,因此这个架构中仅提供一个完整的数据副本。arbiter节点只需要更少的资源,代价是更有限的冗余和容错。
    当主库宕机时,将会选择从库成为主,主库修复后,将其加入到现有的复制集群中即可。
    MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第8张图片
Primary选举

复制集通过replSetInitiate命令(或mongo shell的rs.initiate())进行初始化,初始化后各个成员间开始发送心跳消息,并发起Priamry选举操作,获得『大多数』成员投票支持的节点,会成为Primary,其余节点成为Secondary。
『大多数』的定义
  假设复制集内投票成员(后续介绍)数量为N,则大多数为 N/2 + 1,当复制集内存活成员数量不足大多数时,整个复制集将无法选举出Primary,复制集将无法提供写服务,处于只读状态。
  在这里插入图片描述

通常建议将复制集成员数量设置为奇数,从上表可以看出3个节点和4个节点的复制集都只能容忍1个节点失效,从『服务可用性』的角度看,其效果是一样的。(但无疑4个节点能提供更可靠的数据存储)
副本集成员
Secondary
正常情况下,复制集的Seconary会参与Primary选举(自身也可能会被选为Primary),并从Primary同步最新写入的数据,以保证与Primary存储相同的数据。
Secondary可以提供读服务,增加Secondary节点可以提供复制集的读服务能力,同时提升复制集的可用性。另外,Mongodb支持对复制集的Secondary节点进行灵活的配置,以适应多种场景的需求。
Arbiter
Arbiter节点只参与投票,不能被选为Primary,并且不从Primary同步数据。
比如你部署了一个2个节点的复制集,1个Primary,1个Secondary,任意节点宕机,复制集将不能提供服务了(无法选出Primary),这时可以给复制集添加一个Arbiter节点,即使有节点宕机,仍能选出Primary。
Arbiter本身不存储数据,是非常轻量级的服务,当复制集成员为偶数时,最好加入一个Arbiter节点,以提升复制集可用性。

搭建副本集群

准备工作

安装 docker
docker安装步骤:https://docs.docker.com/engine/install/centos/
下载Mongo镜像
下载 mongo 镜像,如有需求可加上版本号

docker pull mongo

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第9张图片
创建挂载目录

mkdir -p /tmp/mongo/mongo{1..3}/data 
mkdir -p /tmp/mongo/mongo{1..3}/logs 
mkdir -p /tmp/mongo/conf

在这里插入图片描述

建立网络

docker network create mongo-cluster 
docker network ls

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第10张图片
生成key

cd /tmp/mongo/conf 
openssl rand -base64 90 -out ./keyfile 
chmod 600 keyfile

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第11张图片
创建配置文件

vi /tmp/mongo/conf/mongodb.conf
dbpath = /data/db 
port = 27017 
# 设置oplog的大小 
oplogSize=4096 
# 最大同时连接数 默认2000 
maxConns=640000 
# 设置每个数据库将被保存在一个单独的目录 
directoryperdb=true 
bind_ip=0.0.0.0 
#auth=true 
# #内存限制 
wiredTigerCacheSizeGB = 6 
replSet=mongo-repliset
# 启用key验证 
keyFile=/etc/mongo/mongo.key

创建3个容器

docker run --net mongo-cluster \ 
--restart always --name mongo1 -p 30001:27017 \ 
-v /tmp/mongo/mongo1/data:/data/db \ 
-v /tmp/mongo/conf:/etc/mongo \ 
-v /etc/localtime:/etc/localtime \ 
-d mongo -f /etc/mongo/mongodb.conf 
docker run --net mongo-cluster \ 
--restart always --name mongo2 -p 30002:27017 \ 
-v /tmp/mongo/mongo2/data:/data/db \ 
-v /tmp/mongo/conf:/etc/mongo \ 
-v /etc/localtime:/etc/localtime \ 
-d mongo -f /etc/mongo/mongodb.conf 
docker run --net mongo-cluster \ 
--restart always --name mongo3 -p 30003:27017 \ 
-v /tmp/mongo/mongo3/data:/data/db \ 
-v /tmp/mongo/conf:/etc/mongo \ 
-v /etc/localtime:/etc/localtime \ 
-d mongo -f /etc/mongo/mongodb.conf

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第12张图片参数说明

  • docker run 从镜像启动一个容器
  • -p 30001:27017 端口映射,容器内的端口 27017 映射到本机的端口 30001
  • –name mongo1 给这个容器起个名字 mongo1
  • –net mongo-cluster 把这个容器添加到网络 mongo-cluster mongo 要使用的镜像名 mongod
  • –replSet mongo-repliset 容器启动后要运行的命令,执行 mongod 命令,并通过参数指定这个实 例加入名为 mongo-repliset 的复制集

操作容器

登录容器
使用我们的本地客户端登录容器,登录任意一台容器都可以

mongo 127.0.0.1:30001

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第13张图片
初始化集群
执行下面的命令进行初始化集群

rs.initiate({ 
"_id" : "mongo-repliset", 
"members" : 
[ 
{ "_id" : 0, "host" : "mongo1:27017" }, 
{ "_id" : 1, "host" : "mongo2:27017" }, 
{ "_id" : 2, "host" : "mongo3:27017" } 
] 
})

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第14张图片
查看集群信息

db.hello()

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第15张图片

主从复制测试

主节点添加数据
在主节点执行下面的命令

# 创建 mytest数据库 
use mytest; 
db.blog.insert({ 
"title": "MongoDB 教程", 
"description": "MongoDB 是一个 Nosql 数据库", 
"by": "我的博客", 
"url": "http://www.baiyp.ren", 
"tags": [ 
"mongodb", 
"database", 
"NoSQL" 
],
"likes": 100 
}); 

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第16张图片
从节点查看数据
切换到从节点,进行查看数据

mongo 127.0.0.1:30002 
use mytest; 
db.blog.find().pretty(); 

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第17张图片
我们发现无法进行查看,报错不是master节点,这个时候需要配置主节点可以查看
db.setSecondaryOk 很关键,代表允许连接读取非 primary 实例数据,没有设置进行查询时报错

use mytest; 
db.setSecondaryOk() 
db.blog.find().pretty();

这个时候就可以查看数据了,但是有一个警告,
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第18张图片

主从切换测试

停掉主节点

docker stop mongo1

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第19张图片
查看从节点信息
我们看刚才的从节点已经变成了主节点
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第20张图片

rs.isMaster()

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第21张图片
启动停止的节点

docker start mongo1

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第22张图片
连接节点查看信息

mongo 127.0.0.1:30001

登录后我们发现已经变成了从节点

扩缩容

扩容节点
新增一个docker节点

docker run --net mongo-cluster \ 
--restart always --name mongo4 -p 30004:27017 \ 
-v /tmp/mongo/mongo4/data:/data/db \ 
-v /tmp/mongo/conf:/etc/mongo \ 
-v /etc/localtime:/etc/localtime \ 
-d mongo -f /etc/mongo/mongodb.conf 

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第23张图片
从主节点新增节点

rs.add("shard1-server4:27017")
或者
rs.add("mongo4:27017")

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第24张图片
查看节点信息

rs.isMaster()

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第25张图片
到新增的副本节点查看数据

mongo 127.0.0.1:30004 
use mytest; 
db.setSecondaryOk() 
db.blog.find().pretty(); 

我们发现数据已经同步过来了
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第26张图片
缩容节点
将我们刚才添加的模拟mongo4节点删除,在主节点执行以下命令

rs.remove("mongo4:27017")

在这里插入图片描述
查看节点信息

rs.isMaster()

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第27张图片

MongoDB分片搭建

分片(sharding)是MongoDB用来将大型集合分割到不同服务器(或者说一个集群)上所采用的方法。尽管分片起源于关系型数据库分区,但MongoDB分片完全又是另一回事。
和MySQL分区方案相比,MongoDB的最大区别在于它几乎能自动完成所有事情,只要告诉
MongoDB要分配数据,它就能自动维护数据在不同服务器之间的均衡

分片介绍

分片的目的
高数据量和吞吐量的数据库应用会对单机的性能造成较大压力,大的查询量会将单机的CPU耗尽,大的数据量对单机的存储压力较大,最终会耗尽系统的内存而将压力转移到磁盘IO上。
为了解决这些问题,有两个基本的方法: 垂直扩展和水平扩展

  • 垂直扩展:增加更多的CPU和存储资源来扩展容量。
  • 水平扩展:将数据集分布在多个服务器上。水平扩展即分片。

分片设计思想
分片为应对高吞吐量与大数据量提供了方法。使用分片减少了每个分片需要处理的请求数,因此,通过水平扩展,集群可以提高自己的存储容量和吞吐量。举例来说,当插入一条数据时,应用只需要访问存储这条数据的分片.
使用分片减少了每个分片存储的数据
例如,如果数据库1tb的数据集,并有4个分片,然后每个分片可能仅持有256 GB的数据。如果有40个分片,那么每个切分可能只有25GB的数据。
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第28张图片
分片机制的优势
分片机制提供了如下三种优势
自动路由
对集群进行抽象,让集群“不可见”
  MongoDB自带了一个叫做mongos的专有路由进程。mongos就是掌握统一路口的路由器,其会将客户端发来的请求准确无误的路由到集群中的一个或者一组服务器上,同时会把接收到的响应拼装起来发回到客户端。
保证高可用
保证集群总是可读写
  MongoDB通过多种途径来确保集群的可用性和可靠性。将MongoDB的分片和复制功能结合使用,在确保数据分片到多台服务器的同时,也确保了每份数据都有相应的备份,这样就可以确保有服务器挂掉时,其他的从库可以立即接替坏掉的部分继续工作。
易于扩展
使集群易于扩展
  当系统需要更多的空间和资源的时候,MongoDB使我们可以按需方便的扩充系统容量。

分片架构
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第29张图片
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第30张图片
mongos的路由进程进行操作
基础组件
其利用到了四个组件:mongos,config server,shard,replica set

基础组件
其利用到了四个组件:mongos,config server,shard,replica set
mongos
数据库集群请求的入口所有请求需要经过mongos进行协调,无需在应用层面利用程序来进行路由选择,mongos其自身是一个请求分发中心,负责将外部的请求分发到对应的shard服务器上,mongos作为统一的请求入口,为防止mongos单节点故障,一般需要对其做HA(高可用,HighlyAvailable缩写)。

config server
配置服务器,存储所有数据库元数据(分片,路由)的配置。mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存中来读取数据,mongos在第一次启动或后期重启时候,就会从config server中加载配置信息,如果配置服务器信息发生更新会通知所有的mongos来更新自己的状态,从而保证准确的请求路由,生产环境中通常也需要多个config server,防止配置文件存在单节点丢失问题。

shard
在传统意义上来讲,如果存在海量数据,单台服务器存储1T压力非常大,考虑到数据库的硬盘,网络IO,还有CPU,内存的瓶颈,如果多台进行分摊1T的数据,到每台上就是可估量的较小数据,在mongodb集群只要设置好分片规则,通过mongos操作数据库,就可以自动把对应的操作请求转发到对应的后端分片服务器上。
replica set
在总体mongodb集群架构中,对应的分片节点,如果单台机器下线,对应整个集群的数据就会出现部分缺失,这是不能发生的,因此对于shard节点需要replica set来保证数据的可靠性,生产环境通常为2个副本+1个仲裁

仲裁者
仲裁者(Arbiter),是复制集中的一个MongoDB实例,它并不保存数据。仲裁节点使用最小的资源并且不要求硬件设备,不能将Arbiter部署在同一个数据集节点中,可以部署在其他应用服务器或者监视服务器中,也可部署在单独的虚拟机中。为了确保复制集中有奇数的投票成员(包括primary),需要添加仲裁节点做为投票,否则primary不能运行时不会自动切换primary。

仲裁节点是一种特殊的节点,它本身并不存储数据,主要的作用是决定哪一个备节点在主节点挂掉之后提升为主节点,所以客户端不需要连接此节点。这里虽然只有一个备节点,但是仍然需要一个仲裁节点来提升备节点级别。如果没有仲裁节点的话,主节点挂了备节点还是备节点,所以咱们还是需要它的。

集群中数据分布

Chunk是什么

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第31张图片
在一个shard server内部,MongoDB还是会把数据分为chunks,每个chunk代表这个shard server内部一部分数据,chunk的产生,会有以下两个用途:

  • Splitting:当一个chunk的大小超过配置中的chunk size时,MongoDB的后台进程会把这个chunk切分成更小的chunk,从而避免chunk过大的情况
  • Balancing:在MongoDB中,balancer是一个后台进程,负责chunk的迁移,从而均衡各个shardserver的负载,系统初始1个chunk,chunk size默认值64M,生产库上选择适合业务的chunk size是最好的。mongoDB会自动拆分和迁移chunks。

chunk的特点

  • 使用chunk来存储数据
  • 集群搭建完成之后,默认开启一个chunk,大小是64M,
  • 存储需求超过64M,chunk会进行分裂,如果单位时间存储需求很大,设置更大的chunk
  • chunk会被自动均衡迁移。

chunksize的选择

  • 适合业务的chunksize是最好的。
  • chunk的分裂和迁移非常消耗IO资源;chunk分裂的时机:在插入和更新,读数据不会分裂。
  • 小的chunksize:数据均衡是迁移速度快,数据分布更均匀,数据分裂频繁,路由节点消耗更多资源。
  • 大的chunksize:数据分裂少。数据块移动集中消耗IO资源,通常100-200M

chunk分裂及迁移

随着数据的增长,其中的数据大小超过了配置的chunk size,默认是64M,则这个chunk就会分裂成两个。数据的增长会让chunk分裂得越来越多。
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第32张图片
 这时候,各个shard 上的chunk数量就会不平衡。这时候,mongos中的一个组件balancer 就会执行自动平衡。把chunk从chunk数量最多的shard节点挪动到数量最少的节点。
chunkSize对分裂及迁移的影响

  • MongoDB 默认的 chunkSize 为64MB,如无特殊需求,建议保持默认值;chunkSize 会直接影响到 chunk分裂、迁移的行为。
  • chunkSize 越小,chunk 分裂及迁移越多,数据分布越均衡;反之,chunkSize 越大,chunk分裂及迁移会更少,但可能导致数据分布不均。 chunkSize 太小,容易出现 jumbo chunk(即shardKey的某个取值出现频率很高,这些文档只能放到一个 chunk 里,无法再分裂)而无法迁移;chunkSize 越大,则可能出现 chunk内文档数太多(chunk 内文档数不能超过 250000 )而无法迁移。
  • chunk 自动分裂只会在数据写入时触发,所以如果将 chunkSize 改小,系统需要一定的时间来将chunk 分裂到指定的大小。
  • chunk 只会分裂,不会合并,所以即使将 chunkSize 改大,现有的 chunk 数量不会减少,但chunk大小会随着写入不断增长,直到达到目标大小。

数据分片

分片键shard key
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第33张图片
MongoDB中数据的分片是、以集合为基本单位的,集合中的数据通过片键(Shard key)被分成多部分。其实片键就是在集合中选一个键,用该键的值作为数据拆分的依据。
所以一个好的片键对分片至关重要。分片键必须是一个索引,通过 sh.shardCollection 会自动创建索引(前提是此集合不存在的情况下)。一个自增的分片键对写入和数据均匀分布就不是很好,因为自增的片键总会在一个分片上写入,后续达到某个阀值可能会写到别的分片。但是按自增键查询会非常高效。
随机片键对数据的均匀分布效果很好。注意尽量避免在多个分片上进行查询。在所有分片上查询,mongos会对结果进行归并排序。
 对集合进行分片时,你需要选择一个片键片键是每条记录都必须包含的,且建立了索引的单个字段或复合字段,MongoDB按照片键将数据划分到不同的数据块中,并将数据块均衡地分布到所有分片中。
  为了按照片键划分数据块,MongoDB使用基于范围的分片方式或者 基于哈希的分片方式。

注意事项

  • 分片键一经设置,不可修改,不可删除。
  • 执行了数据分片操作后,均衡器会对满足条件的数据进行拆分,这将占用实例的资源,请在业务低峰期操作
  • 分片键必须有索引。
  • 分片键大小限制512bytes。
  • 分片键用于路由查询。
  • MongoDB不接受已进行collection级分片的collection上插入分片
  • 分片键不支持空值插入

分片键分类

范围分片
MongoDB按照片键的值的范围将数据拆分为不同的块(chunk),每个块包含了一段范围内的数据
Sharded Cluster支持将单个集合的数据分散存储在多个shard上,用户可以指定根据集合内文档的某个字段即shard key来进行范围分片(range sharding)。
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第34张图片
对于基于范围的分片,MongoDB按照片键的范围把数据分成不同部分。

  • 优点: mongos可以快速定位请求需要的数据,并将请求转发到相应的Shard节点中。
  • 缺点: 可能导致数据在Shard节点上分布不均衡,容易造成读写热点,且不具备写分散性。

哈希分片
MongoDB计算单个字段的哈希值作为索引值,并以哈希值的范围将数据拆分为不同的块
  分片过程中利用哈希索引作为分片的单个键,且哈希分片的片键只能使用一个字段,而基于哈希片
键最大的好处就是保证数据在各个节点分布基本均匀

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第35张图片

对于基于哈希的分片,MongoDB计算一个字段的哈希值,并用这个哈希值来创建数据块。在使用基于哈希分片的系统中,拥有”相近”片键的文档很可能不会存储在同一个数据块中,因此数据的分离性更好一些。
  Hash分片与范围分片互补,能将文档随机的分散到各个chunk,充分的扩展写能力,弥补了范围分片的不足,但不能高效的服务范围查询,所有的范围查询要分发到后端所有的Shard才能找出满足条件的文档。

  • 优点:可以将数据更加均衡地分布在各Shard节点中,具备写分散性。
  • 缺点:不适合进行范围查询,进行范围查询时,需要将读请求分发到所有的Shard节点。

什么情况下使用分片

当您遇到如下两个问题时,您可以使用Sharded cluster来解决您的问题:

  • 存储容量受单机限制,即磁盘资源遭遇瓶颈。
  • 读写能力受单机限制,可能是CPU、内存或者网卡等资源遭遇瓶颈,导致读写能力无法扩展。

如何确定容量
当需要决定使用Sharded cluster时,到底应该部署多少个shard、多少个mongos?shard、mongos的数量归根结底是由应用需求决定:

存储型
如果您使用sharding只是解决海量数据存储问题,访问并不多。
假设单个shard能存储M(1G), 需要的存储总量是N(75G),那么您可以按照如下公式来计算实际需要的shard、mongos数量:

  • numberOfShards = N/M/0.75 (假设容量水位线为75%)
  • numberOfMongos = 2+(对访问要求不高,至少部署2个mongos做高可用即可)

计算型
如果您使用sharding是解决高并发写入(或读取)数据的问题,总的数据量其实很小。
您要部署的shard、mongos要满足读写性能需求,容量上则不是考量的重点。假设单个shard最大QPS(Query Per Second)为M,单个mongos最大QPS为Ms,需要总的QPS为Q。那么您可以按照如
下公式来计算实际需要的shard、mongos数量:

  • numberOfShards = Q/M/0.75 (假设负载水位线为75%)
  • numberOfMongos = Q/Ms/0.75

如何选择shard key
如果sharding要同时解决上述2个问题,则按需求更高的指标来预估。以上估算是基于sharded cluster里数据及请求都均匀分布的理想情况。但实际情况下,分布可能并不均衡,为了让系统的负载分布尽量均匀,就需要合理的选择shard key。

分片类型
MongoDB Sharded cluster支持2种分片方式:

  • 范围分片,通常能很好的支持基于shard key的范围查询。
  • Hash 分片,通常能将写入均衡分布到各个shard。

问题
上述2种分片策略都无法解决以下3个问题:

  • shard key取值范围太小(low cardinality),比如将数据中心作为shard key,而数据中心通常不会很多,分片的效果肯定不好。
  • shard key某个值的文档特别多,这样导致单个chunk特别大(及 jumbo chunk),会影响chunk迁移及负载均衡。
  • 根据非shardkey进行查询、更新操作都会变成scatter-gather查询,影响效率。

如何评估分片
好的shard key应该拥有如下特性:

  • key分布足够离散(sufficient cardinality)
  • 写请求均匀分布(evenly distributed write)
  • 尽量避免scatter-gather查询(targeted read)

数据分片

分片案例

我们要对我们的Blog数据进行分片,假如数据量是百万以及千万级别的数据

{ 
"title": "张三的文章", 
"by": "李四", 
"url": "http://www.baidu.com", 
"tags": [ 
"语文", 
"数学" 
],
"likes": 10000 
}

分片方案
likes范围分片
likes作为shard key,范围分片

  • 新的写入都是连续的likes,都会请求到同一个shard,写分布不均。
  • 根据 by 的查询会分散到所有shard上查询,效率低。

likes哈希分片

  • 写入能均分到多个shard。
  • 根据 by 的查询会分散到所有shard上查询,效率低。

by哈希分片
by作为shardKey,hash分片(如果ID没有明显的规则,范围分片也一样)

  • 写入能均分到多个shard。
  • 同一个 by 对应的数据无法进一步细分,只能分散到同一个chunk,会造成jumbo chunk根据 by 的查询只请求到单个shard。不足的是,请求路由到单个shard后,根据 likes 的范围查询需要全表 扫描并排序。

组合分片
(by,likes)组合起来作为shardKey,范围分片(Better)

  • 写入能均分到多个shard。
  • 同一个 by 的数据能根据 likes 进一步分散到多个chunk。
  • 根据 likes 查询时间范围的数据,能直接利用(by,likes)复合索引来完成。

开启分片

上面我们已经搭建好了三个分片集群了,但是mongos不知道该如何切分数据,也就是我们先前所说的片键,在mongodb中设置片键要做两步
开启数据库分片
开启数据库分片功能,命令很简单 enablesharding(),这里我就开启test数据库。

# 对集合所在的数据库启用分片功能 
sh.enableSharding("test")

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第36张图片
对片键的字段建立索引
分片键必须要有索引才可以,并且一个集合只能有一个分片健;

db.blog.createIndex({title:1}) 
db.blog.createIndex({"by":"hashed","likes":1}) 
db.blog.getIndexes()

因为我们要对 by 分片,索引需要对 likes 字段做升序索引
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第37张图片
指定分片键
使用如下命令可以指定分片键

sh.shardCollection(".",{ "":<value> } )

说明
:数据库名。
:集合名。
:分片的键,MongoDB将根据片键的值进行数据分片。

  • 1:表示基于范围分片,通常能很好地支持基于片键的范围查询。
  • “hashed”:表示基于哈希分片,通常能将写入均衡分布到各Shard节点中

指定集合中分片的片键,这里我就指定为 person.name 字段作分片键,并且指定使用范围分片

sh.shardCollection("test.blog", {"by":"hashed","likes":1})

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第38张图片
查看分片状态

sh.status()

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第39张图片
查看数据分布
通过该命令可以查看数据的分布

db.blog.getShardDistribution(); #可以查看数据分布

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第40张图片
我们发现现在是没有分片的,数据只在一个分片中

插入数据
我们对 blog 中设置分片键后,我们需要大量插入数据进行测试,我们插入十万条数据

调用Controller插入数据

http://localhost:8080/blog/batchAdd

查看分片情况
查看分片状态

sh.status()

我们发现负载均衡正在运行
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第41张图片
下面是具体分片的信息
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第42张图片
查看分片分布情况

db.blog.getShardDistribution()

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第43张图片

扩缩容

扩容

准备工作
创建挂载目录
我们先创建挂载目录

# 创建配置文件目录 
mkdir -p /tmp/mongo-cluster/shard4-server/conf 
# 创建数据文件目录 
mkdir -p /tmp/mongo-cluster/shard4-server/data/{1..3} 
# 创建日志文件目录 
mkdir -p /tmp/mongo-cluster/shard4-server/logs/{1..3}

在这里插入图片描述
创建密钥文件
因为集群只需要一个密钥文件,我们可以将 config-server 中的密钥文件复制过来

cp /tmp/mongo-cluster/config-server/conf/mongo.key /tmp/mongo-cluster/shard4- server/conf/

在这里插入图片描述
配置配置文件
因为有多个容器,配置文件是一样的,我们只需要创建一个配置文件,其他的容器统一读取该配置文件即可

echo " 
# 日志文件 
storage: 
# mongod 进程存储数据目录,此配置仅对 mongod 进程有效 
dbPath: /data/db 
systemLog: 
destination: file 
logAppend: true 
path: /data/logs/mongo.log 
# 网络设置 
net:
port: 27017 #端口号 
# bindIp: 127.0.0.1 #绑定ip 
replication: 
replSetName: shard4 #复制集名称是 shard2 
sharding: 
clusterRole: shardsvr # 集群角色,这里配置的角色是分片节点 
security: 
authorization: enabled #是否开启认证 
keyFile: /data/configdb/conf/mongo.key #keyFile路径 
" > /tmp/mongo-cluster/shard4-server/conf/mongo.conf 

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第44张图片

启动新分片
增加分片节点
增加shard4-server节点

version: '2' 
services: 
config-server1: 
image: mongo 
container_name: config-server1 
privileged: true 
networks: 
- mongo-cluster-network
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/config-server:/data/configdb 
- /tmp/mongo-cluster/config-server/data/1:/data/db 
- /tmp/mongo-cluster/config-server/logs/1:/data/logs 
config-server2: 
image: mongo 
container_name: config-server2 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/config-server:/data/configdb 
- /tmp/mongo-cluster/config-server/data/2:/data/db 
- /tmp/mongo-cluster/config-server/logs/2:/data/logs 
config-server3: 
image: mongo 
container_name: config-server3 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/config-server:/data/configdb 
- /tmp/mongo-cluster/config-server/data/3:/data/db 
- /tmp/mongo-cluster/config-server/logs/3:/data/logs 
shard1-server1: 
image: mongo 
container_name: shard1-server1 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard1-server:/data/configdb 
- /tmp/mongo-cluster/shard1-server/data/1:/data/db 
- /tmp/mongo-cluster/shard1-server/logs/1:/data/logs 
shard1-server2: 
image: mongo 
container_name: shard1-server2 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard1-server:/data/configdb 
- /tmp/mongo-cluster/shard1-server/data/2:/data/db 
- /tmp/mongo-cluster/shard1-server/logs/2:/data/logs
shard1-server3: 
image: mongo 
container_name: shard1-server3 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard1-server:/data/configdb 
- /tmp/mongo-cluster/shard1-server/data/3:/data/db 
- /tmp/mongo-cluster/shard1-server/logs/3:/data/logs 
shard2-server1: 
image: mongo 
container_name: shard2-server1 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard2-server:/data/configdb 
- /tmp/mongo-cluster/shard2-server/data/1:/data/db 
- /tmp/mongo-cluster/shard2-server/logs/1:/data/logs 
shard2-server2: 
image: mongo 
container_name: shard2-server2 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard2-server:/data/configdb 
- /tmp/mongo-cluster/shard2-server/data/2:/data/db 
- /tmp/mongo-cluster/shard2-server/logs/2:/data/logs 
shard2-server3: 
image: mongo 
container_name: shard2-server3 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard2-server:/data/configdb 
- /tmp/mongo-cluster/shard2-server/data/3:/data/db 
- /tmp/mongo-cluster/shard2-server/logs/3:/data/logs 
shard3-server1: 
image: mongo 
container_name: shard3-server1 
privileged: true 
networks:
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard3-server:/data/configdb 
- /tmp/mongo-cluster/shard3-server/data/1:/data/db 
- /tmp/mongo-cluster/shard3-server/logs/1:/data/logs 
shard3-server2: 
image: mongo 
container_name: shard3-server2 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard3-server:/data/configdb 
- /tmp/mongo-cluster/shard3-server/data/2:/data/db 
- /tmp/mongo-cluster/shard3-server/logs/2:/data/logs 
shard3-server3: 
image: mongo 
container_name: shard3-server3 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard3-server:/data/configdb 
- /tmp/mongo-cluster/shard3-server/data/3:/data/db 
- /tmp/mongo-cluster/shard3-server/logs/3:/data/logs 
shard4-server1: 
image: mongo 
container_name: shard4-server1 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard4-server:/data/configdb 
- /tmp/mongo-cluster/shard4-server/data/1:/data/db 
- /tmp/mongo-cluster/shard4-server/logs/1:/data/logs 
shard4-server2: 
image: mongo 
container_name: shard4-server2 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard4-server:/data/configdb 
- /tmp/mongo-cluster/shard4-server/data/2:/data/db
- /tmp/mongo-cluster/shard4-server/logs/2:/data/logs 
shard4-server3: 
image: mongo 
container_name: shard4-server3 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard4-server:/data/configdb 
- /tmp/mongo-cluster/shard4-server/data/3:/data/db 
- /tmp/mongo-cluster/shard4-server/logs/3:/data/logs 
mongos-server1: 
image: mongo 
container_name: mongos-server1 
privileged: true 
entrypoint: "mongos" 
networks: 
- mongo-cluster-network 
ports: 
- "30001:27017" 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/mongos-server:/data/configdb 
- /tmp/mongo-cluster/mongos-server/logs/1:/data/logs 
command: --config /data/configdb/conf/mongo.conf 
mongos-server2: 
image: mongo 
container_name: mongos-server2 
privileged: true 
entrypoint: "mongos" 
networks: 
- mongo-cluster-network 
ports: 
- "30002:27017" 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/mongos-server:/data/configdb 
- /tmp/mongo-cluster/mongos-server/logs/2:/data/logs 
command: --config /data/configdb/conf/mongo.conf 
mongos-server3: 
image: mongo 
container_name: mongos-server3 
privileged: true 
entrypoint: "mongos" 
networks: 
- mongo-cluster-network 
ports: 
- "30003:27017" 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/mongos-server:/data/configdb 
- /tmp/mongo-cluster/mongos-server/logs/3:/data/logs
command: --config /data/configdb/conf/mongo.conf 
networks: 
mongo-cluster-network: 
driver: bridge 

启动服务

docker-compose up -d

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第45张图片
初始化分片组
登录节点后进行初始化分片2

docker exec -it shard4-server1 bin/bash 
mongo -port 27017

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第46张图片
执行下面的命令进行初始化分片4, arbiterOnly:true 参数是设置为仲裁节点

#进行副本集配置 
rs.initiate( 
{ 
_id : "shard4", 
members: [ 
{ _id : 0, host : "shard4-server1:27017" }, 
{ _id : 1, host : "shard4-server2:27017" }, 
{ _id : 2, host : "shard4-server3:27017",arbiterOnly:true } 
] 
} 
);

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第47张图片

创建用户
因为我们需要对用户进行权限管理,我们需要创建用户,这里为了演示,我们创建超级用户 权限是 root

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

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第48张图片
添加到mongos
要将新增节点添加到mongos中
进入容器处理

docker exec -it mongos-server1 /bin/bash 
mongo -port 27017 
use admin; 
db.auth("root","root"); 
sh.addShard("shard4/shard4-server1:27017,shard4-server2:27017,shard4- 
server3:27017")

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第49张图片
查看均衡信息

db.blog.getShardDistribution()

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第50张图片
查看分片信息

sh.status()

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第51张图片

缩容

Mongodb分片集群shard节点缩容相对是比较简单的,可以利用MongoDB自身的平衡器来将预下线中的分片中存储的数据进行转移,待预下线shard节点中无任何数据库,进行下线处理。所有的下线操作通过mongos进行管理实现。
查看分片状态
查看分片集群是否开启平衡器

sh.getBalancerState();

在这里插入图片描述
删除分片
发起删除分片节点命令,平衡器开始自动迁移数据

use admin 
db.runCommand({removeshard: "shard4"})

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第52张图片
等待平衡器将需要删除的分片节点中数据全部迁移完毕

sh.status()

正在进行负载均衡
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第53张图片
查看迁移数据

sh.status()

我们发现数据已经迁移完成
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第54张图片
再次删除节点
真正从分片集群中删除shard副本集信息

use admin 
db.runCommand({removeShard:"shard4"})

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第55张图片
发现数据还在迁移,稍等,然后在执行删除命令

use admin 
db.runCommand({removeShard:"shard4"}) 

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第56张图片
这次是真正的删除了
查看集群状态
检查分片缩容后的分片集群状态

sh.status()

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第57张图片
我们发现只剩下三个节点

Mongo分片高可用集群搭建

高可用集群整体架构

整体架构涉及到15个节点,我们这里使用Docker容器进行部署
那么我们先来总结一下我们搭建一个高可用集群需要多少个Mongo
mongos: 3台
configserver : 3台
shard : 3片; 每个分片由三个节点构成

容器部署情况
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第58张图片
整体架构预览MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第59张图片

基础环境准备

安装Docker
本次使用Docker环境进行搭建,需要提前准备好Docker环境

创建Docker网络
因为需要使用Docker搭建MongoDB集群,所以先创建Docker网络

docker network create mongo-cluster 
docker network ls 

在这里插入图片描述

搭建ConfigServer副本集

我们先来搭建ConfigServer的副本集,这里面涉及到三个节点,我们需要创建配置文件以及启动容器
创建挂载目录
我们需要创建对应的挂载目录来存储配置文件以及日志文件

# 创建配置文件目录 
mkdir -p /tmp/mongo-cluster/config-server/conf 
# 创建数据文件目录 
mkdir -p /tmp/mongo-cluster/config-server/data/{1..3} 
# 创建日志文件目录 
mkdir -p /tmp/mongo-cluster/config-server/logs/{1..3}

在这里插入图片描述
创建密钥文件
因为我们知道搭建的话一定要高可用,而且一定要权限,这里mongo之间通信采用秘钥文件,所以我们先进行生成密钥文件

# 创建密钥文件 
openssl rand -base64 756 > /tmp/mongo-cluster/config-server/conf/mongo.key 
# 设置 
chmod 600 /tmp/mongo-cluster/config-server/conf/mongo.key 

在这里插入图片描述
创建配置文件
因为由多个容器,配置文件是一样的,我们只需要创建一个配置文件,其他的容器统一读取该配置文件即可

echo " 
# 日志文件 
storage: 
# mongod 进程存储数据目录,此配置仅对 mongod 进程有效 
dbPath: /data/db 
systemLog:
destination: file 
logAppend: true 
path: /data/logs/mongo.log 
# 网络设置 
net:
port: 27017 #端口号 
# bindIp: 127.0.0.1 #绑定ip 
replication: 
replSetName: configsvr #副本集名称 
sharding: 
clusterRole: configsvr # 集群角色,这里配置的角色是配置节点 
security: 
authorization: enabled #是否开启认证 
keyFile: /data/configdb/conf/mongo.key #keyFile路径 
" > /tmp/mongo-cluster/config-server/conf/mongo.conf 

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第60张图片
启动容器
启动config-server1

docker run --name config-server1 -d \ 
--net=mongo-cluster \ 
--privileged=true \ 
-v /tmp/mongo-cluster/config-server:/data/configdb \ 
-v /tmp/mongo-cluster/config-server/data/1:/data/db \ 
-v /tmp/mongo-cluster/config-server/logs/1:/data/logs \ 
mongo --config /data/configdb/conf/mongo.conf

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第61张图片
启动config-server2

docker run --name config-server2 -d \ 
--net=mongo-cluster \ 
--privileged=true \ 
-v /tmp/mongo-cluster/config-server:/data/configdb \ 
-v /tmp/mongo-cluster/config-server/data/2:/data/db \ 
-v /tmp/mongo-cluster/config-server/logs/2:/data/logs \ 
mongo --config /data/configdb/conf/mongo.conf

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第62张图片
启动config-server3

docker run --name config-server3 -d \ 
--net=mongo-cluster \ 
--privileged=true \ 
-v /tmp/mongo-cluster/config-server:/data/configdb \ 
-v /tmp/mongo-cluster/config-server/data/3:/data/db \ 
-v /tmp/mongo-cluster/config-server/logs/3:/data/logs \ 
mongo --config /data/configdb/conf/mongo.conf

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第63张图片
初始化config-server
登录容器
进入第一台容器

docker exec -it config-server1 bash 
mongo -port 27017 

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第64张图片
执行命令
执行以下命令进行MongoDB容器的初始化

rs.initiate( 
{ 
_id: "configsvr", 
members: [ 
{ _id : 1, host : "config-server1:27017" }, 
{ _id : 2, host : "config-server2:27017" }, 
{ _id : 3, host : "config-server3:27017" } 
] 
} 
)

如果出现 OK 表示MongoDB配置服务器已经初始化成功
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第65张图片
创建用户
因为我们需要对用户进行权限管理,我们需要创建用户,这里为了演示,我们创建超级用户 权限是 root

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

这样就在MongoDB的 admin 数据库添加了一个用户名为root 密码是root的用户
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第66张图片

搭建Shard分片组

由于mongos是客户端,所以我们先搭建好config以及shard之后再搭建mongos。
创建挂载目录
我们先创建挂载目录

# 创建配置文件目录 
mkdir -p /tmp/mongo-cluster/shard{1..3}-server/conf 
# 创建数据文件目录 
mkdir -p /tmp/mongo-cluster/shard{1..3}-server/data/{1..3} 
# 创建日志文件目录 
mkdir -p /tmp/mongo-cluster/shard{1..3}-server/logs/{1..3} 

在这里插入图片描述
搭建shard1分片组
在同一台服务器上初始化一组分片
创建密钥文件
因为集群只需要一个密钥文件,我们可以将 config-server 中的密钥文件复制过来

cp /tmp/mongo-cluster/config-server/conf/mongo.key /tmp/mongo-cluster/shard1- 
server/conf/

在这里插入图片描述
配置配置文件
因为有多个容器,配置文件是一样的,我们只需要创建一个配置文件,其他的容器统一读取该配置文件即可

echo " 
# 日志文件 
storage: 
# mongod 进程存储数据目录,此配置仅对 mongod 进程有效 
dbPath: /data/db 
systemLog: 
destination: file 
logAppend: true 
path: /data/logs/mongo.log 
# 网络设置 
net:
port: 27017 #端口号 
# bindIp: 127.0.0.1 #绑定ip 
replication: 
replSetName: shard1 #复制集名称是 shardsvr 
sharding: 
clusterRole: shardsvr # 集群角色,这里配置的角色是分片节点 
security: 
authorization: enabled #是否开启认证 
keyFile: /data/configdb/conf/mongo.key #keyFile路径 
" > /tmp/mongo-cluster/shard1-server/conf/mongo.conf 

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第67张图片
启动shard1-server1

docker run --name shard1-server1 -d \ 
--net=mongo-cluster \ 
--privileged=true \ 
-v /tmp/mongo-cluster/shard1-server:/data/configdb \ 
-v /tmp/mongo-cluster/shard1-server/data/1:/data/db \ 
-v /tmp/mongo-cluster/shard1-server/logs/1:/data/logs \ 
mongo --config /data/configdb/conf/mongo.conf

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第68张图片
启动shard1-server2

docker run --name shard1-server2 -d \ 
--net=mongo-cluster \ 
--privileged=true \ 
-v /tmp/mongo-cluster/shard1-server:/data/configdb \ 
-v /tmp/mongo-cluster/shard1-server/data/2:/data/db \ 
-v /tmp/mongo-cluster/shard1-server/logs/2:/data/logs \ 
mongo --config /data/configdb/conf/mongo.conf

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第69张图片
启动shard1-server3
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第70张图片
初始化shard1分片组
并且制定第三个副本集为仲裁节点

docker exec -it shard1-server1 bin/bash 
mongo -port 27017 

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第71张图片
登录后进行初始化节点,这里面 arbiterOnly:true 是设置为仲裁节点

#进行副本集配置 
rs.initiate( 
{ 
_id : "shard1", 
members: [ 
{ _id : 0, host : "shard1-server1:27017" }, 
{ _id : 1, host : "shard1-server2:27017" }, 
{ _id : 2, host : "shard1-server3:27017",arbiterOnly:true } 
] 
} 
);

显示OK即副本集创建成功
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第72张图片
创建用户
因为我们需要对用户进行权限管理,我们需要创建用户,这里为了演示,我们创建超级用户 权限是 root

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

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第73张图片
查看节点信息

rs.isMaster()

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第74张图片
搭建shard2分片组
创建密钥文件
因为集群只需要一个密钥文件,我们可以将 config-server 中的密钥文件复制过来

cp /tmp/mongo-cluster/config-server/conf/mongo.key /tmp/mongo-cluster/shard2- 
server/conf/ 

在这里插入图片描述
配置配置文件
因为有多个容器,配置文件是一样的,我们只需要创建一个配置文件,其他的容器统一读取该配置文件即可

echo " 
# 日志文件 
storage: 
# mongod 进程存储数据目录,此配置仅对 mongod 进程有效 
dbPath: /data/db 
systemLog: 
destination: file 
logAppend: true 
path: /data/logs/mongo.log 
# 网络设置 
net:
port: 27017 #端口号 
# bindIp: 127.0.0.1 #绑定ip 
replication: 
replSetName: shard2 #复制集名称是 shard2 
sharding: 
clusterRole: shardsvr # 集群角色,这里配置的角色是分片节点 
security: 
authorization: enabled #是否开启认证 
keyFile: /data/configdb/conf/mongo.key #keyFile路径 
" > /tmp/mongo-cluster/shard2-server/conf/mongo.conf

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第75张图片
启动shard2-server1

docker run --name shard2-server1 -d \ 
--net=mongo-cluster \ 
--privileged=true \ 
-v /tmp/mongo-cluster/shard2-server:/data/configdb \ 
-v /tmp/mongo-cluster/shard2-server/data/1:/data/db \ 
-v /tmp/mongo-cluster/shard2-server/logs/1:/data/logs \ 
mongo --config /data/configdb/conf/mongo.conf 

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第76张图片
启动shard2-server2

docker run --name shard2-server2 -d \ 
--net=mongo-cluster \ 
--privileged=true \ 
-v /tmp/mongo-cluster/shard2-server:/data/configdb \ 
-v /tmp/mongo-cluster/shard2-server/data/2:/data/db \ 
-v /tmp/mongo-cluster/shard2-server/logs/2:/data/logs \ 
mongo --config /data/configdb/conf/mongo.conf

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第77张图片
启动shard2-server3

docker run --name shard2-server3 -d \ 
--net=mongo-cluster \ 
--privileged=true \ 
-v /tmp/mongo-cluster/shard2-server:/data/configdb \ 
-v /tmp/mongo-cluster/shard2-server/data/3:/data/db \ 
-v /tmp/mongo-cluster/shard2-server/logs/3:/data/logs \ 
mongo --config /data/configdb/conf/mongo.conf

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第78张图片
初始化shard2分片组
登录节点后进行初始化分片2

docker exec -it shard2-server1 bin/bash 
mongo -port 27017

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第79张图片
执行下面的命令进行初始化分片2, arbiterOnly:true 参数是设置为仲裁节点

#进行副本集配置 
rs.initiate( 
{ 
_id : "shard2", 
members: [ 
{ _id : 0, host : "shard2-server1:27017" }, 
{ _id : 1, host : "shard2-server2:27017" }, 
{ _id : 2, host : "shard2-server3:27017",arbiterOnly:true } 
] 
} 
);

返回 ok 就表示
MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第80张图片
创建用户
因为我们需要对用户进行权限管理,我们需要创建用户,这里为了演示,我们创建超级用户 权限是 root

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

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第81张图片

搭建shard3分片组
创建密钥文件
因为集群只需要一个密钥文件,我们可以将 config-server 中的密钥文件复制过来

cp /tmp/mongo-cluster/config-server/conf/mongo.key /tmp/mongo-cluster/shard3- server/conf/

在这里插入图片描述
配置配置文件
因为有多个容器,配置文件是一样的,我们只需要创建一个配置文件,其他的容器统一读取该配置文件即可

echo " 
# 日志文件 
storage: 
# mongod 进程存储数据目录,此配置仅对 mongod 进程有效 
dbPath: /data/db 
systemLog: 
destination: file 
logAppend: true 
path: /data/logs/mongo.log 
# 网络设置 
net:
port: 27017 #端口号 
# bindIp: 127.0.0.1 #绑定ip 
replication: 
replSetName: shard3 #复制集名称是 shard3 
sharding: 
clusterRole: shardsvr # 集群角色,这里配置的角色是分片节点 
security: 
authorization: enabled #是否开启认证 
keyFile: /data/configdb/conf/mongo.key #keyFile路径 
" > /tmp/mongo-cluster/shard3-server/conf/mongo.conf

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第82张图片
启动shard3-server1

docker run --name shard3-server1 -d \ 
--net=mongo-cluster \ 
--privileged=true \ 
-v /tmp/mongo-cluster/shard3-server:/data/configdb \ 
-v /tmp/mongo-cluster/shard3-server/data/1:/data/db \ 
-v /tmp/mongo-cluster/shard3-server/logs/1:/data/logs \ 
mongo --config /data/configdb/conf/mongo.conf 

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第83张图片
启动shard3-server2

docker run --name shard3-server2 -d \ 
--net=mongo-cluster \ 
--privileged=true \ 
-v /tmp/mongo-cluster/shard3-server:/data/configdb \ 
-v /tmp/mongo-cluster/shard3-server/data/2:/data/db \ 
-v /tmp/mongo-cluster/shard3-server/logs/2:/data/logs \ 
mongo --config /data/configdb/conf/mongo.conf 

启动shard3-server3

docker run --name shard3-server3 -d \ 
--net=mongo-cluster \ 
--privileged=true \ 
-v /tmp/mongo-cluster/shard3-server:/data/configdb \ 
-v /tmp/mongo-cluster/shard3-server/data/3:/data/db \ 
-v /tmp/mongo-cluster/shard3-server/logs/3:/data/logs \ 
mongo --config /data/configdb/conf/mongo.conf

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第84张图片
初始化shard3分片组
登录节点后进行初始化分片2

docker exec -it shard3-server1 bin/bash 
mongo -port 27017

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第85张图片
执行下面的命令进行初始化分片3, arbiterOnly:true 参数是设置为仲裁节点

#进行副本集配置 
rs.initiate( 
{ 
_id : "shard3", 
members: [ 
{ _id : 0, host : "shard3-server1:27017" }, 
{ _id : 1, host : "shard3-server2:27017" }, 
{ _id : 2, host : "shard3-server3:27017",arbiterOnly:true } 
] 
} 
);

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第86张图片
创建用户
因为我们需要对用户进行权限管理,我们需要创建用户,这里为了演示,我们创建超级用户 权限是 root

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

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第87张图片

搭建Mongos

mongos负责查询与数据写入的路由,是实例访问的统一入口,是一个无状态的节点,每一个节点都可以从 config-server 节点获取到配置信息

创建挂载目录
我们需要创建对应的挂载目录来存储配置文件以及日志文件

# 创建配置文件目录 
mkdir -p /tmp/mongo-cluster/mongos-server/conf 
# 创建数据文件目录 
mkdir -p /tmp/mongo-cluster/mongos-server/data/{1..3} 
# 创建日志文件目录 
mkdir -p /tmp/mongo-cluster/mongos-server/logs/{1..3} 

在这里插入图片描述创建密钥文件
因为集群只需要一个密钥文件,我们可以将 config-server 中的密钥文件复制过来

cp /tmp/mongo-cluster/config-server/conf/mongo.key /tmp/mongo-cluster/mongos- 
server/conf/ 

在这里插入图片描述
创建配置文件
因为有多个容器,配置文件是一样的,我们只需要创建一个配置文件,其他的容器统一读取该配置文件即可,因为Mongos只负责路由,就不需要数据文件了,并且mongos服务是不负责认证的,需要将 authorization 配置项删除

echo " 
# 日志文件 
systemLog: 
destination: file 
logAppend: true 
path: /data/logs/mongo.log 
# 网络设置 
net:
port: 27017 #端口号 
# bindIp: 127.0.0.1 #绑定ip 
# 配置分片,这里面配置的是需要读取的配置节点的信息 
sharding: 
configDB: configsvr/config-server1:27017,config-server2:27017,config- 
server3:27017
security: 
keyFile: /data/configdb/conf/mongo.key #keyFile路径 
" > /tmp/mongo-cluster/mongos-server/conf/mongo.conf 

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第88张图片
启动mongos集群
启动mongos1

docker run --name mongos-server1 -d \ 
-p 30001:27017 \ 
--net=mongo-cluster \ 
--privileged=true \ 
--entrypoint "mongos" \ 
-v /tmp/mongo-cluster/mongos-server:/data/configdb \ 
-v /tmp/mongo-cluster/mongos-server/logs/1:/data/logs \ 
mongo --config /data/configdb/conf/mongo.conf 

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第89张图片
启动mongos2

docker run --name mongos-server2 -d \ 
-p 30002:27017 \ 
--net=mongo-cluster \ 
--privileged=true \ 
--entrypoint "mongos" \ 
-v /tmp/mongo-cluster/mongos-server:/data/configdb \ 
-v /tmp/mongo-cluster/mongos-server/logs/2:/data/logs \ 
mongo --config /data/configdb/conf/mongo.conf

启动mongos3

docker run --name mongos-server3 -d \ 
-p 30003:27017 \ 
--net=mongo-cluster \ 
--privileged=true \ 
--entrypoint "mongos" \ 
-v /tmp/mongo-cluster/mongos-server:/data/configdb \ 
-v /tmp/mongo-cluster/mongos-server/logs/3:/data/logs \ 
mongo --config /data/configdb/conf/mongo.conf 


配置mongos-server1
因为 mongos 是无中心的配置,所有需要每一台都需要进行分片配置
进入容器

docker exec -it mongos-server1 /bin/bash 
mongo -port 27017

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第90张图片
登录Mongos
使用前面设置的root用户密码

use admin; 
db.auth("root","root");

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第91张图片
配置分片
进行配置分片信息

sh.addShard("shard1/shard1-server1:27017,shard1-server2:27017,shard1- 
server3:27017") 
sh.addShard("shard2/shard2-server1:27017,shard2-server2:27017,shard2- 
server3:27017") 
sh.addShard("shard3/shard3-server1:27017,shard3-server2:27017,shard3- 
server3:27017")

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第92张图片

配置mongos-server2

docker exec -it mongos-server2 /bin/bash 
mongo -port 27017
use admin; 
db.auth("root","root");
sh.addShard("shard1/shard1-server1:27017,shard1-server2:27017,shard1- 
server3:27017") 
sh.addShard("shard2/shard2-server1:27017,shard2-server2:27017,shard2- 
server3:27017") 
sh.addShard("shard3/shard3-server1:27017,shard3-server2:27017,shard3- 
server3:27017")

配置mongos-server2

docker exec -it mongos-server3 /bin/bash 
mongo -port 27017
use admin; 
db.auth("root","root");
sh.addShard("shard1/shard1-server1:27017,shard1-server2:27017,shard1- 
server3:27017") 
sh.addShard("shard2/shard2-server1:27017,shard2-server2:27017,shard2- 
server3:27017") 
sh.addShard("shard3/shard3-server1:27017,shard3-server2:27017,shard3- 
server3:27017")

Docker-compose方式搭建

环境准备
初始化目录脚本

# 创建config-server 目录 
# 创建配置文件目录 
mkdir -p /tmp/mongo-cluster/config-server/conf 
# 创建数据文件目录 
mkdir -p /tmp/mongo-cluster/config-server/data/{1..3} 
# 创建日志文件目录 
mkdir -p /tmp/mongo-cluster/config-server/logs/{1..3} 
# 创建shard-server 目录 
# 创建配置文件目录 
mkdir -p /tmp/mongo-cluster/shard{1..3}-server/conf 
# 创建数据文件目录 
mkdir -p /tmp/mongo-cluster/shard{1..3}-server/data/{1..3} 
# 创建日志文件目录 
mkdir -p /tmp/mongo-cluster/shard{1..3}-server/logs/{1..3} 
# 创建mongos-server 目录 
# 创建配置文件目录 
mkdir -p /tmp/mongo-cluster/mongos-server/conf 
# 创建数据文件目录 
mkdir -p /tmp/mongo-cluster/mongos-server/data/{1..3} 
# 创建日志文件目录 
mkdir -p /tmp/mongo-cluster/mongos-server/logs/{1..3}

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第93张图片
生成密钥文件

# 创建密钥文件 
openssl rand -base64 756 > /tmp/mongo-cluster/config-server/conf/mongo.key 
# 设置 
chmod 600 /tmp/mongo-cluster/config-server/conf/mongo.key 
cp /tmp/mongo-cluster/config-server/conf/mongo.key /tmp/mongo-cluster/shard1- 
server/conf/ 
cp /tmp/mongo-cluster/config-server/conf/mongo.key /tmp/mongo-cluster/shard2- 
server/conf/ 
cp /tmp/mongo-cluster/config-server/conf/mongo.key /tmp/mongo-cluster/shard3- 
server/conf/ 
cp /tmp/mongo-cluster/config-server/conf/mongo.key /tmp/mongo-cluster/mongos- 
server/conf/ 

在这里插入图片描述
创建配置文件

echo " 
# 日志文件 
storage: 
# mongod 进程存储数据目录,此配置仅对 mongod 进程有效 
dbPath: /data/db 
systemLog: 
destination: file 
logAppend: true 
path: /data/logs/mongo.log 
# 网络设置 
net:
port: 27017 #端口号 
# bindIp: 127.0.0.1 #绑定ip 
replication: 
replSetName: configsvr #副本集名称 
sharding: 
clusterRole: configsvr # 集群角色,这里配置的角色是配置节点 
security: 
authorization: enabled #是否开启认证 
keyFile: /data/configdb/conf/mongo.key #keyFile路径 
" > /tmp/mongo-cluster/config-server/conf/mongo.conf 
echo " 
# 日志文件 
storage: 
# mongod 进程存储数据目录,此配置仅对 mongod 进程有效 
dbPath: /data/db 
systemLog: 
destination: file 
logAppend: true
path: /data/logs/mongo.log 
# 网络设置 
net:
port: 27017 #端口号 
# bindIp: 127.0.0.1 #绑定ip 
replication: 
replSetName: shard1 #复制集名称是 shardsvr 
sharding: 
clusterRole: shardsvr # 集群角色,这里配置的角色是分片节点 
security: 
authorization: enabled #是否开启认证 
keyFile: /data/configdb/conf/mongo.key #keyFile路径 
" > /tmp/mongo-cluster/shard1-server/conf/mongo.conf 
echo " 
# 日志文件 
storage: 
# mongod 进程存储数据目录,此配置仅对 mongod 进程有效 
dbPath: /data/db 
systemLog: 
destination: file 
logAppend: true 
path: /data/logs/mongo.log 
# 网络设置 
net:
port: 27017 #端口号 
# bindIp: 127.0.0.1 #绑定ip 
replication: 
replSetName: shard2 #复制集名称是 shard2 
sharding: 
clusterRole: shardsvr # 集群角色,这里配置的角色是分片节点 
security: 
authorization: enabled #是否开启认证 
keyFile: /data/configdb/conf/mongo.key #keyFile路径 
" > /tmp/mongo-cluster/shard2-server/conf/mongo.conf 
echo " 
# 日志文件 
storage: 
# mongod 进程存储数据目录,此配置仅对 mongod 进程有效 
dbPath: /data/db 
systemLog: 
destination: file 
logAppend: true 
path: /data/logs/mongo.log 
# 网络设置 
net:
port: 27017 #端口号 
# bindIp: 127.0.0.1 #绑定ip 
replication: 
replSetName: shard3 #复制集名称是 shard3 
sharding:
clusterRole: shardsvr # 集群角色,这里配置的角色是分片节点 
security: 
authorization: enabled #是否开启认证 
keyFile: /data/configdb/conf/mongo.key #keyFile路径 
" > /tmp/mongo-cluster/shard3-server/conf/mongo.conf 
echo " 
# 日志文件 
systemLog: 
destination: file 
logAppend: true 
path: /data/logs/mongo.log 
# 网络设置 
net:
port: 27017 #端口号 
bindIp: 0.0.0.0 #绑定ip 
# 配置分片,这里面配置的是需要读取的配置节点的信息 
sharding: 
configDB: configsvr/config-server1:27017,config-server2:27017,config- 
server3:27017 
security: 
keyFile: /data/configdb/conf/mongo.key #keyFile路径 
" > /tmp/mongo-cluster/mongos-server/conf/mongo.conf 

启动服务

docker-compos配置文件
使用docker-compos方式启动Docker容器

version: '2' 
services: 
config-server1: 
image: mongo 
container_name: config-server1 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/config-server:/data/configdb 
- /tmp/mongo-cluster/config-server/data/1:/data/db 
- /tmp/mongo-cluster/config-server/logs/1:/data/logs 
config-server2: 
image: mongo 
container_name: config-server2 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/config-server:/data/configdb
- /tmp/mongo-cluster/config-server/data/2:/data/db 
- /tmp/mongo-cluster/config-server/logs/2:/data/logs 
config-server3: 
image: mongo 
container_name: config-server3 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/config-server:/data/configdb 
- /tmp/mongo-cluster/config-server/data/3:/data/db 
- /tmp/mongo-cluster/config-server/logs/3:/data/logs 
shard1-server1: 
image: mongo 
container_name: shard1-server1 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard1-server:/data/configdb 
- /tmp/mongo-cluster/shard1-server/data/1:/data/db 
- /tmp/mongo-cluster/shard1-server/logs/1:/data/logs 
shard1-server2: 
image: mongo 
container_name: shard1-server2 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard1-server:/data/configdb 
- /tmp/mongo-cluster/shard1-server/data/2:/data/db 
- /tmp/mongo-cluster/shard1-server/logs/2:/data/logs 
shard1-server3: 
image: mongo 
container_name: shard1-server3 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard1-server:/data/configdb 
- /tmp/mongo-cluster/shard1-server/data/3:/data/db 
- /tmp/mongo-cluster/shard1-server/logs/3:/data/logs 
shard2-server1: 
image: mongo 
container_name: shard2-server1
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard2-server:/data/configdb 
- /tmp/mongo-cluster/shard2-server/data/1:/data/db 
- /tmp/mongo-cluster/shard2-server/logs/1:/data/logs 
shard2-server2: 
image: mongo 
container_name: shard2-server2 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard2-server:/data/configdb 
- /tmp/mongo-cluster/shard2-server/data/2:/data/db 
- /tmp/mongo-cluster/shard2-server/logs/2:/data/logs 
shard2-server3: 
image: mongo 
container_name: shard2-server3 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard2-server:/data/configdb 
- /tmp/mongo-cluster/shard2-server/data/3:/data/db 
- /tmp/mongo-cluster/shard2-server/logs/3:/data/logs 
shard3-server1: 
image: mongo 
container_name: shard3-server1 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard3-server:/data/configdb 
- /tmp/mongo-cluster/shard3-server/data/1:/data/db 
- /tmp/mongo-cluster/shard3-server/logs/1:/data/logs 
shard3-server2: 
image: mongo 
container_name: shard3-server2 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime
- /tmp/mongo-cluster/shard3-server:/data/configdb 
- /tmp/mongo-cluster/shard3-server/data/2:/data/db 
- /tmp/mongo-cluster/shard3-server/logs/2:/data/logs 
shard3-server3: 
image: mongo 
container_name: shard3-server3 
privileged: true 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/shard3-server:/data/configdb 
- /tmp/mongo-cluster/shard3-server/data/3:/data/db 
- /tmp/mongo-cluster/shard3-server/logs/3:/data/logs 
mongos-server1: 
image: mongo 
container_name: mongos-server1 
privileged: true 
entrypoint: "mongos" 
networks: 
- mongo-cluster-network 
command: --config /data/configdb/conf/mongo.conf 
ports: 
- "30001:27017" 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/mongos-server:/data/configdb 
- /tmp/mongo-cluster/mongos-server/logs/1:/data/logs 
command: --config /data/configdb/conf/mongo.conf 
mongos-server2: 
image: mongo 
container_name: mongos-server2 
privileged: true 
entrypoint: "mongos" 
networks: 
- mongo-cluster-network 
ports: 
- "30002:27017" 
volumes: 
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/mongos-server:/data/configdb 
- /tmp/mongo-cluster/mongos-server/logs/2:/data/logs 
command: --config /data/configdb/conf/mongo.conf 
mongos-server3: 
image: mongo 
container_name: mongos-server3 
privileged: true 
entrypoint: "mongos" 
networks: 
- mongo-cluster-network 
ports: 
- "30003:27017" 
volumes:
- /etc/localtime:/etc/localtime 
- /tmp/mongo-cluster/mongos-server:/data/configdb 
- /tmp/mongo-cluster/mongos-server/logs/3:/data/logs 
command: --config /data/configdb/conf/mongo.conf 
networks: 
mongo-cluster-network: 
driver: bridge 

启动服务

docker-compose up -d

MongoDB集群搭建与管理(集群搭建 分片 扩缩容 搭建高可用集群)_第94张图片
初始化文件
执行下面脚本进行容器初始化

docker exec -it config-server1 bash 
mongo -port 27017 
rs.initiate( 
{ 
_id: "configsvr", 
members: [ 
{ _id : 1, host : "config-server1:27017" }, 
{ _id : 2, host : "config-server2:27017" }, 
{ _id : 3, host : "config-server3:27017" } 
] 
} 
)
use admin 
db.createUser({user:"root",pwd:"root",roles:[{role:'root',db:'admin'}]}) 
db.auth("root","root") 
db.createUser({user:"test",pwd:"test",roles:[{role:'readWrite',db:'test'}]}) 
docker exec -it shard1-server1 bin/bash 
mongo -port 27017 
#进行副本集配置 
rs.initiate( 
{ 
_id : "shard1", 
members: [
{ _id : 0, host : "shard1-server1:27017" }, 
{ _id : 1, host : "shard1-server2:27017" }, 
{ _id : 2, host : "shard1-server3:27017",arbiterOnly:true } 
] 
} 
);
use admin 
db.createUser({user:"root",pwd:"root",roles:[{role:'root',db:'admin'}]}) 
db.auth("root","root") 
db.createUser({user:"test",pwd:"test",roles:[{role:'readWrite',db:'test'}]}) 
docker exec -it shard2-server1 bin/bash 
mongo -port 27017 
#进行副本集配置 
rs.initiate( 
{ 
_id : "shard2", 
members: [ 
{ _id : 0, host : "shard2-server1:27017" }, 
{ _id : 1, host : "shard2-server2:27017" }, 
{ _id : 2, host : "shard2-server3:27017",arbiterOnly:true } 
] 
} 
);
use admin 
db.createUser({user:"root",pwd:"root",roles:[{role:'root',db:'admin'}]}) 
db.auth("root","root") 
db.createUser({user:"test",pwd:"test",roles:[{role:'readWrite',db:'test'}]}) 
docker exec -it shard3-server1 bin/bash 
mongo -port 27017 
#进行副本集配置 
rs.initiate( 
{ 
_id : "shard3", 
members: [ 
{ _id : 0, host : "shard3-server1:27017" }, 
{ _id : 1, host : "shard3-server2:27017" }, 
{ _id : 2, host : "shard3-server3:27017",arbiterOnly:true } 
] 
} 
);
use admin 
db.createUser({user:"root",pwd:"root",roles:[{role:'root',db:'admin'}]}) 
db.auth("root","root") 
db.createUser({user:"test",pwd:"test",roles:[{role:'readWrite',db:'test'}]}) 

初始化分片

docker exec -it mongos-server1 /bin/bash 
mongo -port 27017 
use admin; 
db.auth("root","root"); 
sh.addShard("shard1/shard1-server1:27017,shard1-server2:27017,shard1- 
server3:27017")
sh.addShard("shard2/shard2-server1:27017,shard2-server2:27017,shard2- 
server3:27017") 
sh.addShard("shard3/shard3-server1:27017,shard3-server2:27017,shard3- 
server3:27017") 
docker exec -it mongos-server2 /bin/bash 
mongo -port 27017 
use admin; 
db.auth("root","root"); 
sh.addShard("shard1/shard1-server1:27017,shard1-server2:27017,shard1- 
server3:27017") 
sh.addShard("shard2/shard2-server1:27017,shard2-server2:27017,shard2- 
server3:27017") 
sh.addShard("shard3/shard3-server1:27017,shard3-server2:27017,shard3- 
server3:27017") 
docker exec -it mongos-server3 /bin/bash 
mongo -port 27017 
use admin; 
db.auth("root","root"); 
sh.addShard("shard1/shard1-server1:27017,shard1-server2:27017,shard1- 
server3:27017") 
sh.addShard("shard2/shard2-server1:27017,shard2-server2:27017,shard2- 
server3:27017") 
sh.addShard("shard3/shard3-server1:27017,shard3-server2:27017,shard3- 
server3:27017")

你可能感兴趣的:(MongoDB,mongodb,集群搭建,分片,扩缩容,高可用)