Mongodb Sharded Cluster 分片集群
1 分片概念
分片(sharding)是一种跨多台机器分布数据的方法, MongoDB使用分片来支持具有非常大的数据集和高吞吐量操作的部署。
2 分片集群包含的组件
MongoDB分片群集包含以下组件:
- 分片(存储):每个分片包含分片数据的子集。 每个分片都可以部署为副本集。
- mongos(路由):mongos充当查询路由器,在客户端应用程序和分片集群之间提供接口。
- config servers(“调度”的配置):配置服务器存储群集的元数据和配置设置
3 分片集群实战
目标搭建两个分片(每个分片分别是副本集),一个配置副本集(包含3个节点),路由 (由两个节点组成)
准备3个虚拟机:地址分别是
192.168.40.144, 192.168.40.145, 192.168.40.146
节点 | 位置 |
---|---|
分片1 | 192.168.40.144:27017,192.168.40.144:27018,192.168.40.144:27019 |
分片2 | 192.168.40.145:27017,192.168.40.145:27018,192.168.40.145:27019 |
配置 | 192.168.40.146:27017,192.168.40.146:27018,192.168.40.146:27019 |
路由 | 192.168.40.146:28001,192.168.40.146:28002 |
分片搭建
首先分别在144/145虚拟机上面搭建一个可复制集(分别包含3个节点)
如:
systemLog:
#MongoDB发送所有日志输出的目标指定为文件
destination: file
#mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
path: "/home/amber/mongodb/sharded_cluster/myshardrs01/mongodb-001/log/mongod.log"
#当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
logAppend: true
storage:
#mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
dbPath: "/home/amber/mongodb/sharded_cluster/myshardrs01/mongodb-001/data/db"
journal:
#启用或禁用持久性日志以确保数据文件保持有效和可恢复。
enabled: true
processManagement:
#启用在后台运行mongos或mongod进程的守护进程模式。
fork: true
#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
pidFilePath: "/home/amber/mongodb/sharded_cluster/myshardrs01/mongodb-001/log/mongod.pid"
net:
# 服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
#bindIpAll: true
#服务实例绑定的IP
bindIp: 0.0.0.0
#bindIp
#绑定的端口
port: 27017
replication:
#副本集的名称
replSetName: myshardrs01
sharding:
#分片角色 shardsvr/configsvr
clusterRole: shardsvr
分片配置要重点关注以下配置:
replication:
#副本集的名称
replSetName: myshardrs01
sharding:
#分片角色 shardsvr分片/configsvr配置
clusterRole: shardsvr
配置节点的搭建:
systemLog:
#MongoDB发送所有日志输出的目标指定为文件
destination: file
#mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
path: "/home/amber/mongodb/sharded_cluster/myconfigrs/mongodb-002/log/mongod.log"
#当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
logAppend: true
storage:
#mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
dbPath: "/home/amber/mongodb/sharded_cluster/myconfigrs/mongodb-002/data/db"
journal:
#启用或禁用持久性日志以确保数据文件保持有效和可恢复。
enabled: true
processManagement:
#启用在后台运行mongos或mongod进程的守护进程模式。
fork: true
#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
pidFilePath: "/home/amber/mongodb/sharded_cluster/myconfigrs/mongodb-002/log/mongod.pid"
net:
# 服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
#bindIpAll: true
#服务实例绑定的IP
bindIp: 0.0.0.0
#bindIp
#绑定的端口
port: 27018
replication:
#副本集的名称
replSetName: myconfigrs
sharding:
#分片角色 shardsvr/configsvr
clusterRole: configsvr
配置节点的配置其实和分片的配置没有很大的差别,主要是修改了分片角色
sharding:
#分片角色 shardsvr/configsvr
clusterRole: configsvr
路由节点搭建
配置
systemLog:
#MongoDB发送所有日志输出的目标指定为文件
destination: file
#mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
path: "/home/amber/mongodb/sharded_cluster/myconfigrs/mongodb-001/log/mongod.log"
#当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
logAppend: true
processManagement:
#启用在后台运行mongos或mongod进程的守护进程模式。
fork: true
#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
pidFilePath: "/home/amber/mongodb/sharded_cluster/myconfigrs/mongodb-001/log/mongod.pid"
net:
# 服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
#bindIpAll: true
#服务实例绑定的IP
bindIp: 0.0.0.0
#bindIp
#绑定的端口
port: 28001
sharding:
configDB: myconfigrs/192.168.40.146:27017,192.168.40.146:27018,192.168.40.146:27219
相对于配置节点和分片节点的配置文件,路由节点的配置文件减少了data存储地址配置。变更了,其中configDB为配置节点的地址
sharding:
configDB: myconfigrs/192.168.40.146:27017,192.168.40.146:27018,192.168.40.146:27219
启动路由节点
mongods -f ../conf/mongod.conf
客户端登录
mongo 192.168.40.146:27017
插入数据时候发现报错,原因是虽然节点配置节点已经和路由节点联通了,但是分片节点还没有与路由节点联通
mongos> use amber
switched to db amber
mongos> db.amber.insert({name: "amber"})
WriteCommandError({
"ok" : 0,
"errmsg" : "unable to initialize targeter for write op for collection amber.amber :: caused by :: Database amber not found :: caused by :: No shards found",
"code" : 70,
"codeName" : "ShardNotFound",
"operationTime" : Timestamp(1593535804, 2),
"$clusterTime" : {
"clusterTime" : Timestamp(1593535804, 2),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
})
联通分片节点
mongos> sh.addShard("myshardrs01/192.168.40.144:27017,192.168.40.144:27018,192.168.40.144:27019")
{
"shardAdded" : "myshardrs01",
"ok" : 1,
"operationTime" : Timestamp(1593536073, 2),
"$clusterTime" : {
"clusterTime" : Timestamp(1593536073, 2),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5efb6ae9d123f9c8ef7b74ed")
}
shards:
{ "_id" : "myshardrs01", "host" : "myshardrs01/192.168.40.144:27017,192.168.40.144:27018,192.168.40.144:27019", "state" : 1 }
active mongoses:
"4.0.10" : 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:
{ "_id" : "config", "primary" : "config", "partitioned" : true }
同样的把145分片也加上
mongos> sh.addShard("myshardrs02/192.168.40.145:27017,192.168.40.145:27018,192.168.40.145:27019")
{
"shardAdded" : "myshardrs02",
"ok" : 1,
"operationTime" : Timestamp(1593536130, 4),
"$clusterTime" : {
"clusterTime" : Timestamp(1593536130, 4),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5efb6ae9d123f9c8ef7b74ed")
}
shards:
{ "_id" : "myshardrs01", "host" : "myshardrs01/192.168.40.144:27017,192.168.40.144:27018,192.168.40.144:27019", "state" : 1 }
{ "_id" : "myshardrs02", "host" : "myshardrs02/192.168.40.145:27017,192.168.40.145:27018,192.168.40.145:27019", "state" : 1 }
active mongoses:
"4.0.10" : 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:
{ "_id" : "config", "primary" : "config", "partitioned" : true }
再操作数据库,开启分片
mongos> sh.enableSharding("amber")
{
"ok" : 1,
"operationTime" : Timestamp(1593536255, 3),
"$clusterTime" : {
"clusterTime" : Timestamp(1593536255, 3),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5efb6ae9d123f9c8ef7b74ed")
}
shards:
{ "_id" : "myshardrs01", "host" : "myshardrs01/192.168.40.144:27017,192.168.40.144:27018,192.168.40.144:27019", "state" : 1 }
{ "_id" : "myshardrs02", "host" : "myshardrs02/192.168.40.145:27017,192.168.40.145:27018,192.168.40.145:27019", "state" : 1 }
active mongoses:
"4.0.10" : 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:
{ "_id" : "amber", "primary" : "myshardrs02", "partitioned" : true, "version" : { "uuid" : UUID("f65d89d3-ad59-40ab-9009-bb91fdb8d1d9"), "lastMod" : 1 } }
{ "_id" : "config", "primary" : "config", "partitioned" : true }
config.system.sessions
shard key: { "_id" : 1 }
unique: false
balancing: true
chunks:
myshardrs01 1
{ "_id" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 } } on : myshardrs01 Timestamp(1, 0)
对amber数据库的amber集合进行分片,并使用age作为键值以及采用hashed算法定位数据应该存放再哪一个分片中
mongos> sh.shardCollection("amber.amber",{"age":"hashed"})
{
"ok" : 0,
"errmsg" : "Please create an index that starts with the proposed shard key before sharding the collection",
"code" : 72,
"codeName" : "InvalidOptions",
"operationTime" : Timestamp(1593536415, 4),
"$clusterTime" : {
"clusterTime" : Timestamp(1593536415, 4),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
分片规则一:哈希策略
对于 基于哈希的分片 ,MongoDB计算一个字段的哈希值,并用这个哈希值来创建数据块.在使用基于哈希分片的系统中,拥有”相近”片键的文档 很可能不会 存储在同一个数据块中,因此数据的分离性更好一些.
sh.shardCollection("amber.amber",{"age":"hashed"})
分片规则二:范围策略
对于 基于范围的分片 ,MongoDB按照片键的范围把数据分成不同部分.假设有一个数字的片键:想象一个从负无穷到正无穷的直线,每一个片键的值都在直线上画了一个点.MongoDB把这条直线划分为更短的不重叠的片段,并称之为 数据块 ,每个数据块包含了片键在一定范围内的数据.
sh.shardCollection("amber.amber",{"age":1})