MongoDB分⽚(Sharding)技术
一、MongoDB分⽚(Sharding)技术
分⽚(sharding)是MongoDB⽤来将⼤型集合分割到不同服务器(或者说⼀个集群)上所采⽤的⽅法。尽管分 ⽚起源于关系型数据库分区,但MongoDB分⽚完全⼜是另⼀回事。
和MySQL分区⽅案相⽐, MongoDB的最 ⼤区别在于它⼏乎能⾃动完成所有事情, 只要告诉MongoDB要分配数据,它就能⾃动维护数据在不同服务器 之间的均衡。
二、MongoDB分⽚介绍
分⽚的⽬的 . ⾼数据量和吞吐量的数据库应⽤会对单机的性能造成较⼤压⼒,⼤的查询量会将单机的CPU耗尽,⼤ 的数据量对单机的存储压⼒较⼤,最终会耗尽系统的内存⽽将压⼒转移到磁盘IO上。
为了解决这些问题,有两个 基本的⽅法: 垂直扩展和⽔平扩展。
垂直扩展:增加更多的CPU和存储资源来扩展容量。
⽔平扩展: 将数据集分布在多个服务器上。⽔平扩展即分⽚
三、分片设计思想
分⽚为应对⾼吞吐量与⼤数据量提供了⽅法。使⽤分⽚减少了每个分⽚需要处理的请求数,因此,通过⽔平扩 展,集群可以提⾼⾃⼰的存储容量和吞吐量。
举例来说,当插⼊⼀条数据时,应⽤只需要访问存储这条数据的 分⽚. 使⽤分⽚减少了每个分⽚存储的数据。
例如,如果数据库1tb的数据集,并有4个分⽚,然后每个分⽚可 能仅持有256GB的数据。如果有40个分⽚,那么每个切分可能只有25GB的数据。
四、分⽚机制提供了如下三种优势
1. 对集群进⾏抽象,让集群“不可⻅” MongoDB⾃带了⼀个叫做mongos的专有路由进程。 mongos就是掌 握统⼀路⼝的路由器,其会将客户端发来的请求准确⽆误的路由到集群中的⼀个或者⼀组服务器上,同 时会把接收到的响应拼装起来发回到客户端。
2. 保证集群总是可读写 MongoDB通过多种途径来确保集群的可⽤性和可靠性。将MongoDB的分⽚和复制 功能结合使⽤,在确保数据分⽚到多台服务器的同时,也确保了每分数据都有相应的备份,这样就可以 确保有服务器换掉时,其他的从库可以⽴即接替坏掉的部分继续⼯作。
3. 使集群易于扩展 当系统需要更多的空间和资源的时候, MongoDB使我们可以按需⽅便的扩充系统容 量。
五、分片集群架构
分片集群构造
1. mongos :数据路由,和客户端打交道的模块。 mongos本身没有任何数据,他也不知道该怎么处理这 数据,去找config server
2. config server:所有存、取数据的⽅式,所有shard节点的信息,分⽚功能的⼀些配置信息。可以理解为 真实数据的元数据。
3. shard:真正的数据存储位置,以chunk为单位存数据。
Mongos本身并不持久化数据, Sharded cluster 所有的元数据都会存储到Config Server,⽽⽤户的数据会议分散存储到各个shard。
Mongos启动后,会 从配置服务器加载元数据,开始提供服务,将⽤户的请求正确路由到对应的碎⽚。
六、Mongos的路由功能
.当数据写⼊时, MongoDB Cluster根据分⽚键设计写⼊数据。 . 当外部语句发起数据查询时, MongoDB根据 数据分布⾃动路由⾄指定节点返回数据。
七、部署分⽚集群
mongodb分⽚集群实战环境搭建说明
环境准备 :
系统版本: CentOS 7
软件版本: MongoDB4.0
关闭防⽕墙 及selinux
mkdir /data/mongodb/{28017..28019}
mkdir /data/mongodb/{27017..27019}
mkdir /data/mongodb/{29017..29020}
1.configsvr配置
1.)创建配置文件
systemLog:
systemLog: destination: file logAppend: true path: /data/mongodb/28017/mongodb.log storage: dbPath: /data/mongodb/28017 journal: enabled: true processManagement: fork: true net: port: 28017 bindIp: 127.0.0.1 replication: replSetName: testconf sharding: clusterRole: configsvr
其他两个节点修改相应端⼝ 启动实例
mongod -f /data/mongodb/28017/mongodb.conf
2.)分⽚集群的配置⻆⾊副本集搭建
config={_id:"testconf", configsvr:true,members:[ {_id:0,host:"127.0.0.1:28017"}, {_id:1,host:"127.0.0.1:28018"}, {_id:2,host:"127.0.0.1:28019"}] }
rs.initiate(config)
2. router配置 mongodb中的router⻆⾊只负责提供⼀个⼊⼝,不存储任何的数据 创建配置⽂件mongodb.conf
systemLog: destination: file logAppend: true path: /data/mongodb/27017/mongodb.log processManagement: fork: true net: port: 27017 bindIp: 127.0.0.1 sharding: configDB: testconf/127.0.0.1:28017,127.0.0.1:28018,127.0.0.1:28019
其他节点修改相应端⼝ router最重要的配置 指定configsvr的地址,使⽤副本集id+ip端⼝的⽅式指定 配置多个 router,任何⼀个都能正常的获取数据 router的启动
启动:
mongos -f /data/mongodb/27017/mongodb.conf
router的验证 需要等到数据⻆⾊搭建完才能够进⾏验证
3.shardsvr配置
数据⻆⾊ 分⽚集群的数据⻆⾊⾥⾯存储着真正的数据,所以数据⻆⾊⼀定得使⽤副本集多个数据⻆⾊ 创建配置 ⽂件29017/mongodb.conf
systemLog: destination: file logAppend: true path: /data/mongodb/29017/mongodb.log storage: dbPath: /data/mongodb/29017 journal: enabled: true processManagement: fork: true net: port: 29017 bindIp: 127.0.0.1 replication: replSetName: testdata1 sharding: clusterRole: shardsvr
创建另一台配置文件
cp 29017/mongodb.conf 29018/ sed -i "s/29017/29018/g" 29018/mongodb.conf
其他节点修改相应端⼝
创建配置⽂件29019/mongodb.conf
systemLog: destination: file logAppend: true path: /data/mongodb/29019/mongodb.log storage: dbPath: /data/mongodb/29019 journal: enabled: true processManagement: fork: true net: port: 29019 bindIp: 127.0.0.1 replication: replSetName: testdata2 sharding: clusterRole: shardsvr
其他节点修改相应端⼝
cp 29019/mongodb.conf 29020/ sed -i "s/29019/29020/g" 29020/mongodb.conf
启动四个实例
mongod -f /data/mongodb/29017/mongodb.conf mongod -f /data/mongodb/29018/mongodb.conf mongod -f /data/mongodb/29019/mongodb.conf mongod -f /data/mongodb/29020/mongodb.conf
4.配置⻆⾊
29017-29018创建副本集
mongo 127.0.0.1:29017 config={_id:"testdata1", members:[ {_id:0,host:"127.0.0.1:29017"}, {_id:1,host:"127.0.0.1:29018"} ] }
rs.initiate(config)
29019-29020创建副本
mongo 127.0.0.1:29019 config={_id:"testdata2", members:[ {_id:0,host:"127.0.0.1:29019"}, {_id:1,host:"127.0.0.1:29020"} ] }
rs.initiate(config)
5.MongoDB分⽚集群的使⽤
mongo 127.0.0.1:27017 sh.addShard("testdata1/127.0.0.1:29017,127.0.0.1:29018")
sh.addShard("testdata2/127.0.0.1:29019,127.0.0.1:29020")
sh.status()
5.验证数据 (27017上操作)
1.尝试添加数据
use mytest; switched to db mytest for (i=1;i<=500;i++){db.myuser.insert({name:"test1",age:i})} db.myuser.find().count()
查看信息
只能查看到文档储存在一组副本集,因为没有进行分片,导致数据只存在一组上
2.正确分片
use admin
db.runCommand({enablesharding:"mytest"})
db.runCommand({shardcollection:"mytest.test1",key:{_id:"hashed"}})
添加数据验证
27017添加数据
29018查看数据
29019查看数据
八、MongoDB 监控命令
mongostat
mongostat 是 MongoDB ⾃带的状态检测⼯具,可以实时监控 MongoDB 的状态。 查看帮助
mongostat --help
命令使⽤, -n 指定打印次数
mongostat --host 127.0.0.1 --port 27017 -n 3
九、serverstatus
https://docs.mongodb.com/manual/reference/command/serverStatus/#dbcmd.serverStatus
在MongoDB Shell 中调⽤ serverStatus 可以获取 MongoDB 的状态信息。
建议重点⼀下关注流量信息、连接信息、增删改查信 息。
> db.serverStatus() \* 查看所有的监控状态 *\ > db.serverStatus().network \* 查看⽹络流量信息 *\ > db.serverStatus().opcounters \* 统计增删改查次数 *\ { "insert" : NumberLong(189556), "query" : NumberLong(14), "update" : NumberLong(0), "delete" : NumberLong(0), "getmore" : NumberLong(0), "command" : NumberLong(190063) } > db.serverStatus().connections \* 统计连接 *\ { "current" : 3, "available" : 816, "totalCreated" : 8, "active" : 1 }
⾮交互模式下获取
echo 'db.serverStatus().opcounters' |mongo --host 127.0.0.1:27017 MongoDB shell version v4.2.3 connecting to: mongodb://127.0.0.1:27017/? compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("b1f33ce1-34ec-4fbf-b8f1-f5943302ce50") } MongoDB server version: 4.2.3 { "insert" : NumberLong(189556), "query" : NumberLong(14), "update" : NumberLong(0), "delete" : NumberLong(0), "getmore" : NumberLong(0), "command" : NumberLong(190190) } bye