MongoDB分片介绍
分片(sharding)是MongoDB用来将大型集合分割到不同服务器(或者说一个集群)上所采用的方法。尽管分片起源于关系型数据库分区,但MongoDB分片完全又是另一回事。
和MySQL分区方案相比,MongoDB的最大区别在于它几乎能自动完成所有事情,只要告诉MongoDB要分配数据,它就能自动维护数据在不同服务器之间的均衡。
分片的目的
高数据量和吞吐量的数据库应用会对单机的性能造成较大压力,大的查询量会将单机的CPU耗尽,大的数据量对单机的存储压力较大,最终会耗尽系统的内存而将压力转移到磁盘IO上。
为了解决这些问题,有两个基本的方法: 垂直扩展和水平扩展。
- 垂直扩展:增加更多的CPU和存储资源来扩展容量。
- 水平扩展:将数据集分布在多个服务器上。水平扩展即分片。
MongoDB几个基本概念
各种概念由小到大;
- 片键shard key:文档中的一个字段
- 文档doc:包含shard key的一行数据
- 块chunk:包含n个文档
- 分片shard:包含n个chunk
- 集群cluster:包含n个分片
重点说一下Chunk,在一个shard server内部,MongoDB还是会把数据分为chunks,每个chunk代表这个shard server内部一部分数据。chunk的产生,会有以下两个用途:
- Splitting:当一个chunk的大小超过配置中的chunk size时,MongoDB的后台进程会把这个chunk切分成更小的chunk,从而避免chunk过大的情况
- Balancing:在MongoDB中,balancer是一个后台进程,负责chunk的迁移,从而均衡各个shard server的负载,系统初始1个chunk,chunk size默认值64M,生产库上选择适合业务的chunk size是最好的。MongoDB会自动拆分和迁移chunks。
分片集群架构
组件 | 说明 |
---|---|
Config Server | 存储集群所有节点、分片数据路由信息。默认需要配置3个Config Server节点。 |
Mongos | 提供对外应用访问,所有操作均通过mongos执行。一般有多个mongos节点。数据迁移和数据自动平衡。 |
Mongod | 存储应用数据记录。一般有多个Mongod节点,达到数据分片目的。 |
官方架构图如下:
配置过程
规划:
10个实例,端口号:38017-38026
- configserver:
3台构成的复制集(1主两从,不支持arbiter)38018-38020(复制集名字configsvr) - shard节点:
sh1:38021-23 (1主两从,其中一个节点为arbiter,复制集名字sh1)
sh2:38024-26 (1主两从,其中一个节点为arbiter,复制集名字sh2) -
router(mongos)节点
一个router节点:38017shard复制集配置:
- 目录创建
mkdir -p /mongodb/38021/conf /mongodb/38021/log /mongodb/38021/data mkdir -p /mongodb/38022/conf /mongodb/38022/log /mongodb/38022/data mkdir -p /mongodb/38023/conf /mongodb/38023/log /mongodb/38023/data mkdir -p /mongodb/38024/conf /mongodb/38024/log /mongodb/38024/data mkdir -p /mongodb/38025/conf /mongodb/38025/log /mongodb/38025/data mkdir -p /mongodb/38026/conf /mongodb/38026/log /mongodb/38026/data
-
修改配置文件
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: 11.111.24.4,127.0.0.1 port: 38021 replication: oplogSizeMB: 2048 replSetName: sh1 #replica set名称 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 's#38021#38022#g' /mongodb/38022/conf/mongodb.conf -i sed 's#38021#38023#g' /mongodb/38023/conf/mongodb.conf -i
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: 11.111.24.4,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 's#38024#38025#g' /mongodb/38025/conf/mongodb.conf -i sed 's#38024#38026#g' /mongodb/38026/conf/mongodb.conf -i
-
启动所有节点,并搭建复制集:
#启动节点 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 #配置复制集sh1 mongo --port 38021 admin config = {_id: 'sh1', members: [ {_id: 0, host: '11.111.24.4:38021'}, {_id: 1, host: '11.111.24.4:38022'}, {_id: 2, host: '11.111.24.4:38023',"arbiterOnly":true}] } rs.initiate(config) #配置复制集sh2 mongo --port 38024 admin config = {_id: 'sh2', members: [ {_id: 0, host: '11.111.24.4:38024'}, {_id: 1, host: '11.111.24.4:38025'}, {_id: 2, host: '11.111.24.4:38026',"arbiterOnly":true}] } rs.initiate(config)
config节点配置:
- 目录创建
mkdir -p /mongodb/38018/conf /mongodb/38018/log /mongodb/38018/data mkdir -p /mongodb/38019/conf /mongodb/38019/log /mongodb/38019/data mkdir -p /mongodb/38020/conf /mongodb/38020/log /mongodb/38020/data
-
修改配置文件
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: 11.111.24.4,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 's#38018#38019#g' /mongodb/38019/conf/mongodb.conf -i sed 's#38018#38020#g' /mongodb/38020/conf/mongodb.conf -i
-
启动节点,并配置复制集
mongod -f /mongodb/38018/conf/mongodb.conf mongod -f /mongodb/38019/conf/mongodb.conf mongod -f /mongodb/38020/conf/mongodb.conf mongo --port 38018 admin config = {_id: 'configReplSet', members: [ {_id: 0, host: '11.111.24.4:38018'}, {_id: 1, host: '11.111.24.4:38019'}, {_id: 2, host: '11.111.24.4:38020'}] } rs.initiate(config)
mongos节点配置
- 创建目录
mkdir -p /mongodb/38017/conf /mongodb/38017/log
- 配置文件
cat >/mongodb/38017/conf/mongos.conf<<EOF systemLog: destination: file path: /mongodb/38017/log/mongos.log logAppend: true net: bindIp: 11.111.24.4,127.0.0.1 port: 38017 sharding: configDB: configReplSet/11.111.24.4:38018,11.111.24.4:38019,11.111.24.4:38020 processManagement: fork: true EOF
- 启动mongos
mongos -f /mongodb/38017/conf/mongos.conf
生产上建议使用多个router,防止出现单点问题,所有节点的router配置一致
分片集群操作
连接到其中一个mongos(11.111.24.4),做以下配置
(1)连接到mongs的admin数据库
# su - mongod
$ mongo 11.111.24.4:38017/admin
(2)添加分片
db.runCommand( { addshard : "sh1/11.111.24.4:38021,11.111.24.4:38022,11.111.24.4:38023",name:"shard1"} )
db.runCommand( { addshard : "sh2/11.111.24.4:38024,11.111.24.4:38025,11.111.24.4:38026",name:"shard2"} )
(3)列出分片
mongos> db.runCommand( { listshards : 1 } )
(4)整体状态查看
mongos> sh.status();
到此MongoDB Sharding Cluster配置完成
使用分片集群
RANGE分片配置及测试
test库下的vast大表进行手工分片
1、激活数据库分片功能
mongo --port 38017 admin
admin> ( { enablesharding : "数据库名称" } )
eg:
admin> db.runCommand( { enablesharding : "test" } )
2、指定分片建对集合分片
eg:范围片键
--创建索引
use test
> db.vast.ensureIndex( { id: 1 } )
--开启分片
use admin
> db.runCommand( { shardcollection : "test.vast",key : {id: 1} } )
3、集合分片验证
admin> use test
test> for(i=1;i<1000000;i++){ db.vast.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); }
test> db.vast.stats()
4、分片结果测试
shard1:
mongo --port 38021
db.vast.count();
shard2:
mongo --port 38024
db.vast.count();
Hash分片例子:
对test2库下的vast大表进行hash
创建哈希索引
(1)对于test2开启分片功能
mongo --port 38017 admin
use admin
admin> db.runCommand( { enablesharding : "test2" } )
(2)对于test2库下的vast表建立hash索引
use test2
test2> db.vast.ensureIndex( { id: "hashed" } )
(3)开启分片
use admin
admin > sh.shardCollection( "test2.vast", { id: "hashed" } )
(4)录入10w行数据测试
use test2
for(i=1;i<100000;i++){ db.vast.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); }
(5)hash分片结果测试
mongo --port 38021
use test2
db.vast.count();
mongo --port 38024
use test2
db.vast.count();
分片操作
-
判断是否Shard集群
admin> db.runCommand({ isdbgrid : 1}) -
列出所有分片信息
admin> db.runCommand({ listshards : 1}) -
列出开启分片的数据库
admin> use config
config> db.databases.find( { "partitioned": true } )
或者:
config> db.databases.find() //列出所有数据库分片情况 -
查看分片的片键
config> db.collections.find().pretty()
{
"_id" : "test.vast",
"lastmodEpoch" : ObjectId("58a599f19c898bbfb818b63c"),
"lastmod" : ISODate("1970-02-19T17:02:47.296Z"),
"dropped" : false,
"key" : {
"id" : 1
},
"unique" : false
} -
查看分片的详细信息
admin> db.printShardingStatus()
或
admin> sh.status() ***** - 删除分片节点(谨慎)
(1)确认blance是否在工作
sh.getBalancerState()
(2)删除shard2节点(谨慎)
mongos> db.runCommand( { removeShard: "shard2" } )
注意:删除操作一定会立即触发blancer。
引用:https://www.cnblogs.com/duanxz/p/10730121.html
官方文档:https://docs.mongodb.com/manual/sharding/