分片是跨多台机器存储数据的过程,它是 MongoDB 满足数据增长需求的方法。随着数据的不断增加,单台机器可能不足以存储全部数据,也无法提供足够的读写吞吐量。通过分片,您可以添加更多计算机来满足数据增长和读/写操作的需求
选定一个或多个key,按照选定的key进行数据分割,分割后的数据分别保存在不同的mongodb副本集中,这个是分片的基本思路。
分片思路可以水平扩展机器,根据业务需要扩展任意多的机器。读写压力分散到集群不同的机器中。
Sharded Cluster
A MongoDB sharded cluster consists of the following components:
shard: Each shard contains a subset of the sharded data. Each shard can be deployed as a replica set.
mongos: The mongos acts as a query router, providing an interface between client applications and the sharded cluster. Starting in MongoDB 4.4, mongos can support hedged reads to minimize latencies.
config servers: Config servers store metadata and configuration settings for the cluster.
Config server:MongoDB负责追踪数据块在shard上的分布信息,每个分片存储哪些数据块,叫做分片的元数据,保存在config server上的数据库 config中,一般使用3台config server,所有config server中的config数据库必须完全相同(建议将config server部署在不同的服务器,以保证稳定性);
只要有一个config server失效,那么集群的metadata都将处于只读状态,可以对shards进行数据读写,但是chunks分离和迁移将不能进行,知道三个config servers全部有效为止。如果三个config servers都失效,那么意味着集群将不能读取metadata数据,如果此时重启mongos,那么它将不能获取metadata数据,将无法提供router,直到config servers有效。此外,metadata的数据量非常小,所以这不会对Config servers或者mongos带来存储上的压力。Config server的负载非常小,它对硬件配置要求很低,只需要较少的内存和存储空间即可。
prodution环境中,需要三个config servers;如果仅仅为了测试可以只需要一个。
Shard server:将数据进行分片,拆分成数据块(chunk),每个trunk块的大小默认为64M,数据块真正存放的单位;
Mongos server:数据库集群请求的入口,所有的请求都通过mongos进行协调,查看分片的元数据,查找chunk存放位置,mongos自己就是一个请求分发中心,在生产环境通常有多mongos作为请求的入口,防止其中一个挂掉所有的mongodb请求都没有办法操作。
三个server 不同的配置 bindIp: 192.168.182.144 需要不相同才行,同时配置多个起不来
sharding:
clusterRole: configsvr
replication:
replSetName: shardtest
systemLog:
destination: file
path: "/usr/local/mongodb/logs/mongodb.log"
logAppend: true
storage:
journal:
enabled: true
dbPath: "/usr/local/mongodb/data"
processManagement:
fork: true
net:
bindIp: 192.168.182.144
setParameter:
enableLocalhostAuthBypass: false
启动config server
mongod --config /etc/mongodb_shard_config_server.conf
mongosh --host 192.168.182.142 --port 27019 登录节点
sharding:
clusterRole: shardsvr
replication:
replSetName: shardRpSets
systemLog:
destination: file
path: "/usr/local/mongodb/logs/mongodbRpSets.log"
logAppend: true
storage:
journal:
enabled: true
dbPath: "/usr/local/mongodb/shardRpSetsData"
processManagement:
fork: true
net:
bindIp: 192.168.182.142
setParameter:
enableLocalhostAuthBypass: false
mongod --config /etc/mongodb_sharedRpSet.conf
mongod --config /etc/mongodb_sharedRpSet2.conf
mongod --config /etc/mongodb_sharedRpSet3.conf
tcp 0 0 192.168.182.143:27018 0.0.0.0:* LISTEN 4319/mongod
查看端口命令:
netstat -anp | grep mongo
默认端口27018
mongosh --host 192.168.182.142 --port 27018 登录节点
mongosh --host 192.168.182.142 --port 27011
mongosh --host 192.168.182.142 --port 27012
初始化集群
rs.initiate()
rs.add("192.168.182.143:27018")
rs.add("192.168.182.144:27018")
mongos
for the Sharded Cluster配置文件
sharding:
configDB: shardtest/192.168.182.142:27019,192.168.182.143:27019,192.168.182.144:27019
systemLog:
destination: file
path: "/usr/local/mongodb/logs/mongosRpSets.log"
logAppend: true
processManagement:
fork: true
net:
bindIp: 192.168.182.142
setParameter:
enableLocalhostAuthBypass: false
mongos --config /etc/mongodb_mongosRpSet.conf
连接集群节点
mongosh --host 192.168.182.142 --port 27017 登录节点
添加Shards 到 集群。 shardRpSets 是 Shard Replica Sets 的名称
sh.addShard( "shardRpSets/192.168.182.142:27018,192.168.182.143:27018,192.168.182.144:27018")
sh.addShard( "shardRpSets2/192.168.182.142:27011,192.168.182.143:27011,192.168.182.144:27011")
sh.addShard( "shardRpSets3/192.168.182.142:27012,192.168.182.143:27012,192.168.182.144:27012")
查看状态
sh.status()
添加前:
test> sh.status()
shardingVersion
{
_id: 1,
minCompatibleVersion: 5,
currentVersion: 6,
clusterId: ObjectId("6480a5c9547b59abc36ef6a4")
}
---
shards
[]
---
active mongoses
[]
---
autosplit
{ 'Currently enabled': 'yes' }
---
balancer
{
'Currently enabled': 'yes',
'Currently running': 'no',
'Failed balancer rounds in last 5 attempts': 0,
'Migration Results for the last 24 hours': 'No recent migrations'
}
---
databases
[
{
database: { _id: 'config', primary: 'config', partitioned: true },
collections: {}
}
]
添加后
shardingVersion
{
_id: 1,
minCompatibleVersion: 5,
currentVersion: 6,
clusterId: ObjectId("6480a5c9547b59abc36ef6a4")
}
---
shards
[
{
_id: 'shardRpSets',
host: 'shardRpSets/192.168.182.142:27018,192.168.182.143:27018,192.168.182.144:27018',
state: 1,
topologyTime: Timestamp({ t: 1686228160, i: 5 })
}
]
---
active mongoses
[ { '6.0.6': 1 } ]
---
autosplit
{ 'Currently enabled': 'yes' }
---
balancer
{
'Currently enabled': 'yes',
'Currently running': 'no',
'Failed balancer rounds in last 5 attempts': 0,
'Migration Results for the last 24 hours': 'No recent migrations'
}
---
databases
[
{
database: { _id: 'config', primary: 'config', partitioned: true },
collections: {}
}
]
开启数据库分片
mongo --host 192.168.182.142 --port 27017
启用分片
仅为测试修改chunksize
use config
设置分片chunk大小
db.settings.updateOne(
{ _id: "chunksize" },
{ $set: { _id: "chunksize", value: 1} },
{ upsert: true }
)
设置db启动分片
sh.enableSharding(“shardtest2”);
# 配置collection分片键 为 shardbtest 库中的usertable表进行分片基于id的哈希分片
sh.shardCollection(“shardtest2.usertable”,{“_id”:“hashed”}); #为 shardbtest裤中的usertable表进行分片基于id的哈希分片
for(i=1;i<=6000;i++){db.usertable.insert({“id”:i,“name”:“nnn”+i})}
查看分片验证
db.usertable.stats();
查看分片状态
db.printShardingStatus()
shark key可以决定collection数据在集群的分布,shard key必须为索引字段或者为组合索引的左前缀。documents插入成功后,任何update操作都不能修改shard key,否则会抛出异常
首先shard key必须是数字类型,整个区间的上下边界分别为“正无穷大”、“负无穷大”,每个chunk覆盖一段子区间,即整体而言,任何shard key均会被某个特定的chunk所覆盖。区间均为作闭右开。每个区间均不会有重叠覆盖,且互相临近。当然chunk并不是预先创建的,而是随着chunk数据的增大而不断split。
Range分区更好的支持range查询,根据指定的shard key进行range查询,
计算shard key的hash值(64位数字),并以此作为Range来分区,基本方式同1);Hash值具有很强的散列能力,通常不同的shard key具有不同的hash值(冲突是有限的),这种分区方式可以将document更加随机的分散在不同的chunks上。
db.shards.find()
查看分片集合信息
db.collections.find().pretty()
查询集合中块信息
db.chunks.find().pretty()
跟踪集群拆分和迁移情况
db.changelog.find({'what': 'split'}).pretty()
跟踪网络连接
db.adminCommand({'connPoolStats':1})
删除分片
db.adminCommand({'removeShard': 'study'})
移动块
sh.moveChunk('video.movies', {imdId: 50000}, "shard0002")
修改块的大小
db.settings.updateOne(
{ _id: "chunksize" },
{ $set: { _id: "chunksize", value: 1} },
{ upsert: true }
)
超大块
当一个块大于config.settings中所设置的最大块大小时,均衡器就不允许移动这个块了。这些不可拆分、不可移动的块被称为超大块
对于分发超大块,可以关闭均衡器,临时设置块大小大于该超大块,然后手工移动该块,后恢复块大小及启动均衡器。为了避免超大块,可以修改片键使其具有更小的粒度,如年月日片键,修改为年月日小时分钟秒。
sh.splitAt('video.movies', {'imdId': NumberLong('7000000000000000000000')})
刷新配置
db.adminCommand({'flushRouterConfig': 1})
1.MongoServerError: Please create an index that starts with the proposed shard key before sharding the collection
这个需要创建index,但是我自己创建了index没啥用。倒是新添加的分区集合按照如下步骤,并不需要创建index
设置db启动分片
sh.enableSharding(“shardtest2”);
配置collection分片键 为 shardbtest 库中的usertable表进行分片基于id的哈希分片
sh.shardCollection(“shardtest2.usertable”,{“_id”:“hashed”}); #为 shardbtest裤中的usertable表进行分片基于id的哈希分片
2.分片集群怎么组建,是一个节点用不同的三个端口建立三个分片还是,不同的节点用不同的端口区分创建不同的分片
本次示例用的是同一端口在不同的节点创建分片副本,组成一个分片集群,从而用3个端口分别包含了不同的节点所组成的分片集群
https://blog.csdn.net/SJshenjian/article/details/127374192