MongoDB Sharding Cluster 分片集群

MongoDB Sharding Cluster 分片集群

1、分片(sharding)是MongoDB将大型集合分割到不同服务器(或者说多个集群)上的方法。和MySQL分区相比,MongoDB的几乎能自动完成所有事情,只要告诉MongoDB要分配数据,它就能自动维护数据在不同服务器之间的均衡

2、分片的目的

大数据量和吞吐量的数据库应用会对单机的性能造成较大压力,大查询量会增大单机的CPU和存储压力。为了解决这些问题,有两个方法:垂直扩展和水平扩展。

垂直扩展:增加更多的CPU和存储资源来扩展容量。

水平扩展:将数据集分布在多个服务器上,即分片。

3、分片机制提供了如下三种优势

1)对集群进行抽象,让集群“不可见”。

MongoDB自带了叫做mongos的专有路由进程。mongos就是掌握统一路口的路由器,其会将客户端发来的请求准确无误的路由到集群中的一个或者一组服务器上,同时会把接收到的响应拼装起来发回到客户端。

2)保证集群总是可读写

MongoDB通过多种途径来确保集群的可用性和可靠性。将MongoDB的分片和复制功能结合使用,在确保数据分片到多台服务器的同时,也确保了每份数据都有相应的备份,这样就可以确保有服务器坏掉时,其他的从库可以立即接替坏掉的部分继续工作。

3)使集群易于扩展

当系统需要更多的空间和资源的时候, MongoDB使我们可以按需方便的扩充系统容量。

4、分片集群的构造

1)mongos :数据路由,和客户端打交道的模块。

mongos本身没有任何数据,他也不知道该怎么处理这些数据,去找config server。

2)Config server:所有存、取数据的方式,所有shard节点的信息,分片功能一些配置信息。可以理解为真实数据的元数据。

3)shard:真正的数据存储位置,以chunk为单位存数据(64M)。

Mongos本身并不持久化数据,Sharded cluster所有的元数据都会存储到Config Server,而用户的数据会分散存储到各个shard。

Mongos启动后,会从配置服务器加载元数据,开始提供服务,将用户的请求正确路由到对应的碎片。

MongoDB官方参考文档:https://www.mongodb.com/zh-cn/docs/manual/

实验环境

安装好MongoDB

实验步骤

规划:
10个实例:38017-38026

1)shard节点:

sh1:38021-23 (1主两从,其中一个节点为arbiter,复制集名字sh1)

sh2:38024-26 (1主两从,其中一个节点为arbiter,复制集名字sh2)

2)Config server:

3台构成的复制集(1主两从,不支持arbiter)38018-38020(复制集名字configsvr)

3)mongos: 路由节点

1台服务器或一组复制集 38017

配置过程:

1、shard复制集配置

1)创建多实例目录

su - mongod

mkdir -p /mongodb/380{21..26}/{conf,log,data}

2)创建配置文件

sh1

cat > /mongodb/38021/conf/mongodb.conf<<EOF

systemLog:

  destination: file

  path: /mongodb/38021/log/mongodb.log  

  logAppend: true

storage:

  journal:

    enabled: true

  dbPath: /mongodb/38021/data

  directoryPerDB: true

  #engine: wiredTiger

  wiredTiger:

    engineConfig:

      cacheSizeGB: 1

      directoryForIndexes: true

    collectionConfig:

      blockCompressor: zlib

    indexConfig:

      prefixCompression: true

net:

  bindIp: 192.168.8.5,127.0.0.1

  port: 38021

replication:

  oplogSizeMB: 2048

  replSetName: sh1

sharding:

  clusterRole: shardsvr

processManagement:

  fork: true

EOF

cp /mongodb/38021/conf/mongodb.conf /mongodb/38022/conf/

cp /mongodb/38021/conf/mongodb.conf /mongodb/38023/conf/

sed -i 's#38021#38022#g' /mongodb/38022/conf/mongodb.conf

sed -i 's#38021#38023#g' /mongodb/38023/conf/mongodb.conf

sh2

cat > /mongodb/38024/conf/mongodb.conf<<EOF

systemLog:

  destination: file

  path: /mongodb/38024/log/mongodb.log  

  logAppend: true

storage:

  journal:

    enabled: true

  dbPath: /mongodb/38024/data

  directoryPerDB: true

  wiredTiger:

    engineConfig:

      cacheSizeGB: 1

      directoryForIndexes: true

    collectionConfig:

      blockCompressor: zlib

    indexConfig:

      prefixCompression: true

net:

  bindIp: 192.168.8.5,127.0.0.1

  port: 38024

replication:

  oplogSizeMB: 2048

  replSetName: sh2

sharding:

  clusterRole: shardsvr

processManagement:

  fork: true

EOF

cp /mongodb/38024/conf/mongodb.conf /mongodb/38025/conf/

cp /mongodb/38024/conf/mongodb.conf /mongodb/38026/conf/

sed -i 's#38024#38025#g' /mongodb/38025/conf/mongodb.conf

sed -i 's#38024#38026#g' /mongodb/38026/conf/mongodb.conf

配置文件解释:

logAppend: true ——在MongoDB的配置文件中表示日志文件采用追加模式,而不是覆盖模式。

directoryPerDB ——用于控制数据库文件的存储方式。当设置为

true时,每个数据库的数据文件将存储在一个单独的目录中;当设置为false时,所有数据库的数据文件将存储在同一个目录中。

WiredTiger ——是一个高性能、多核扩展性强、支持事务的存储引擎,由MongoDB从3.2版本开始默认使用。

prefixCompression(前缀压缩) ——是一种数据压缩技术,通过存储词项间的共同前缀来减少冗余。例如,对于词项[“compression”, “compressed”, “compressor”],可以存储为[“compression”, “7ed”, “7or”],其中7表示前7个字符相同。

前缀压缩在数据库和索引设计中有着重要的应用。例如,在SQL Server中,前缀压缩可以用于优化存储和查询性能。通过减少存储空间和提高数据加载速度,前缀压缩能够显著提升数据库的整体性能。此外,前缀压缩还可以应用于MongoDB等分布式存储引擎中,帮助优化存储效率和查询性能。

fork ——MongoDB会在后台运行,并且创建一个子进程。

3)启动所有实例节点

mongod -f  /mongodb/38021/conf/mongodb.conf

mongod -f  /mongodb/38022/conf/mongodb.conf

mongod -f  /mongodb/38023/conf/mongodb.conf

mongod -f  /mongodb/38024/conf/mongodb.conf

mongod -f  /mongodb/38025/conf/mongodb.conf

mongod -f  /mongodb/38026/conf/mongodb.conf

netstat -anpt | grep mongod

4)搭建复制集

sh1

mongo -port 38021 admin

config = {_id: 'sh1', members: [

{_id: 0, host: '192.168.8.5:38021'},

{_id: 1, host: '192.168.8.5:38022'},

{_id: 2, host: '192.168.8.5:38023',"arbiterOnly":true}]

}

初始化副本集

rs.initiate(config)

输入命令前面变成复制集的状态,一开始是SECONARY等待变成PRIMARY

sh2

mongo -port 38024 admin

config = {_id: 'sh2', members: [

{_id: 0, host: '192.168.8.5:38024'},

{_id: 1, host: '192.168.8.5:38025'},

{_id: 2, host: '192.168.8.5:38026',"arbiterOnly":true}]

}

初始化副本集

rs.initiate(config)

输入命令前面变成复制集的状态,一开始是SECONARY等待变成PRIMARY

2、config节点配置

1)创建多实例目录

mkdir -p /mongodb/380{18..20}/{conf,log,data}

2)创建配置文件

cat > /mongodb/38018/conf/mongodb.conf <<EOF

systemLog:

  destination: file

  path: /mongodb/38018/log/mongodb.conf

  logAppend: true

storage:

  journal:

    enabled: true

  dbPath: /mongodb/38018/data

  directoryPerDB: true

  #engine: wiredTiger

  wiredTiger:

    engineConfig:

      cacheSizeGB: 1

      directoryForIndexes: true

    collectionConfig:

      blockCompressor: zlib

    indexConfig:

      prefixCompression: true

net:

  bindIp: 192.168.8.5,127.0.0.1

  port: 38018

replication:

  oplogSizeMB: 2048

  replSetName: configReplSet

sharding:

  clusterRole: configsvr

processManagement:

  fork: true

EOF

cp /mongodb/38018/conf/mongodb.conf /mongodb/38019/conf/

cp /mongodb/38018/conf/mongodb.conf /mongodb/38020/conf/

sed -i 's#38018#38019#g' /mongodb/38019/conf/mongodb.conf

sed -i 's#38018#38020#g' /mongodb/38020/conf/mongodb.conf

3)启动所有实例节点

mongod -f /mongodb/38018/conf/mongodb.conf

mongod -f /mongodb/38019/conf/mongodb.conf

mongod -f /mongodb/38020/conf/mongodb.conf

netstat -anpt | grep mongod

4)搭建复制集

mongo -port 38018 admin

config = {_id: 'configReplSet', members: [

{_id: 0, host: '192.168.8.5:38018'},

{_id: 1, host: '192.168.8.5:38019'},

{_id: 2, host: '192.168.8.5:38020'}]

}

初始化副本集

rs.initiate(config)

输入命令前面变成复制集的状态,一开始是SECONARY等待变成PRIMARY

注:Config server 可以是一个节点,官方建议复制集。Config server不能有arbiter(仲裁)。新版本中,要求必须是复制集。

注:MongoDB 3.4之后,虽然要求Config server为replica set,但是不支持arbiter

3、路由(mongos)节点配置

1)创建实例目录

mkdir -p /mongodb/38017/{conf,log}

2)创建配置文件

cat > /mongodb/38017/conf/mongos.conf << EOF

systemLog:

  destination: file

  path: /mongodb/38017/log/mongos.log

  logAppend: true

net:

  bindIp: 192.168.8.5,127.0.0.1

  port: 38017

sharding:

  configDB: configReplSet/192.168.8.5:38018,192.168.8.5:38019,192.168.8.5:38020

processManagement:

  fork: true

EOF

3)启动路由(mongos)节点

mongos -f /mongodb/38017/conf/mongos.conf

netstat -anpt | grep mongos

4、分片集群操作

1)连接到mongos的admin数据库

mongo 192.168.8.5:38017/admin

2)添加分片

db.runCommand( { addshard : "sh1/192.168.8.5:38021,192.168.8.5:38022,192.168.8.5:38023",name:"shard1"} )

db.runCommand( { addshard : "sh2/192.168.8.5:38024,192.168.8.5:38025,192.168.8.5:38026",name:"shard2"} )

3)列出分片

db.runCommand ( { listshards : 1 } )

4)查看整体状态

sh.status()

分片方法:

范围分片-id,date类

定义:基数大、频率低、非单调变化(如果单调写,则会分到同一个块里面,容易达到chunk割裂的条件,产生chunk的搬运)

分析:存储倾斜、查询范围数据方便

Hash分片-订单号,uuid等类

定义:应该有良好的基数或者该字段包含大量不同的值-防止出现数据倾斜

分析:存储分散、查询单条数据方便

哈希索引适合单调变化的字段,例如自增值,时间值等(因为可以将单调的字段通过hash函数映射到不同的块上去,从而分散写入压力,例如下图,虽然数据连续,但是写入了不同的数据块中)

联合分片-随机值+范围值组成的联合索引

分析:适合复杂场景

5、Hash分片

对hehe库下的大表进行hash

创建哈希索引

1)对hehe库开启分片功能

mongo -port 38017 admin

use admin

针对hehe库分片

db.runCommand( { enablesharding : "hehe" } )

2)对hehe库下的他t10w表建立hash索引

use hehe

db.t10w.ensureIndex( { id: "hashed" } )

3)开启分片

use admin

sh.shardCollection( "hehe.t10w", { id: "hashed" } )

4)往hehe库下的t10w表写入十万行数据进行测试

use hehe

for(i=1;i<100000;i++){ db.t10w.insert({"id":i,"name":"lisi","age":30,"date":new Date()}); }

5)查看hash分片结果

复制一个会话

会话二:

su – mongod

mongo -port 38021

use hehe

查看t10w表中行数

db.t10w.count()

数据在持续写入

在复制一个会话

会话三:

su – mongod

mongo -port 38024

use hehe

查看t10w表中行数

db.t10w.count()

数据在持续写入

当十万行数据写入之后,再进行查看

会话二:

db.t10w.count()

会话三:

db.t10w.count()

写入的数据进行了分片存储,分别存放到了shard1和shard2上

6、判断是否为shard集群,若返回 ok 为 1,则表示是分片

db.runCommand({ isdbgrid : 1})

7、列出所有分片信息

use admin

db.runCommand({ listshards : 1})

8、列出开启分片的数据库

use config

db.databases.find( { "partitioned": true } )

列出所有数据库分片情况

db.databases.find()

9、查看分片的片键

db.collections.find().pretty()

10、查看分片的详细信息(查询整个集群的状态,包括副本集、分片集、mongos数量、数据库分布在哪个分片上、有无开启平衡器等)

db.printShardingStatus()

sh.status()

两个命令显示结果相同

11、balancer操作

介绍:

mongos的一个重要功能,自动巡查所有shard节点上的chunk的情况,自动做chunk迁移。

什么时候工作?

1)自动运行,会检测系统不繁忙的时候做迁移

2)在做节点删除的时候,立即开始迁移工作

3)balancer只能在预设定的时间窗口内运行

有需要时可以关闭和开启blancer(备份的时候

sh.stopBalancer()

sh.startBalancer()

12、删除分片节点(谨慎

1)确认blance(平衡器)是否工作

sh.getBalancerState()

2)删除shard2节点(谨慎),访问量低的时候才会删除

use admin

db.runCommand( { removeShard: "shard2" } )

会话二:

登录shard1的主节点

su – mongod

mongo -port 38021

use hehe

查看数据

db.t10w.count()

shard2的数据会被自动传到shard1上

13、自动平衡进行的时间段

mongo -port 38017 admin

use config

启动平衡器(默认情况下,在任何需要移动块的时候,平衡器都会进行工作)

sh.setBalancerState(true)

设置负载均衡器的时间窗口

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

获取当前均衡器时间窗口

sh.getBalancerWindow()

查看分片的详细信息

sh.status()

删除时间窗口设置‌

db.settings.update({ _id : "balancer" }, { $unset : { activeWindow : true } })

获取当前均衡器时间窗口

sh.getBalancerWindow()

查看分片的详细信息

sh.status()

查看所有的监控状态

db.serverStatus()

查看网络流量信息

db.serverStatus().network

统计增删改查次数

db.serverStatus().opcounters

统计连接信息

db.serverStatus().connections

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值