目录
5.3、分片键公式{coarseLocality:1,search:1}
9.1、创建MongoDB四个实例的数据存储目录、日志存储目录、日志文件,修改权限
9.9、配置服务器存储了MongoDB数据库集合分片的详细信息
一、分片概念
分片是一种用于在
多台计算机之间分配数据的方法。
MongoDB使用分片来支持具有非常大的数据集和高吞吐量操作的部署。
当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。
解决系统增长的方法有两种:
垂直缩放和水平缩放。MongoDB
通过分片支持水平扩展。
二、为何使用分片?
2.1、分片特点
-
复制所有的写入操作到主节点
-
延迟的敏感数据会在主节点查询
-
单个副本集限制在12个节点
-
当请求量巨大时出现内存不足,想将大量数据放在内存中提高性能
-
本地磁盘不足
-
垂直扩展价格昂贵
-
服务器出现写瓶颈的时候
分片就是把mongo单个表的数据分到多个chunk上,从而提升mongo的读写能力。
2.2、为何分到多个chunk上可以提升读写能力??
-
多个chunk分布在多个机器上,可以充分利用多台机器的CPU和磁盘IO;
-
分到多个chunk上的时候由于分片键的存在,如果按照分片键进行查询,则直接定位到某个chunk,只需要在这一个chunk上进行查询,这样明显会很快。
三、分片集群Sharded cluster
实现分片集群时,MongoDB 引入 Config Server 来存储集群的元数据,引入 mongos 作为应用访问的入口,mongos 从 Config Server 读取路由信息,并将请求路由到后端对应的 Shard 上。
MongoDB 分片集群由以下组件组成:
-
shard:用来保存数据,保证数据的高可用性和一致性。可以是单独的mongod实例,也可以是个副本集。在生产环境中shard一般是一个Replica Set,以防止该数据片的单点故障。所有Shard中有一个PrimaryShard,里面包含未进行划分的数据集合;
-
config servers:mongod实例,保存集群的元数据(metadata),包含各个shard的路由规则;
-
mongos:Mongos是Sharded cluster的访问入口,其本身并不持久化数据(Sharded cluster所有的元数据都会存储到Config Server,而用户的数据则会分散存储到各个shard)。Mongos启动后,会从config servers加载元数据,开始提供服务,将用户的请求正确路由到对应的shard。 Sharded cluster可以有一个mongos,也可以有多个mongos以减轻客户端请求的压力。
3.1、分片键
MongoDB 使用分片键在分片之间分发集合的文档。分片键由文档中的一个或多个字段组成。
从 4.4 版开始,分片集合中的文档可能会缺少分片键字段。在跨分片分发文档时,缺少分片键字段被视为具有空值,但在路由查询时则不然。有关更多信息,请参阅缺少分片键字段。
在 4.2 及更早版本中,分片集合的每个文档中都必须存在分片键字段。
您在对集合进行分片时选择分片键。
从 MongoDB 5.0 开始,您可以通过更改集合的分片键来重新分片集合。
从 MongoDB 4.4 开始,您可以通过向现有分片键添加一个或多个后缀字段来优化分片键。
在 MongoDB 4.2 及更早版本中,分片后无法更改分片键的选择。
文档的分片键值决定了它在分片中的分布。
从 MongoDB 4.2 开始,您可以更新文档的分片键值,除非您的分片键字段是不可变的 _id 字段。有关更多信息,请参阅更改文档的分片键值。
在 MongoDB 4.0 及更早版本中,文档的分片键字段值是不可变的。
3.2、分片键索引
要对填充的集合进行分片,该集合必须具有以分片键开头的索引。 对空集合进行分片时,如果集合还没有指定分片键的适当索引,则 MongoDB 会创建支持索引。
四、分片分类
MongoDB 支持两种分片策略,用于跨分片集群分布数据。
4.1、Hashed Sharding
散列分片涉及计算分片键字段值的hash散列。 然后根据散列的分片键值为每个块分配一个范围。
基于散列值的数据分布有利于更均匀的数据分布,尤其是在分片键单调变化的数据集中。然而,散列分布意味着对分片键的基于范围的查询不太可能针对单个分片,从而导致更多的集群范围的广播操作
优势:由于hash键可以分布多个chunk,所以会极大提高写入性能
劣势:不方便范围查询
4.2、Ranged Sharding
范围分片涉及根据分片键值将数据划分为范围。 然后根据分片键值为每个块分配一个范围。
值“接近”的一系列分片键更有可能驻留在同一块上。 这允许有针对性的操作,因为 mongos 可以将操作路由到仅包含所需数据的分片。
优势:方便范围查询;若果分片键不是单调递增,也可以提升写入性能
劣势:如果分片键是单调递增,则无法提升写入性能
五、分片键策略与选择逻辑
分片键的选择会影响分片集群的性能、效率和可扩展性。 具有最佳硬件和基础设施的集群可能会因选择分片键而成为瓶颈。 分片键及其后备索引的选择也会影响集群可以使用的分片策略。
5.1、分片键的限制
-
分片键是不可变;
-
分片键必须有索引;
-
分片键大小限制在512bytes;
-
分片键用于路由查询;
-
MongoDB不接受已进行collection级分片的collection插入无分片键的文档(也不支持空值插入)
5.2、分片键的选择逻辑
-
所有的分片读写均匀;
-
数据均匀访问,由于新数据都是先在内存中创建,尽量避免需要从磁盘访问数据;
-
尽量避免由于数据块的数据移动导致数据从磁盘加载到内存中从而导致热数据被清理出内存;
-
组合字段的分片可能会是理想的分片方案
-
分片公式(范围热度)
5.3、分片键公式{coarseLocality:1,search:1}
-
coarseLocality:应该是一个大粒度的局部字段。比如MONTH月份升序字段。
-
*search:是一个经常用来查找的字段。
六、分片后对查询、写入影响
所有的请求都有mongos来路由、分发、合并,这些动作对客户端driver透明。Mongos会根据请求类型及shard key将请求路由到对应的shard,因此不同的操作请求存在不同的限制。
查询请求:
-
查询请求中不包含shard key,则必须将查询分发到所有的shard,然后合并查询结果返回给客户端;
-
查询请求包含shard key,则直接根据shard key计算出需要查询的chunk,向对应的shard发送查询请求。
插入请求:
-
写操作必须包含shard key,mongos根据shard key算出文档应该存储到哪个chunk,然后将写请求发送到chunk所在的shard;
更新/删除请求:
-
更新、删除请求的查询条件必须包含shard key或者_id,若果是包含shard key,则直接路由到指定的chunk,如果只包含_id,则需将请求发送到所有的shard
七、分片优势
1、读/写
MongoDB 在分片集群中的分片之间分配读写工作负载,允许每个分片处理集群操作的子集。通过添加更多分片,读取和写入工作负载都可以在集群中水平扩展。
对于包含分片键或复合分片键前缀的查询,mongos 可以将查询定位在特定分片或分片集上。这些有针对性的操作通常比向集群中的每个分片广播更有效。
2、存储容量
分片将数据分布在集群中的分片中,允许每个分片包含整个集群数据的一个子集。随着数据集的增长,额外的分片会增加集群的存储容量。
3、高可用性
将配置服务器和分片部署为副本集提供了更高的可用性。
即使一个或多个分片副本集变得完全不可用,分片集群也可以继续执行部分读写。也就是说,虽然无法访问不可用分片上的数据,但针对可用分片的读取或写入仍然可以成功。
八、分片中的排序规则
使用带有 collation : { locale : "simple" } 选项的 shardCollection 命令来分片具有默认排序规则的集合。
成功的分片需要:
-
集合必须有一个索引,其前缀是分片键
-
索引必须具有排序规则 { locale: "simple" }
使用排序规则创建新集合时,请确保在对集合进行分片之前满足这些条件。
九、分片中集群部署
在一台物理机74机器上模拟部署一个简单的mongodb分片集群。
-
1台路由实例(端口17017)
-
1台配置实例(端口37017、37018) mongodb1、mongodb2,副本集
-
2台分片实例(端口47017、47018) mongodb3、mongodb4
9.1、创建MongoDB四个实例的数据存储目录、日志存储目录、日志文件,修改权限
mkdir -p /data/mongodb/config_{37017,37018}
mkdir -p /data/mongodb/shard_{47017,47018}
mkdir /data/logs
touch /data/logs/config_{37017,37018}.log
touch /data/logs/shard_{47017,47018}.log
touch /data/logs/route_17017.log
chmod -R 777 /data/logs/*.log
9.2、针对MongoDB服务进行Linux系统内核调优
ulimit -n 25000 #最大文件 数
ulimit -u 25000 #最大进程数
9.3、部署config服务器
9.3.1、编辑config_37017.conf,config_37018.conf,端口号37017、37018,设置configsvr=true,启动配置服务器
# vim config_37017.conf
bind_ip=0.0.0.0port=37017 #指定服务端口dbpath=/data/mongodb/config_37017 #数据存储目录logpath=/data/logs/config_37017.log #日志文件logappend=true #使用追加方式写日志fork=true #后台运行maxConns=5000 #设定最大同时连接数,默认为2000storageEngine=mmapv1#指定存储引擎为内存映射文件configsvr=true #模式为配置服务器模式replSet=rs0 #副本集名称
# vim config_37018.conf
bind_ip=0.0.0.0port=37018 #指定服务端口dbpath=/data/mongodb/config_37018 #数据存储目录logpath=/data/logs/config_37018.log #日志文件logappend=true #使用追加方式写日志fork=true #后台运行maxConns=5000 #设定最大同时连接数,默认为2000storageEngine=mmapv1#指定存储引擎为内存映射文件configsvr=true #模式为配置服务器模式replSet=rs0 #副本集名称
9.3.2、启动配置服务器,进入,可看到配置服务器前缀为“configsvr>”
#启动配置服务器
mongod -f config_37017.conf
mongod -f config_37018.conf
netstat -tlunp| grep mongo
#进入服务,副本集
> mongo --port 37017
use admin
var config={
_id:"rs0",
members:[
{_id:0,host:"192.168.11.74:37017"},
{_id:1,host:"192.168.11.74:37018"}
]
};
rs.initiate(config)
添加这行storageEngine=mmapv1 #指定存储引擎为内存映射文件,在初始化副本集时会报如下错误:
9.4、部署shard分片服务器
9.4.1、编辑shard_47017.conf、shard_47018.conf,端口号47017、47018,设置shardsvr=true
# vim shard_47017.conf
bind_ip=0.0.0.0port=47017 #指定服务端口dbpath=/data/mongodb/shard_47017 #数据存储目录logpath=/data/logs/shard_47017.log #日志文件logappend=true #使用追加方式写日志fork=true #后台运行maxConns=5000 #设定最大同时连接数,默认为2000storageEngine=mmapv1 #指定存储引擎为内存映射文件shardsvr=true #模式为分片服务器模式
# vim shard_47018.conf
bind_ip=0.0.0.0port=47018 #指定服务端口dbpath=/data/mongodb/shard_47018 #数据存储目录logpath=/data/logs/shard_47018.log #日志文件logappend=true #使用追加方式写日志fork=true #后台运行maxConns=5000 #设定最大同时连接数,默认为2000storageEngine=mmapv1 #指定存储引擎为内存映射文件shardsvr=true
9.4.2、启动两个shard服务器
# mongod -f shard_47017.conf
# mongod -f shard_47018.conf
9.5、启动route路由服务器
通过mongos --help命令可以查看启动路由相关参数信息。chunkSize为数据块大小,默认为200MB,为了便于测试这里将值设置为1
# vim route_17017.conf
bind_ip=0.0.0.0port=17017fork=truelogpath=/data/logs/route_17017.logconfigdb=rs0/192.168.11.74:37017,192.168.11.74:37018
# mongos -f route_17017.conf
报错:
![](https://i-blog.csdnimg.cn/blog_migrate/7f045e65cdc239aaac9d55b783eb230e.png)
要求config服务器是副本集,所以9.3章节config服务器配置成副本集
![](https://i-blog.csdnimg.cn/blog_migrate/60ef9717ccb3de0853dd3b192f26c3c8.png)
9.6、启用shard服务器
9.6.1、连接到route服务器,通过sh.status()命令查看分片状态信息
# mongo --port 17017 #进入路由实例
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("62cf9dfd0915271ec0959b9b
")
}
shards: #shards下为空,没有分片服务器
active mongoses:
"3.6.3" : 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 }
9.6.2、通过sh.addShard()命令添加shard服务器
mongos> sh.addShard("192.168.11.74:47017")
{
"shardAdded" : "shard0000",
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1635297315, 4),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1635297315, 4)
}
mongos> sh.addShard("192.168.11.74:47018")
{
"shardAdded" : "shard0001",
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1635297326, 3),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1635297326, 3)
}
9.6.3、再次查看分片信息,可以看到shards:选项下已经显示刚刚添加的分片服务器
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("62cf9dfd0915271ec0959b9b
")
}
shards:
{ "_id" : "shard0000", "host" : "192.168.11.74:47017", "state" : 1 } # 添加的分片
{ "_id" : "shard0001", "host" : "192.168.11.74:47018", "state" : 1 }
active mongoses:
"3.6.3" : 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 }
9.7、实现分片功能
分片选择 hash分片 的方式 就可以很明显的看见分片效果了,其他的分片的方式需要很大的数据才能进行分片。查看自己分片的库的大小,然后看下自己设置的块的大小(chunksize),默认是 64MB,多是数据没有达到分块的值。
9.7.1、添加两个分片服务器后,数据库与集合还未启用分片
mongos> show dbs
admin 0.000GB
config 0.157GB
mongos> use school #进入并创建数据库school
switched to db school
mongos> for (var i=1;i<=5000000;i++)db.info.insert({"id":i,"name":"tom"+i}) #创建集合info,并使用循环插入50000条数据
WriteResult({ "nInserted" : 1 }) #此时50000条数据都在primary(47017)服务器上
9.7.2、使用sh.enableSharding("school")命令启动school数据库分片
mongos> sh.enableSharding("school")
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1635298856, 6),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1635298856, 6)
}
9.7.3、针对info集合创建索引
mongos> db.info.createIndex({"id":1})
{
"raw" : {
"192.168.30.55:47017" : {
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
},
"ok" : 1
}
9.7.4、使用sh.shardCollection("school.info",{"id":1})命令对集合info进行分片
mongos> sh.shardCollection("school.info",{"id":1})
{
"collectionsharded" : "school.info",
"collectionUUID" : UUID("64af5a8d-ae31-4916-b0fc-2859ebb0a65d"),
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1635301130, 10),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1635301130, 10)
}
9.7.5、查看分片信息
mongos
>
sh
.
status
()
--- Sharding Status
---
sharding version
:
{
"_id"
:
1
,
"minCompatibleVersion"
:
5
,
"currentVersion"
:
6
,
"clusterId"
: ObjectId
(
"62cf9dfd0915271ec0959b9b"
)
}
shards
:
{
"_id"
:
"shard0000"
,
"host"
:
"192.168.11.74:47017"
,
"state"
:
1
}
{
"_id"
:
"shard0001"
,
"host"
:
"192.168.11.74:47018"
,
"state"
:
1
}
active mongoses
:
"3.6.3"
:
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
:
8
: Success
databases
:
{
"_id"
:
"config"
,
"primary"
:
"config"
,
"partitioned"
: true
}
config
.system
.sessions
shard key
:
{
"_id"
:
1
}
unique
: false
balancing
: true
chunks
:
shard0000
1
{
"_id"
:
{
"$minKey"
:
1
}
}
-->>
{
"_id"
:
{
"$maxKey"
:
1
}
} on
: shard0000 Timestamp
(
1
,
0
)
{
"_id"
:
"school"
,
"primary"
:
"shard0000"
,
"partitioned"
: true
}
#
数据库
school
的分片信息
school
.info
shard key
:
{
"id"
:
1
}
# 分片键
unique
: false
balancing
: true
chunks
:
#
可以看到
chunks
均匀分布到两个分片上
shard0000
9
# 9+8=17
shard0001
8
{
"id"
:
{
"$minKey"
:
1
}
}
-->>
{
"id"
:
299594
} on
: shard0001 Timestamp
(
2
,
0
)
{
"id"
:
299594
}
-->>
{
"id"
:
599188
} on
: shard0001 Timestamp
(
3
,
0
)
{
"id"
:
599188
}
-->>
{
"id"
:
898782
} on
: shard0001 Timestamp
(
4
,
0
)
{
"id"
:
898782
}
-->>
{
"id"
:
1198376
} on
: shard0001 Timestamp
(
5
,
0
)
{
"id"
:
1198376
}
-->>
{
"id"
:
1497970
} on
: shard0001 Timestamp
(
6
,
0
)
{
"id"
:
1497970
}
-->>
{
"id"
:
1797564
} on
: shard0001 Timestamp
(
7
,
0
)
{
"id"
:
1797564
}
-->>
{
"id"
:
2097158
} on
: shard0001 Timestamp
(
8
,
0
)
{
"id"
:
2097158
}
-->>
{
"id"
:
2396752
} on
: shard0001 Timestamp
(
9
,
0
)
{
"id"
:
2396752
}
-->>
{
"id"
:
2696346
} on
: shard0000 Timestamp
(
9
,
1
)
{
"id"
:
2696346
}
-->>
{
"id"
:
2995940
} on
: shard0000 Timestamp
(
1
,
9
)
{
"id"
:
2995940
}
-->>
{
"id"
:
3295534
} on
: shard0000 Timestamp
(
1
,
10
)
{
"id"
:
3295534
}
-->>
{
"id"
:
3595128
} on
: shard0000 Timestamp
(
1
,
11
)
{
"id"
:
3595128
}
-->>
{
"id"
:
3894722
} on
: shard0000 Timestamp
(
1
,
12
)
{
"id"
:
3894722
}
-->>
{
"id"
:
4194316
} on
: shard0000 Timestamp
(
1
,
13
)
{
"id"
:
4194316
}
-->>
{
"id"
:
4493910
} on
: shard0000 Timestamp
(
1
,
14
)
{
"id"
:
4493910
}
-->>
{
"id"
:
4793504
} on
: shard0000 Timestamp
(
1
,
15
)
{
"id"
:
4793504
}
-->>
{
"id"
:
{
"$maxKey"
:
1
}
} on
: shard0000 Timestamp
(
1
,
16
)
9.7.6、sh.addShardTag()添加标签
mongos> sh.addShardTag("shard0000","abc01")
mongos> sh.addShardTag("shard0001","abc02")
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("62cf9dfd0915271ec0959b9b
")
}
shards:
{ "_id" : "shard0000", "host" : "192.168.30.55:47017", "tags" : [ "abc01" ] }
{ "_id" : "shard0001", "host" : "192.168.30.55:47018", "tags" : [ "abc02" ] }
9.8、MongoDB分片服务器管理
9.8.1、根据需求可以添加或删除sharding server
# cp shard_47018.conf mongodb4shard_47019.conf
# vim shard_47019.conf
bind_ip = 0.0.0.0port = 47019 # 指定服务端口dbpath =/data /mongodb /shard_47019 # 数据存储目录logpath =/data /logs /shard_47019 .log # 日志文件logappend =true # 使用追加方式写日志fork =true # 后台运行maxConns = 5000 # 设定最大同时连接数,默认为 2000storageEngine =mmapv1 # 指定存储引擎为内存映射文件shardsvr =true
# 启动实例4
mongod -f shard_47019.conf
9.8.2、进入route服务器添加新的分片服务器mongo4
# mongo
mongos> sh.addShard("192.168.11.74:47019") # 添加一个新的分片服务器
mongos
> sh
.status
()
# 查看分片服务信息
--- Sharding Status
---
sharding version
:
{
"_id"
:
1
,
"minCompatibleVersion"
:
5
,
"currentVersion"
:
6
,
"clusterId"
: ObjectId
(
"62cf9dfd0915271ec0959b9b"
)
}
shards
:
{
"_id"
:
"shard0000"
,
"host"
:
"192.168.11.74:47017"
,
"state"
:
1
}
{
"_id"
:
"shard0001"
,
"host"
:
"192.168.11.74:47018"
,
"state"
:
1
}
{
"_id"
:
"shard0002"
,
"host"
:
"192.168.11.74:47019"
,
"state"
:
1
}
active mongoses
:
"3.6.3"
:
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
:
13
: Success
databases
:
{
"_id"
:
"config"
,
"primary"
:
"config"
,
"partitioned"
: true
}
config
.system
.sessions
shard key
:
{
"_id"
:
1
}
unique
: false
balancing
: true
chunks
:
shard0000
1
{
"_id"
:
{
"$minKey"
:
1
}
}
-->>
{
"_id"
:
{
"$maxKey"
:
1
}
} on
: shard0000 Timestamp
(
1
,
0
)
{
"_id"
:
"school"
,
"primary"
:
"shard0000"
,
"partitioned"
: true
}
school
.info
shard key
:
{
"id"
:
1
}
unique
: false
balancing
: true
chunks
:
#
可以看到
chunks
均匀分布到三个分片上
shard0000
6
# 6+6+5=17
shard0001
6
shard0002
5
{
"id"
:
{
"$minKey"
:
1
}
}
-->>
{
"id"
:
299594
} on
: shard0002 Timestamp
(
12
,
0
)
{
"id"
:
299594
}
-->>
{
"id"
:
599188
} on
: shard0002 Timestamp
(
14
,
0
)
{
"id"
:
599188
}
-->>
{
"id"
:
898782
} on
: shard0001 Timestamp
(
14
,
1
)
{
"id"
:
898782
}
-->>
{
"id"
:
1198376
} on
: shard0001 Timestamp
(
5
,
0
)
{
"id"
:
1198376
}
-->>
{
"id"
:
1497970
} on
: shard0001 Timestamp
(
6
,
0
)
{
"id"
:
1497970
}
-->>
{
"id"
:
1797564
} on
: shard0001 Timestamp
(
7
,
0
)
{
"id"
:
1797564
}
-->>
{
"id"
:
2097158
} on
: shard0001 Timestamp
(
8
,
0
)
{
"id"
:
2097158
}
-->>
{
"id"
:
2396752
} on
: shard0001 Timestamp
(
9
,
0
)
{
"id"
:
2396752
}
-->>
{
"id"
:
2696346
} on
: shard0002 Timestamp
(
10
,
0
)
{
"id"
:
2696346
}
-->>
{
"id"
:
2995940
} on
: shard0002 Timestamp
(
11
,
0
)
{
"id"
:
2995940
}
-->>
{
"id"
:
3295534
} on
: shard0002 Timestamp
(
13
,
0
)
{
"id"
:
3295534
}
-->>
{
"id"
:
3595128
} on
: shard0000 Timestamp
(
13
,
1
)
{
"id"
:
3595128
}
-->>
{
"id"
:
3894722
} on
: shard0000 Timestamp
(
1
,
12
)
{
"id"
:
3894722
}
-->>
{
"id"
:
4194316
} on
: shard0000 Timestamp
(
1
,
13
)
{
"id"
:
4194316
}
-->>
{
"id"
:
4493910
} on
: shard0000 Timestamp
(
1
,
14
)
{
"id"
:
4493910
}
-->>
{
"id"
:
4793504
} on
: shard0000 Timestamp
(
1
,
15
)
{
"id"
:
4793504
}
-->>
{
"id"
:
{
"$maxKey"
:
1
}
} on
: shard0000 Timestamp
(
1
,
16
)
9.8.3、使用db.runCommand({"removeshard":"192.168.11.74:47019"})命令可以删除新添加的分片服务器
mongos> use admin # 注:在admin db下执行命令。
switched to db admin
mongos> db.runCommand({"removeshard":"192.168.30.55:47019"})
{
"msg" : "draining started successfully",
"state" : "started",
"shard" : "shard0002",
"note" : "you need to drop or movePrimary these databases",
"dbsToMove" : [ ],
"ok" : 1
}
mongos> db.runCommand({"removeshard":"192.168.30.55:47019"})
{
"msg" : "removeshard completed successfully",
"state" : "completed", # 该命令至少执行两次才能成功删除,执行到state为completed才真正删除,否则就是没有删除成功
"shard" : "shard0002",
"ok" : 1
}
9.9、配置服务器存储了MongoDB数据库集合分片的详细信息
可以通过以下命令查看
# mongo --port 37017
configsvr> use config
configsvr> show collections
....
collections
chunks
databases
....
configsvr> db.chunks.findOne()
configsvr> db.collections.find()
configsvr> db.databases.find()
9.10、分析查询
走分片键查询:db.getCollection("info").find({"id":3345667}).explain("executionStats")
{
"queryPlanner" : {
"mongosPlannerVersion" : 1,
"winningPlan" : {
"stage" : "SINGLE_SHARD", # 数据在一个shard中
"shards" : [
{
"shardName" : "shard0001", # 只需在分片1上查询
"connectionString" : "192.168.11.74:47018",
"serverInfo" : {
"host" : "node1",
"port" : 47018,
"version" : "3.6.3",
"gitVersion" : "9586e557d54ef70f9ca4b43c26892cd55257e1a5"
},
"plannerVersion" : 1,
"namespace" : "school.info",
"indexFilterSet" : false,
"parsedQuery" : {
"id" : {
"$eq" : 3345667
}
},
"winningPlan" : {
"stage" : "FETCH", # 根据索引去检索指定document
"inputStage" : {
"stage" : "SHARDING_FILTER", # 通过mongos对分片数据进行查询
"inputStage" : {
"stage" : "IXSCAN", # 索引扫描
"keyPattern" : {
"id" : 1
},
"indexName" : "id_1", # 索引名称
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"id" : [
"[3345667.0, 3345667.0]"
]
}
}
}
},
"rejectedPlans" : [ ]
}
]
}
},
"executionStats" : {
"nReturned" : 1,
"executionTimeMillis" : 1,
"totalKeysExamined" : 1,
"totalDocsExamined" : 1,
"executionStages" : {
"stage" : "SINGLE_SHARD",
"nReturned" : 1,
"executionTimeMillis" : 1,
"totalKeysExamined" : 1,
"totalDocsExamined" : 1,
"totalChildMillis" : NumberLong(1),
"shards" : [
{
"shardName" : "shard0001",
"executionSuccess" : true,
"executionStages" : {
"stage" : "FETCH", # 根据索引去检索指定document
"nReturned" : 1,
"executionTimeMillisEstimate" : 0, # 表示执行时间,单位毫秒
"works" : 2,
"advanced" : 1,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 1,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "SHARDING_FILTER", # 通过mongos对分片数据进行查询
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 2,
"advanced" : 1,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"chunkSkips" : 0,
"inputStage" : {
"stage" : "IXSCAN", # 索引扫描
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 2,
"advanced" : 1,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"id" : 1
},
"indexName" : "id_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"id" : [
"[3345667.0, 3345667.0]"
]
},
"keysExamined" : 1,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
}
]
}
},
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1657762267, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1657762267, 1)
}
不走分片键查询:db.getCollection("info").find({"name":"tom3345667"}).explain("executionStats")
{
"queryPlanner" : {
"mongosPlannerVersion" : 1,
"winningPlan" : {
"stage" : "SHARD_MERGE", # 将各个分片返回数据进行merge
"shards" : [
{
"shardName" : "shard0000", # 分片1
"connectionString" : "192.168.11.74:47017",
"serverInfo" : {
"host" : "node1",
"port" : 47017,
"version" : "3.6.3",
"gitVersion" : "9586e557d54ef70f9ca4b43c26892cd55257e1a5"
},
"plannerVersion" : 1,
"namespace" : "school.info",
"indexFilterSet" : false,
"parsedQuery" : {
"name" : {
"$eq" : "tom3345667"
}
},
"winningPlan" : {
"stage" : "SHARDING_FILTER", # 通过mongos对分片数据进行查询
"inputStage" : {
"stage" : "COLLSCAN", # 全表扫描
"filter" : {
"name" : {
"$eq" : "tom3345667"
}
},
"direction" : "forward"
}
},
"rejectedPlans" : [ ]
},
{
"shardName" : "shard0001", # 分片2
"connectionString" : "192.168.11.74:47018",
"serverInfo" : {
"host" : "node1",
"port" : 47018,
"version" : "3.6.3",
"gitVersion" : "9586e557d54ef70f9ca4b43c26892cd55257e1a5"
},
"plannerVersion" : 1,
"namespace" : "school.info",
"indexFilterSet" : false,
"parsedQuery" : {
"name" : {
"$eq" : "tom3345667"
}
},
"winningPlan" : {
"stage" : "SHARDING_FILTER",
"inputStage" : {
"stage" : "COLLSCAN",
"filter" : {
"name" : {
"$eq" : "tom3345667"
}
},
"direction" : "forward"
}
},
"rejectedPlans" : [ ]
}
]
}
},
"executionStats" : {
"nReturned" : 1,
"executionTimeMillis" : 1179,
"totalKeysExamined" : 0,
"totalDocsExamined" : 6437426,
"executionStages" : {
"stage" : "SHARD_MERGE", # 将各个分片返回数据进行merge
"nReturned" : 1,
"executionTimeMillis" : 1179,
"totalKeysExamined" : 0,
"totalDocsExamined" : 6437426,
"totalChildMillis" : NumberLong(2305),
"shards" : [
{
"shardName" : "shard0000", # 分片1
"executionSuccess" : true,
"executionStages" : {
"stage" : "SHARDING_FILTER", # 通过mongos对分片数据进行查询
"nReturned" : 0,
"executionTimeMillisEstimate" : 1031, # 耗时
"works" : 3142992,
"advanced" : 0,
"needTime" : 3142991,
"needYield" : 0,
"saveState" : 24556,
"restoreState" : 24556,
"isEOF" : 1,
"invalidates" : 0,
"chunkSkips" : 0,
"inputStage" : {
"stage" : "COLLSCAN", # 全表扫描
"filter" : {
"name" : {
"$eq" : "tom3345667"
}
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 951,
"works" : 3142992,
"advanced" : 0,
"needTime" : 3142991,
"needYield" : 0,
"saveState" : 24556,
"restoreState" : 24556,
"isEOF" : 1,
"invalidates" : 0,
"direction" : "forward",
"docsExamined" : 3142990
}
}
},
{
"shardName" : "shard0001", # 分片2
"executionSuccess" : true,
"executionStages" : {
"stage" : "SHARDING_FILTER",
"nReturned" : 1,
"executionTimeMillisEstimate" : 1051,
"works" : 3294438,
"advanced" : 1,
"needTime" : 3294436,
"needYield" : 0,
"saveState" : 25737,
"restoreState" : 25737,
"isEOF" : 1,
"invalidates" : 0,
"chunkSkips" : 0,
"inputStage" : {
"stage" : "COLLSCAN", # 全表扫描
"filter" : {
"name" : {
"$eq" : "tom3345667"
}
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 1001,
"works" : 3294438,
"advanced" : 1,
"needTime" : 3294436,
"needYield" : 0,
"saveState" : 25737,
"restoreState" : 25737,
"isEOF" : 1,
"invalidates" : 0,
"direction" : "forward",
"docsExamined" : 3294436
}
}
}
]
}
},
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1657762867, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1657762867, 1)
}
十、分片 与 不分片 性能比对
数据量5000000
size | storage size | index size | query all | {"id":3345660} | {"name":"tom3345660"} | {"name":{'$regex':".*om334566.*"}} | |
不分片 | 261.2M | 76.8M | 111.8M | 0.88s | 0.001s | 2.405s | 3.523s |
2分片 | 534.1M | 1.1GB | 281M | 0.671s | 0.003s | 1.033s | 1.436s |
3分片 | 534.1M | 1.3G | 311.1M | 0.698s | 0.002s | 0.711s | 1.167s |