MongoDB分片实战:性能和优化

MongoDB慢查询优化实战:从Profiling到索引优化的完整指南 本文详细介绍了MongoDB慢查询优化的完整流程,从使用Profiling工具诊断慢查询,到分析执行计划、设计高效索引,再到查询重构技巧。通过实战案例展示了如何优化电商平台的商品搜索、订单查询等场景,帮助开发者提升MongoDB数据库性能,解决高并发下的慢查询问题。 阅读详情


插入、查询和更新

插入:MongoDB会根据片键和conifg中的信息写入到指定的分片上。

读取:以下内容摘抄自《深入学习MongoDB》

关于读取:上一节故障恢复中已经有所验证。

更新:如果要更新单个文档一定要在片键中使用片键(update的第一个参数)。我们现在OSSP10.bizuser(已经在_id上进行哈希分片)中插入一条记录:

1.    mongos> use OSSP10
2.    switched to db OSSP10
3.    mongos> db.bizuser.insert({"Uid":10001,"Name":"zhanjindong","Age":23})
4.    db.bizuser.find({"Name":"zhanjindong"})
5.    { "_id" : ObjectId("5160dd378bc15cdb61a131fc"), "Uid" : 10001, "Name" : "zhanjindong", "Age" : 23 }

 尝试根据Name来更新这个文档会得到一个错误:

1.    mongos> db.bizuser.update({"Name":"zhanjindong"},{"$set":{"Sex":0}})
2.    For non-multi updates, must have _id or full shard key ({ _id: "hashed" }) in query

根据片键来更新则不会有任何问题:

1.    mongos> db.bizuser.update({"_id":ObjectId("5160dd378bc15cdb61a131fc")},{"$set":{"Sex":0}})
2.    mongos> db.bizuser.find({"Name":"zhanjindong"})
3.    { "Age" : 23, "Name" : "zhanjindong", "Sex" : 0, "Uid" : 10001, "_id" : ObjectId("5160dd378bc15cdb61a131fc") }

但是批量更新中可以用任何条件:

1.    mongos> db.bizuser.insert({"Uid":10002,"Name":"dsfan","Age":23})
2.    mongos> db.bizuser.insert({"Uid":10003,"Name":"junling","Age":25})
3.    mongos> db.bizuser.update({"Age":23},{"$set":{"Sex":1}},false,true)
4.    mongos> db.bizuser.find({"Age":23})
5.    { "Age" : 23, "Name" : "zhanjindong", "Sex" : 1, "Uid" : 10001, "_id" : ObjectId("5160dd378bc15cdb61a131fc") }
6.    { "Age" : 23, "Name" : "dsfan", "Sex" : 1, "Uid" : 10002, "_id" : ObjectId("5160e2af8bc15cdb61a131fd") }

之所以更新单个文档会有这个强制限制是因为如果不指定片键,MongoDB会将更新操作路由到所有分片上,则无法保证更新操作在整个集群中只操作了一次(不同的分片上可能存在相同Uid的数据),指定片键后,更新操作只会路由到某一个分片上,MongoDB能保证只会更新在这个分片找到的第一个符合条件的文档。下面提到的唯一索引问题和这个问题本质是一样的。批量更新没有这个限制很好理解。

排序:在需要调用sort()来查询排序后的结果的时候,以分片Key的最左边的字段为依据,Mongos可以按照预先排序的结果来查询最少的分片,并且将结果信息返回给调用者。这样会花最少的时间和资源代价。 相反,如果在利用sort()来排序的时候,排序所依据的字段不是最左侧(起始)的分片Key,那么Mongos将不得不并行的将查询请求传递给每一个分片,然后将各个分片返回的结果合并之后再返回请求方。这个会增加Mongos的额外的负担。

片键和索引

 

所有分片的集合在片键上都必须建索引,这是MongoDB自动执行的,所以如果选择某个字段作为片键但是基本不在这个字段做查询那么等于浪费了一个索引,而增加一个索引总是会使得插入操作变慢。

唯一索引问题 如果集群在_id上进行了分片,则无法再在其他字段上建立唯一索引:

复制代码
1.    mongos> db.bizuser.ensureIndex( { "Uid": 1 }, { unique: true } )
2.    {
3.            "err" : "can't use unique indexes with sharding  ns:OSSP10.bizuser key: { Uid: 1.0 }",
4.            "code" : 10205,
5.            "n" : 0,
6.            "ok" : 1
7.    }
复制代码

之所以出现这个错误是因为MongoDB无法保证集群中除了片键意外其他字段的唯一性(验证了CAP理论),能保证片键的唯一性是因为文档根据片键进行切分,一个特定的文档只属于一个分片,MongoDB只要保证它在那个分片上唯一就在整个集群中唯一。

如果实现分片集群上的文档唯一性一种方法是在创建片键的时候指定它的唯一性:

复制代码
1.    mongos> use admin
2.    switched to db admin
3.    mongos> db.runCommand({"enablesharding":"test"})
4.    mongos> db.runCommand({"shardcollection":"test.users","key":{"Uid":1},unique:true})
5.    mongos> use test
6.    switched to db test
7.    mongos> db.users.insert({"Uid":1001})
8.    mongos> db.users.insert({"Uid":1001})
9.    E11000 duplicate key error index: test.users.$Uid_1  dup key: { : 1001.0 }
复制代码

事实上就是建立了一个唯一索引:

Note:更多关于分片集群上唯一索引问题参见《MongoDB Manual》page468。

哈希索引:

 

哈希索引支持使用任何单个字段包括内嵌文档,但是不能使用复合的字段,因此创建哈希索引的时候也只能指定一个字段:

1.    mongos> db.runCommand({"shardcollection":"mydb.mycollection","key":{"Uid":"hashed","Name":"hashed"}})
2.    {
3.            "ok" : 0,
4.            "errmsg" : "hashed shard keys currently only support single field keys"
5.    }

片键的选择

片键的选择对于整个分片集群的性能至关重要,上一节对分片集群中的读、写和更新操作已经做了说明,选择片键的时候要考虑到读自身应用的读写模式和新增分片的情况。

小基数片键:如果某个片键一共只有N个值,那最多只能有N个数据块,也最多只有个N个分片。则随着数据量的增大会出现非常大的但不可分割的chunk。如果打算使用小基数片键的原因是需要在那个字段上进行大量的查询,请使用组合片键,并确保第二个字段有非常多的不同值。

1.    mongos> db.runCommand({"enablesharding":"mydb"})
2.    db.runCommand({"shardcollection":"mydb.mycollection","key":{"x":1}})
3.    mongos> use mydb
4.    switched to db mydb
5.    mongos> var arrayObj = new Array("A","B","C")
6.    mongos> for(i=0;i<333333;i++){ db.mycollection.insert({"x":arrayObj[i%3],"y":"zhanjindong2","Age":13,"Date":new Date()}); }

无论再插入多少条数据,我们查看一下config.chunks会发现只会有三个块,三个块最多只能使用三个分片:

1.    { "_id" : "mydb.mycollection-x_MinKey", "lastmod" : { "t" : 2, "i" : 0 }, "lastmodEpoch" : ObjectId("51613a843999888c2cd63f41"), "ns" : "mydb.mycollection", "min" : { "x" : { "$minKey" : 1 } }, "max" : { "x" : "A" }, "shard" : "shard0001" }
2.    { "_id" : "mydb.mycollection-x_\"A\"", "lastmod" : { "t" : 3, "i" : 0 }, "lastmodEpoch" : ObjectId("51613a843999888c2cd63f41"), "ns" : "mydb.mycollection", "min" : { "x" : "A" }, "max" : { "x" : "C" }, "shard" : "shard0002" }
3.    { "_id" : "mydb.mycollection-x_\"C\"", "lastmod" : { "t" : 3, "i" : 1 }, "lastmodEpoch" : ObjectId("51613a843999888c2cd63f41"), "ns" : "mydb.mycollection", "min" : { "x" : "C" }, "max" : { "x" : { "$maxKey" : 1 } }, "shard" : "shard0000" }

递增的片键:使用递增的分片的好处是数据的“局部性”,使得将最新产生的数据放在一起,对于大部分应用来说访问新的数据比访问老的数据更频繁,这就使得被访问的数据尽快能的都放在内存中,提升读的性能。这类的片键比如时间戳、日期、ObjectId、自增的主键(比如从sqlserver中导入的数据)。但是这样会导致新的文档总是被插入到“最后”一个分片(块)上去,这种片键创造了一个单一且不可分散的热点,不具有写分散性。

随机片键:随机片键(比如MD5)最终会使数据块均匀分布在各个分片上,一般观点会以为这是一个很好的选择,解决了递增片键不具有写分散的问题,但是正因为是随机性会导致每次读取都可能访问不同的块,导致不断将数据从硬盘读到内存中,磁盘IO通常会很慢。

举个例子:比如mydb.mycollection集合记录下面这样的用户信息,Uid是一个比较随机的值:

{
    Uid:12313477994,
    Name:zhanjindong,
    Age:23,
    CreatedTime:2013-04-08 15:23:24.122
}

如果我们对Uid进行分片,那么同一分钟创建的用户信息可能被写入到了不同的块上(通常在不同的分片上),这有很好的分散性。但如果我们想根据时间来查找这一分钟产生的所有新用户,则mongos必须将查询操作路由给所有的分片的多个块上。但如果我们根据时间进行分片,那么这一分钟内新增用户可能都写入到一个块中,那么上面的查询操作只需要路由给一个分片上的一个块就完成了。

组合片键:一个理想的片键是同时拥有递增片键和随即片键的优点,这点很难做到关键是要理解自己的数据然后做出平衡。通常需要组合片键达到这种效果:

准升序键加搜索键 {coarselyAscending:1,search:1}

其中coarselyAscending每个值最好能对应几十到几百个数据块(比如以月为单位或天为单位),serach键应当是应用程序中通常都会依据其进行查询的字段,比如GUID。

注意:serach字段不能是升序字段,不然整个复合片键就下降为升序片键。这个字段应该具备非升序、分布随机基数适当的特点。

事实上,上面这种复合片键中的第一个字段保证了拥有数据局部性,第二字段则保证了查询的隔离性。同时因为第二个字段具备分布随机的特性因此又一定程度的拥有随机片键的特点。

哈希片键:对于哈希片键的选择官方文档中有很明确的说明:

选择哈希分片最大好处就是使得数据在各个节点分布比较均匀。2.2.5 Hased Shaeding一节对哈希片键的使用有简单的测试。

注意:建立哈希片键的时候不能指定唯一:

1.    mongos> db.runCommand({"shardcollection":"OSSP10.Devices","key":{"DeviceId":"hashed"},unique:true})
2.    { "ok" : 0, "errmsg" : "hashed shard keys cannot be declared unique." }

基于范围vs基于哈希

什么时候选择基于范围的分片,什么时候选择基于哈希的分片呢?官方文档的说明很少:

基于哈希的分片通常可以使得集群中数据分布的更加均匀。但是考虑具体应用情况可能有所不同,下面是引用10gen的产品市场总监Kelly Stirman的一段话:

当使用基于范围的分片,如果你的应用程序基于一个分片键范围请求数据,那么这些查询会被路由到合适的分片,通常只有一个分片,特殊情况下可能有一些分片。在一个使用了基于哈希分片的系统中,同样的查询会将请求路由到更多的分片,可能是所有的分片。理想情况下,我们希望查询会被路由到一个单独的分片或者尽可能少的分片,因为这样的扩展能力要比将所有的查询路由到所有的分片好。因此,如果你非常理解自己的数据和查询,那么基于范围的分片可能是最好的选择。

出处:http://www.infoq.com/news/2013/03/mongodb-2-4

总结:对MongoDB 单条记录的访问比较随机时,可以考虑采用哈希分片,否则范围分片可能会更好。

Balancer

小的chunkSize能保证各个分片数据分布更均匀,但导致迁移更频繁。MongoDB为了尽量减少对性能的影响对块迁移的算法有很多的优化措施:2.2.2节对Migration Threshold有简单的说明,另外balancer进程能聪明的避开整个集群高峰时期。

可以定时的执行数据迁移:

1.    use config
2.    db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "23:00", stop: "6:00"

删除定时数据迁移设置:

1.    use config
2.    db.settings.update({ _id : "balancer" }, { $unset : { activeWindow : true } })

开启和关闭balancer:

1.    sh.startBalancer()
2.    sh.stopBalancer()

如果正在有数据进行迁移的话,stopBalancer会等待迁移结束,可以通过下面的方式查看当前是否有迁移在进行:

1.    use config
2.    while( db.locks.findOne({_id: "balancer"}).state ) {
3.    print("waiting..."); sleep(1000);

Note:更多关于balancer信息参见《MongoDB-Manual》page 455

手动分片

MongoDB自动分片都是先从一个分片上的一个块开始的,然后通过不断的分裂和迁移来达到数据的切分和平衡,依赖机器自动执行的好处是简单,但是代价就是性能(虽然balancer已经做了很多优化)。因此MongoDB允许进行手动切分,手动切分有下面两个步骤(官方示例):

1、用split命令对空集合进行手动的切分。

复制代码
1.    mongos> use admin
2.    switched to db admin
3.    mongos> db.runCommand({"enablesharding":"myapp"})
4.    mongos> db.runCommand({"shardcollection":"myapp.users","key":{"email":1}})
5.    for ( var x=97; x<97+26; x++ ){
6.    for( var y=97; y<97+26; y+=6 ) {
7.    var prefix = String.fromCharCode(x) + String.fromCharCode(y);
8.    db.runCommand( { split : "myapp.users" , middle : { email : prefix } } );
9.           }
10.    }
复制代码

注意:

最好只对一个空的集合进行预分割,如果对存在数据的集合进行预分割,MongoDB会先进行自动分割,然后在尝试进行手动的分割。这可能导致大规模的分割和低效的平横。

2、利用moveChunk命令手动的移动分割的块:

复制代码
1.    var shServer = [ "sh0.example.net", "sh1.example.net", "sh2.example.net", "sh3.example.net", "sh4.example.net" ];
2.    for ( var x=97; x<97+26; x++ ){
3.     for( var y=97; y<97+26; y+=6 ) {
4.      var prefix = String.fromCharCode(x) + String.fromCharCode(y);
5.      db.adminCommand({moveChunk : "myapp.users", find : {email : prefix}, to : shServer[(y-97)/6]})
6.     }
7.    }
复制代码

或者利用balancer自动平衡。

要很好进行手动的切分必须了解片键的范围,如果片键是一个随机值比如哈希分片,则很难进行手动的预分割,其次及时进行了预分割随后插入数据块分裂和迁移(没关闭balancer)依然会存在。

结论:预分割和手动分片适合于将片键范围确定的数据初始化到分片集群中。

其他

journal

如果机器是32位的话在配置分片集群启动shard的时候跟上—journal参数。因为64位默认是开启journal的,32位没有。

NUMA CPU架构问题

NUMA是多核心CPU架构中的一种,其全称为Non-Uniform MemoryAccess,简单来说就是在多核心CPU中,机器的物理内存是分配给各个核的。2.1.1的表中可以看到192.168.71.43这台机器的CPU架构正是NUMA。

在NUMA架构的机器上启动mongodb进程需要特别注意。我们先以正常的方式启动mongodb,然后登录,如下:

3.    ./bin/mongod --dbpath data/ --logpath log/mongodb.log –fork
4.    ./bin/mongo

你会看到类似下面的警告信息:

1.    . Server has startup warnings: 
2.    Mon Apr  1 20:49:25.900 [initandlisten] 
3.    Mon Apr  1 20:49:25.900 [initandlisten] ** WARNING: You are running on a NUMA machine.
4.    Mon Apr  1 20:49:25.900 [initandlisten] **          We suggest launching mongod like this to avoid performance problems:
5.    Mon Apr  1 20:49:25.900 [initandlisten] **              numactl --interleave=all mongod [other options]
6.    Mon Apr  1 20:49:25.900 [initandlisten]

按照提示我们应该向下面这样启动mongodb进程,在启动命令前加上numactl --interleave选项:

1.    numactl --interleave=all ./bin/mongod --dbpath data/ --logpath log/mongodb.log --fork

这时再登录mongodb就不会再有警告信息了。

以上只是就问题解决问题,至于在NUMA架构的CPU上非正常启动mongodb会带来什么样的性能影响还没做验证,网上可以搜到一些别人使用的经验。官方的文档(参看MongoDB Documentation, Release 2.4.1 12.8.1 MongoDB on NUMA Hardware)中有如下说明:

简单做下解释,NUMA架构中每个核访问分配给自己的内存会比分配给其他核内存要快,有下面几种访问控制策略:

  • 缺省(default):总是在本地节点分配(分配在当前进程运行的节点上);
  • 绑定(bind):强制分配到指定节点上;
  • 交叉(interleave):在所有节点或者指定的节点上交织分配;
  • 优先(preferred):在指定节点上分配,失败则在其他节点上分配。

但是目前mongodb在这种架构下工作的不是很好,--interleave=all就是禁用NUMA为每个核单独分配内存的机制。

突破极限:MongoDB 16MB 文档限制的实战优化策略 本文深入探讨了MongoDB 16MB文档限制的成因及优化策略,包括文档结构优化、引用替代内嵌、分块存储等实用方法。通过真实案例展示了如何有效应对大文档挑战,提升数据库性能,特别适合面临MongoDB存储限制的开发者和架构师参考。 阅读详情

相关推荐

开源CMDB与资产管理平台对比报告

本文对比分析了9款主流开源CMDB平台,从集成能力、功能完整性和多语言支持三个维度进行评测。重点介绍了VeCMDB、蓝鲸CMDB、WeCMDB和OpsAny等国产平台的特色:VeCMDB以动态模型和自动发现见长;蓝鲸CMDB适合超大规模企业级应用;WeCMDB专注金融级高并发场景;OpsAny提供一体化运维解决方案。针对不同规模企业给出选型建议:中小团队推荐Snipe-IT等轻量工具;大型企业建议蓝鲸或WeCMDB;需国产化适配的可选VeCMDB或OpsAny。文章还特别指出iTop、GLPI等适合ITIL

huang0612123的博客 1081

MongoDB分片实战(三):性能和优化

插入、查询和更新 插入:MongoDB会根据片键和conifg中的信息写入到指定的分片上。 读取:以下内容摘抄自《深入学习MongoDB》 关于读取:上一节故障恢复中已经有所验证。 更新:如果要更新单个文档一定要在片键中使用片键(update的第一个参数)。我们现在OSSP10.bizuser(已经在_id上进行哈希分片)中插入一条记录: 1. mongos&gt; use...

weixin_34216036的博客 548

Python爬虫实战:5分钟搞定Boss直聘数据抓取(附完整代理IP配置)

本文详细介绍了如何使用Python爬虫高效抓取Boss直聘的招聘数据,包括环境配置、反爬策略、数据采集与存储、数据分析等完整流程。通过实战案例,帮助开发者快速掌握招聘市场数据抓取技术,为职业决策提供数据支持。

weixin_30832143的博客 349

百万级高并发mongodb集群性能数十倍提升优化实践(上篇)

背景 线上某集群峰值TPS超过100万/秒左右(主要为写流量,读流量很低),峰值tps几乎已经到达集群上限,同时平均时延也超过100ms,随着读写流量的进一步增加,时延抖动严重影响业务可用性。该集群采用mongodb天然的分片模式架构,数据均衡的分布于各个分片中,添加片键启用分片功能后实现完美的负载均衡。集群每个节点流量监控如下图所示: 从上图可以看出集群流量比较大,峰值已经突破120万/...

github_39037504的博客 3275

[Python + UG NX 二次开发新手教程] 第五课 采用Python / UF 开发模式

在 NX 二次开发里看到的“UF”是的缩写,它是 Siemens 提供的集合,也是整个 NX Open 体系里最贴近内核、历史最悠久的一套接口。相当于 NX 的“系统调用”——只要 NX 能做的事,UF 几乎都能调得动。Siemens 从 NX 12 开始把原来的 C 接口(UF)全部打包进了官方 Python 模块,命名空间为 NXOpen.UF.*,所以只要 NX 安装目录里带了 NXOpen\UF 子模块,就能在 Python 里直接调用 UF 函数。

温良 1007

KEPServerEX 6 之驱动协议(UDD)实战 HTTP协议对接OpenWeatherMap天气 API全流程指南

本文分享了基于 KEPServerEX 6 的通用设备驱动(UDD)对接OpenWeatherMap天气API的实战方案。该方案针对工业物联网场景进行了深度优化,具有动态城市切换、运行时热配置、老旧JS引擎兼容等核心特性。文章详细介绍了从环境准备、脚本部署到Tag配置的全流程,重点解析了Legacy JS语法适配、Float类型安全处理等关键实现细节,并提供了完整的避坑指南和故障排查方法。该方案经过生产环境验证,可稳定实现气象数据采集与动态切换功能,适用于SCADA/MES系统集成场景。

-雲飛兄-博客 718

mongoDB笔记

1、文档型数据库mongodb: 它是一个内存数据库,数据都是放在内存里面的。 对数据的操作大部分都在内存中,但mongodb并不是单纯的内存数据库。 持久化方式: mongodb的所有数据实际上是存放在硬盘的,所有要操作的数据通过mmap的方式映射到内存某个区域内。 然后,mongodb就在这块区域里面进行数据修改,避免了零碎的硬盘操作。 至于mmap上的内容flush到硬盘就是操作...

sinat_27143551的博客 198

软件集成:Simulink与STM32联合开发

本文首先通过一个简单的Simulink模型生成代码,然后将代码copy到一个STM32工程中去编译软件。最后将软件下载到STM32F407中,通过串口输出Simulink计算的结果。 阅读本文需要有一定的STM32开发调试经验和Simulink代码生成经验。关于Simulink代码生成可以参考博主的专栏《Simulink代码生成》。 文章目录1 问题引入2 集成方案3 建模与编程过程3.1 Simulink模型搭建3.2 代码生成配置3.3 STM32工程搭建3.4 STM32的main.c文件修改3.4.

u013288925的博客 2万+

Mongodb——基本原理与常见优化

Mongodb——数据结构 Collections 在mongodb中叫做集合,是文档的集合,内部存储一行又一行不规则的数据;相当于mysql的表 Document 存储在集合中一行又一行的数据 Document——松散结构特性 mongodb是一个模式自由的NOSQL,不像其他RDBMS一样需要预先定义Schema而且所有的数据都整齐划一,mongodb的document是BSON格式,松散的 Document——松散数据策略(背景) 对于有些update,比如对array新增元素等,会导致

weixin_44275259的博客 1043

结构优化软件:OptiStruct_(11).拓扑优化

在OptiStruct中,设计空间可以通过定义设计区域来实现。设计区域是结构中可以进行材料变化的部分。几何区域:通过几何选择工具选择特定的区域。网格区域:通过网格选择工具选择特定的单元。假设我们有一个简单的梁结构模型,网格文件为beam.fem。我们希望在梁的中部进行拓扑优化,以减轻重量并保持刚度。

kkchenjj的博客 1372

DSI3协议介绍

分布式系统接口(DSI)是一种通用且功能强大的总线协议,旨在将多个遥感器和执行器设备互连到中央控制模块。该网络的主要目标应用是汽车安全系统。这种应用的一些特点是需要低成本、高鲁棒性、中速互连,仅限于两根导线。此外,它必须具有故障安全性、确定性和良好的EMC特性。即使具有所有级别的智能和可编程性的设备都可以连接到网络,远程设备也必须能够通过简单的状态机实现。由于模块尺寸非常重要,因此中央模块和远程单元中的最小组件至关重要。

汽车电子软件领域知识分享 1万+

难题来了:分库分表后,查询太慢了,如何优化?

难题来了:分库分表后,查询太慢了,如何优化?

浩浩的博客 1495

手把手教你完成YOLOv11 PySide6目标检测界面搭建,使用Qt6设计YOLOv11检测系统,前台系统+后台管理系统开发实战,可用于大论文凑工作量或毕设必备,全网最详细教程

目标检测是计算机视觉中的重要任务,广泛应用于安防监控、自动驾驶、智能家居等领域。YOLO系列模型由于其高效的检测速度和较高的准确率,成为目标检测任务的首选算法之一。本项目结合 YOLOv11 与 PySide6,构建了一个图形化界面,便于用户进行目标检测的操作和展示,实现对图片、视频和摄像头的实时目标检测,不仅可以用于大论文的工作量展示,还可以作为毕业设计。系统功能有:目标检测程序实现图片/视频/摄像头检测,AI 问答界面(deepseek大模型接口,流式输出)、退出登录、界面保存登录状态、个人信息修改等

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 7015

MongoDB 性能优化:索引设计与分片集群配置实战

MongoDB 作为主流 NoSQL 数据库,以灵活的文档模型和高扩展性成为海量数据存储的首选,但在数据量突破百万 / 千万级后,容易出现查询延迟高、存储容量不足、写入吞吐量受限等问题。性能优化的核心逻辑是 “精准提速 + 横向扩展”:索引设计聚焦 “减少数据扫描范围”,解决查询效率问题;分片集群聚焦 “数据分布式存储”,解决海量数据存储与高并发写入问题。两者结合可覆盖 80% 以上的 MongoDB 性能场景,本文将从实战角度拆解全流程优化方案。

2501_93877737的博客 325

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

MongoDB分片集群性能测试实战:分片键选型与查询路由优化

数据库性能优化是系统扩展的核心挑战,分片集群作为解决海量数据存储与查询的关键方案,其数据分布均匀性和查询路由效率直接影响集群整体吞吐。分片键设计决定了数据在集群中的分布形态,精准路由与广播查询之间的性能差距可达数倍,而索引匹配和mongos路由行为则是压测中必须验证的关键环节。通过JMeter压测,可以量化不同分片键下的数据倾斜程度、路由延迟和吞吐瓶颈,为生产环境扩容提供可靠依据。本文基于MongoDB分片集群的真实性能测试,剖析复合分片键的选型逻辑、数据分布验证方法以及查询路由效率的对比分析,并结合JMe

weixin_31315567的博客 255

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

MongoDB分片实战(三):性能和优化 插入、查询和更新

插入、查询和更新 插入:MongoDB会根据片键和conifg中的信息写入到指定的分片上。 读取:以下内容摘抄自《深入学习MongoDB》 关于读取:上一节故障恢复中已经有所验证。 更新:如果要更新单个文档一定要在片键中使用片键(update的第一个参数)。我们现在OSSP10.bizuser(已经在_id上进行哈希分片)中插入一条记录: 1. mongos> use OS

wackycrazy的专栏 7012

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

mongdo 减少访问量_MongoDB分片实战(三):性能和优化

插入、查询和更新插入:MongoDB会根据片键和conifg中的信息写入到指定的分片上。读取:以下内容摘抄自《深入学习MongoDB》关于读取:上一节故障恢复中已经有所验证。更新:如果要更新单个文档一定要在片键中使用片键(update的第一个参数)。我们现在OSSP10.bizuser(已经在_id上进行哈希分片)中插入一条记录:1. mongos>use OSSP102. sw...

weixin_29031057的博客 287

MongoDB千万级数据聚合查询性能优化实战

数据库聚合查询是数据分析的核心操作,其本质是通过多阶段管道对数据进行转换与计算。MongoDB聚合框架采用流式处理模型,每个阶段都会遍历前序输出的全部文档,当处理千万级数据时容易出现内存溢出、磁盘IO过载等性能瓶颈。通过合理设计复合索引(遵循等值字段优先、范围字段次之、排序分组字段最后的顺序)、优化聚合管道(尽早过滤减少数据量、合并冗余阶段)以及系统级调优(内存配置、分片策略),可显著提升查询效率。以电商订单分析为例,经过索引优化和管道重构后,聚合查询从58秒降至0.48秒,特别适合处理实时分析、时间序列等

weixin_28683689的博客 236

搭建高可用mongodb集群

搭建高可用mongodb集群(四)—— 分片 http://www.kankanews.com/ICkengine/archives/127201.shtml

Make progress step by step everyday..... 772
上一篇: 火狐(Firefox)插件Yslow使用心得
下一篇: back to top 功能实现
rtnull
博客等级 码龄16年 5粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值