mongo 哪些指令条件需要包含分片键

一、mongo分片原理

          在MongoDB中,数据根据一个称为分片键(Shared Key) 的字段进行分片。根据指定字段按照指定分片方式(哈希分片、范围分片)将数据拆分到mongo集群里的不同服务器中

        分片键的选择非常关键,它应该能够确保数据均匀分布,避免热点问题。

        分片键通常是在文档中的一个字段,MongoDB根据这个字段的值来决定将文档存储在哪个分片上

二、分片作用

       1、MongoDB分片的主要优势在于它允许数据库在数据量增加时水平扩展

           通过增加更多的分片来处理更多的负责。通过增加更多的分片来处理更多的负载。分片键的选择和分片集群的规划是关键的设计决策,因为它们直接影响了系统的性能和可扩展性

      2、提高查询效率

           当我们在使用条件查询时,如果查询条件中包含了分片键,MongoDB就可以利用分片键来进行数据定位,确定数据存储在哪个分片上,从而只在特定的分片上进行查询, 而不是在整个集群中搜搜,可以大大减少查询的范围,提高查询效率

三、是不是所有的MongoDB 指令条件都需要包含分片键

      最好在MongoDB指令(如查找、更新、删除)操作时,条件都包含分片键,这样可以提高查询效率。但在实际业务中,常常不同的db操作指令,可能会有自己的索引,而索引不一定都能命中分片键。 这种情况下就不能实现所有的条件都包含分片键了。

     举个例子:

        现在有一个umsg库,索引、分片键声明如下

"umsg": {
        "indexes" : [
            {
                "index": [
                    ["_id", 1]    //索引1
                ],
                "options": {
                }
            },
            {
                "index": [
                    ["avatarID", 1]   //索引2
                ],
                "options": {
                }
            }
        ],
        "shard_key": {"_id": "hashed"}  // _id 分片键,分片方式:哈希分片
    },

     1)update指令更新数据,指令操作失败

更新指令:
db.getCollection('umsg').update({id:1}, {$set:{a:1}})



更新报错:
A single update on a sharded collection must contain an exact match on _id (and have the collection default collation) or contain the shard key (and have the simple collation). Update request: { q: { id: 1.0 }, u: { $set: { a: 1.0 } }, multi: false, upsert: false }, shard key pattern: { _id: "hashed" }

   2)deleteOne指令删除数据,指令操作失败

删除指令:
db.getCollection('umsg').deleteOne({id:1})



删除结果:
Failed to execute script.

Error:
WriteError({
	"index" : 0,
	"code" : 61,
	"errmsg" : "A single delete on a sharded collection must contain an exact match on _id (and have the collection default collation) or contain the shard key (and have the simple collation). Delete request: { q: { id: 1.0 }, limit: 1 }, shard key pattern: { _id: \"hashed\" }",
	"op" : {
		"q" : {
			"id" : 1
		},
		"limit" : 1
	}
}) :
WriteError({
	"index" : 0,
	"code" : 61,
	"errmsg" : "A single delete on a sharded collection must contain an exact match on _id (and have the collection default collation) or contain the shard key (and have the simple collation). Delete request: { q: { id: 1.0 }, limit: 1 }, shard key pattern: { _id: \"hashed\" }",
	"op" : {
		"q" : {
			"id" : 1
		},
		"limit" : 1
	}
})
WriteError@src/mongo/shell/bulk_api.js:458:48
mergeBatchResults@src/mongo/shell/bulk_api.js:855:49
executeBatch@src/mongo/shell/bulk_api.js:919:13
Bulk/this.execute@src/mongo/shell/bulk_api.js:1163:21
DBCollection.prototype.deleteOne@src/mongo/shell/crud_api.js:375:17
@(shell):1:1

3)   findAndModify、findOneAndUpdate、findOneAndDelete 指令 ,指令操作失败

查找并更新指令
db.getCollection('umsg').findAndModify({id:1}, {$set:{a:1}})
查找单条数据并更新指令
db.getCollection('umsg').findOneAndUpdate({id:1}, {$set:{a:1}})
茶轴单条数据并删除指令
db.getCollection('umsg').findOneAndDelete({id:1}, {$set:{a:1}})


操作结果:

Failed to execute script.

Error:
Uncaught exception: Error: findAndModifyFailed failed: {
	"ok" : 0,
	"errmsg" : "Query for sharded findAndModify must contain the shard key",
	"code" : 61,
	"codeName" : "ShardKeyNotFound",
	"operationTime" : Timestamp(1710298791, 1),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1710298791, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	}
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DBCollection.prototype.findAndModify@src/mongo/shell/collection.js:725:15
@(shell):1:1

4)findOne和find查询指令,正常

db.getCollection('umsg').find({id:1})

db.getCollection('umsg').findOne({id:1})

结论:

      查找条件不一定要包含分片键(会去不同的分片上查询,效率低),修改到文档数据的指令操作条件都要包含分片键。

  • 27
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MongoDB的分片集群是一种将数据分布在多个服务器上的方式,以实现高可用性和横向扩展性。下面是一些关于MongoDB分片集群的常见问题和答案: 1. 什么是MongoDB的分片集群? MongoDB的分片集群是一种将数据分割成多个片段并分布在多个服务器上的方法。每个片段(shard)都是一个独立的MongoDB实例,可以存储一部分数据。通过将数据分散在多个片段上,可以实现数据的水平扩展和负载均衡。 2. 如何设置MongoDB的分片集群? 要设置MongoDB的分片集群,需要遵循以下步骤: a. 部署和配置一个或多个Config Server。Config Server用于存储集群的元数据,如分片范围和配置信息。 b. 部署和配置一个或多个mongos路由器。mongos路由器是客户端与分片集群交互的入口点。 c. 部署和配置一个或多个shard服务器。每个shard服务器都是一个独立的MongoDB实例,可以存储一部分数据。 d. 启动mongos路由器,并将其连接到Config Server和shard服务器。 e. 创建分片集合,并根据需要启用分片。 3. 分片是什么?如何选择分片分片是用来决定将数据分配到哪个片段的字段。选择合适的分片非常重要,以确保数据在分片集群中均匀分布。通常,一个好的分片应该满足以下条件: a. 数据均匀分布:分片的值应该能够在不同的分片之间平均分配。 b. 查询性能:选择经常被查询的字段作为分片,以便查询可以在单个片段上执行而不需要扫描整个集群。 c. 数据增长:选择一个能够支持数据增长的分片,以避免在未来需要重新分片。 4. 如何监控和管理MongoDB的分片集群? MongoDB提供了一些工具和功能来监控和管理分片集群。一些常见的方法包括: a. 使用mongos路由器的命令行工具或管理界面来管理集群配置、添加/删除shard以及监控性能指标。 b. 使用MongoDB的内置监控工具,如mongostat和mongotop,来监视集群的吞吐量、延迟和负载情况。 c. 使用第三方监控工具,如Prometheus、Grafana等,来获取更详细的指标和可视化。 这些是关于MongoDB分片集群的一些常见问题和答案。希望能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值