技术瓶颈?如何解决MongoDB超大块数据问题?

news2025/7/17 11:31:23

在这里插入图片描述

目录

    • 一、MongoDB服务器管理
      • 1、添加服务器
      • 2、修改分片中的服务器
      • 3、删除分片
    • 二、均衡器
    • 三、修改块的大小
    • 四、超大块
      • 1、分发超大块
      • 2、分发超大块步骤:
      • 3、避免出现超大块
      • 4、输出内容详解:
    • 五、系统分析器
    • 六、一些常见的辅助命令

大家好,我是哪吒,最近项目在使用MongoDB作为图片和文档的存储数据库,为啥不直接存MySQL里,还要搭个MongoDB集群,麻不麻烦?

让我们一起,一探究竟,继续学习解决MongoDB超大块数据问题,实现快速入门,丰富个人简历,提高面试level,给自己增加一点谈资,秒变面试小达人,BAT不是梦。

一、MongoDB服务器管理

1、添加服务器

可以在任何时间添加mongos进程,只要确保,它们的 --configdb选项指定了正确的配置服务器副本集,并且客户端可以立即与其建立连接。

2、修改分片中的服务器

要修改一个分片的成员,需要直接连接到该分片的主节点,并重新配置副本集。集群配置会检测到变更并自动更新 config.shards

3、删除分片

一般情况下,不应该从集群中删除分片,会给系统带来不必要的压力。

删除分片时,要确保均衡器的打开状态。

均衡器的作用是把要删除分片上的所有数据移动到其它分片,这个过程称为排空。可以通过 removeShard命令执行排空操作。

在这里插入图片描述

二、均衡器

可以通过 sh.setBalancerState(false)关闭均衡器。关闭均衡器不会将正在进行的过程停止,也就是说迁移过程不会立即停止。

通过db.locks.find({"_id","balancer"})["state"]查看均衡器是否关闭。0表示均衡器已关闭。

均衡过程会增加系统的负载,目标分片必须查询源分片的所有文档,并将文档插入目标分片的块中,然后源分片必须删除这些文档。

数据迁移是很消耗性能的,此时可以在config.settings集合中为均衡过程指定一个时间窗口。将其指定在一个闲暇时间执行。

如果设置了均衡窗口,应该对其进行监控,确保mongos能够在所分配的时间内保持集群的均衡。

均衡器使用块的数量而不是数据的大小作为度量。移动一个块被称为迁移,这是MongoDB平衡数据的方式。可能会存在一个大块的分片称为许多小分片迁移的目标。

三、修改块的大小

一个块可以存放数百万个文档,块越大,迁移到另一个分片所花费的时间就越长,默认情况下,块的大小为64MB。

但对于64MB的块,迁移时间太长了,为了加快迁移速度,可以减少块的大小。

比如将块的大小改为32MB。

db.settings.save({"_id","chunksize","value":32})

已经存在的块不会发生改变,自动拆分仅会在插入或更新时发生,拆分操作是无法恢复的,如果增加了块的大小,那么已经存在的块只会通过插入或更新来增长,直到它们达到新的大小。块大小的取值范围在1MB到1024MB。

这是一个集群范围的设置,会影响所有的集合和数据库。因此,如果一个集合需要较小的块,另一个集合需要较大的块,那么可能需要在这两个大小间取一个折中的值。

如果MongoDB的迁移过于频繁或者使用的文档太大,则可能需要增加块的大小。

四、超大块

一个块的所有数据都位于某个特定的分片上。如果最终这个分片拥有的块比其它分片多,那么MongoDB会将一些块移动到其它分片上。

当一个块大于 config.settings中所设置的最大块大小时,均衡器就不允许移动这个块了。这些不可拆分、不可移动的块被称为超大块

1、分发超大块

要解决超大块引起的集群不均衡问题,就必须将超大块均匀地分配到各个分片中。

2、分发超大块步骤:

  1. 关闭均衡器 sh.setBalancerState(false)
  2. 因为MongoDB不允许移动超过最大块大小的块,所以要暂时先增大块大小,使其超过现有的最大块块大小。记录下当时的块大小。db.settings.save({"_id","chunksize","value":maxInteger})
  3. 使用moveChunk命令移动分片中的超大块;
  4. 在源分片剩余的块上运行splitChunk命令,直到其块数量与目标分片块数量大致相同;
  5. 将块大小设置为其最初值;
  6. 开启均衡器

在这里插入图片描述

3、避免出现超大块

更改片键,使其拥有更细粒度的分片。

通过db.currentOp()查看当前操作,``db.currentOp()```最常见的用途是查找慢操作。

MongoDB Enterprise > db.currentOp()
{
        "inprog" : [
                {
                        "type" : "op",
                        "host" : "LAPTOP-P6QEH9UD:27017",
                        "desc" : "conn1",
                        "connectionId" : 1,
                        "client" : "127.0.0.1:50481",
                        "appName" : "MongoDB Shell",
                        "clientMetadata" : {
                                "application" : {
                                        "name" : "MongoDB Shell"
                                },
                                "driver" : {
                                        "name" : "MongoDB Internal Client",
                                        "version" : "5.0.14"
                                },
                                "os" : {
                                        "type" : "Windows",
                                        "name" : "Microsoft Windows 10",
                                        "architecture" : "x86_64",
                                        "version" : "10.0 (build 19044)"
                                }
                        },
                        "active" : true,
                        "currentOpTime" : "2023-02-07T23:12:23.086+08:00",
                        "threaded" : true,
                        "opid" : 422,
                        "lsid" : {
                                "id" : UUID("f83e33d1-9966-44a4-87de-817de0d804a3"),
                                "uid" : BinData(0,"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=")
                        },
                        "secs_running" : NumberLong(0),
                        "microsecs_running" : NumberLong(182),
                        "op" : "command",
                        "ns" : "admin.$cmd.aggregate",
                        "command" : {
                                "aggregate" : 1,
                                "pipeline" : [
                                        {
                                                "$currentOp" : {
                                                        "allUsers" : true,
                                                        "idleConnections" : false,
                                                        "truncateOps" : false
                                                }
                                        },
                                        {
                                                "$match" : {

                                                }
                                        }
                                ],
                                "cursor" : {

                                },
                                "lsid" : {
                                        "id" : UUID("f83e33d1-9966-44a4-87de-817de0d804a3")
                                },
                                "$readPreference" : {
                                        "mode" : "primaryPreferred"
                                },
                                "$db" : "admin"
                        },
                        "numYields" : 0,
                        "locks" : {

                        },
                        "waitingForLock" : false,
                        "lockStats" : {

                        },
                        "waitingForFlowControl" : false,
                        "flowControlStats" : {

                        }
                },
                {
                        "type" : "op",
                        "host" : "LAPTOP-P6QEH9UD:27017",
                        "desc" : "Checkpointer",
                        "active" : true,
                        "currentOpTime" : "2023-02-07T23:12:23.086+08:00",
                        "opid" : 3,
                        "op" : "none",
                        "ns" : "",
                        "command" : {

                        },
                        "numYields" : 0,
                        "locks" : {

                        },
                        "waitingForLock" : false,
                        "lockStats" : {

                        },
                        "waitingForFlowControl" : false,
                        "flowControlStats" : {

                        }
                },
                {
                        "type" : "op",
                        "host" : "LAPTOP-P6QEH9UD:27017",
                        "desc" : "JournalFlusher",
                        "active" : true,
                        "currentOpTime" : "2023-02-07T23:12:23.086+08:00",
                        "opid" : 419,
                        "op" : "none",
                        "ns" : "",
                        "command" : {

                        },
                        "numYields" : 0,
                        "locks" : {

                        },
                        "waitingForLock" : false,
                        "lockStats" : {

                        },
                        "waitingForFlowControl" : false,
                        "flowControlStats" : {

                        }
                }
        ],
        "ok" : 1
}

4、输出内容详解:

在这里插入图片描述

  1. opid,操作的唯一标识,可以使用这个字段来终止操作;
  2. active,操作是否正在进行,如果为false,意味着此操作已经让出或者正在等待其它操作交出锁;
  3. secs_running,操作的持续时间,可以使用这个字段查询耗时过长的操作;
  4. op,操作类型,通常为query、insert、update、remove;
  5. desc,客户端的标识符,可以与日志中的消息相关联;
  6. locks,描述操作所涉及的锁类型;
  7. waitingForLock,当前操作是否处于阻塞中并等待获取锁;
  8. numYields,操作释放锁以允许其它操作进行的次数。一个操作只有在其它操作进入队列并等待获取它的锁时才会让出自己的锁,如果没有操作处于waitingForLock状态,则当前操作不会让出锁;
  9. lockStats.timeAcquiringMiros,操作为了获取锁所花费的时间;

通过``db.currentOp()找到慢查询后,可以通过db.killOp(opid)```的方式将其终止。

并不是所有操作都可以被终止,只有当操作让出时,才能终止,因此,更新、查找、删除操作都可以被终止,但持有或等待锁的操作不能被终止。

如果MongoDB中的请求发生了堆积,那么这些写操作将堆积在操作系统的套接字缓冲区,当终止MongoDB正在运行的写操作时,MongoDB依旧会处理缓冲区的写操作。可以通过开启写入确认机制,保证每次写操作都要等前一个写操作完成后才能执行,而不是仅仅等到前一个写操作处于数据库服务器的缓冲区就开始下一次写入。

五、系统分析器

系统分析器可以提供大量关于耗时过长操作的信息,但系统分析器会严重的降低MongoDB的效率,因为每次写操作都会将其记录在system.profile中记录一下。每次读操作都必须等待system.profile写入完毕才行。

开启分析器:

MongoDB Enterprise > db.setProfilingLevel(2)
{ "was" : 0, "slowms" : 100, "sampleRate" : 1, "ok" : 1 }

slowms决定了在日志中打印慢速操作的阈值。比如slowms设置为100,那么每个耗时超过100毫秒的操作都会被记录在日志中,即使分析器是关闭的。

查询分析级别:

MongoDB Enterprise > db.getProfilingLevel()
2

重新启动MongoDB数据库会重置分析级别。

六、一些常见的辅助命令

通过Object.bsonsize函数获取其在磁盘中存储大小,单位是字节。

> Object.bsonsize(db.worker.find())
65194

使用mongotop统计哪些集合最繁忙。

使用mongotop --locks统计每个数据库的锁信息。

mongostat提供了整个服务器范围的信息。

在这里插入图片描述
在这里插入图片描述

Java学习路线总结,搬砖工逆袭Java架构师

10万字208道Java经典面试题总结(附答案)

Java基础教程系列

Java基础教程系列(进阶篇)

既然有MySQL了,为什么还要有MongoDB?

一次线上事故,我顿悟了MongoDB的精髓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/406323.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿里巴巴高并发架构,到底如何对抗双十一亿级并发流量

前言 我们知道,高并发代表着大流量,高并发系统设计的魅力就在于我们能够凭借自己的聪明才智设计巧妙的方案,从而抵抗巨大流量的冲击,带给用户更好的使用体验。这些方案好似能操纵流量,让流量更加平稳得被系统中的服务…

【Linux】网络编程套接字(中)

🎇Linux: 博客主页:一起去看日落吗分享博主的在Linux中学习到的知识和遇到的问题博主的能力有限,出现错误希望大家不吝赐教分享给大家一句我很喜欢的话: 看似不起波澜的日复一日,一定会在某一天让你看见坚持…

【Linux】第一座高山——进程地址空间

大家好我是沐曦希💕 文章目录一、什么是进程地址空间二、进程地址空间的管理1.区域划分和调整三、为什么存在进程地址空间四、写在最后一、什么是进程地址空间 我们在学习C/C的动态内存空间,习惯把地址空间划分为几个区域: 但是这并不是真的的地址空间…

2023年网络安全趋势

数据安全越来越重要。 我国《数据安全法》提出“建立健全数据安全治理体系”,各地区部门均在探索和简历数据分类分级、重要数据识别与重点保护制度。 数据安全治理不仅是一系列技术应用或产品,更是包括组织构建、规范制定、技术支撑等要素共同完成数据…

node - 下载安装指定版本

文章目录前言一、什么是Node?二、安装1.打开 Node官网2.点击DOWNLOADS3.点击 All download options4.修改地址栏中对应的版本号修改版本号后选择需要的文件下载即可 ![在这里插入图片描述](https://img-blog.csdnimg.cn/049c33e7ebad4114937f23447c5d8c71.png)前言 node 下载…

python实现——处理Excel表格(超详细)

目录xls和xlsx基本操作1:用openpyxl模块打开Excel文档,查看所有sheet表2.1:通过sheet名称获取表格2.2:获取活动表3.1:获取表格的尺寸4.1:获取单元格中的数据4.2:获取单元格的行、列、坐标5&…

Linux- 系统随你玩之--玩出花活的命令浏览器上

文章目录1、背景2、命令浏览器2.1、命令浏览器介绍2.2、特点2.3 常用功能选项3、实操3.1、使用 wget 下载文件3.2、 断点续传3.3、镜像整个站点4、 总结1、背景 一位友人说他有台服务器,需要下载一个文件,但是没有视窗界面与下载工具,怎么办…

Cobalt Strike----(1)

团队服务器 Cobalt Strike 分为客户端组件和服务器组件。服务器组件,也就是团队服务器,是Beacon payload 的控制器,也是 Cobalt Strike 社会工程功能的托管主机。团队服务器还存储由Cobalt Strike 收集的数据,并管理日志记录。Cob…

猿创征文|【Typescript】搭建TS的编译环境

🍳作者:贤蛋大眼萌,一名很普通但不想普通的程序媛\color{#FF0000}{贤蛋 大眼萌 ,一名很普通但不想普通的程序媛}贤蛋大眼萌,一名很普通但不想普通的程序媛🤳 🙊语录:多一些不为什么的…

vue修改 el-input 输入框默认背景色

vue修改 el-input 输入框默认背景色 实际项目需要修改默认的 输入框背景色 &#xff0c;因为原本的默认框背景色设置属性 :disabledtrue 之后显示不是很清晰&#xff0c;所以需要配置相应的规则 原本的不能修改的输入样式&#xff0c;显示的不是很清晰 加上样式之后的效果 <…

自学黑客,一般人我劝你还是算了吧

写在开篇 笔者本人 17 年就读于一所普通的本科学校&#xff0c;20 年 6 月在三年经验的时候顺利通过校招实习面试进入大厂&#xff0c;现就职于某大厂安全联合实验室。 我为啥说自学黑客&#xff0c;一般人我还是劝你算了吧。因为我就是那个不一般的人。 首先我谈下对黑客&…

十大经典排序算法(上)

目录 1.1冒泡排序 1. 算法步骤 3.什么时候最快 4. 什么时候最慢 5.代码实现 1.2选择排序 1. 算法步骤 2. 动图演示 3.代码实现 1.3 插入排序 1. 算法步骤 2. 动图演示 3. 算法实现 1.4 希尔排序 1. 算法步骤 2. 动图演示 3.代码实现 1.5 归并排序 1. 算法步骤 2…

Android: 彻底搞懂Lifecycle——使用篇

系列文章目录 第一章 Android: 彻底搞懂Lifecycle——使用篇 第二章 Android: 彻底搞懂Lifcycle——原理篇 文章目录系列文章目录前言一、Lifecycle是什么&#xff1f;1. 应用场景2. 示例二、Lifecycle使用1. 泳&#xff08;用&#xff09;裤&#xff08;库&#xff09;第一步…

PyQt5(一) PyQt5安装及配置,从文件夹读取图片并显示,模拟生成素描图像

目录 一、环境配置 1.1 安装PyQt5 1.2 安装Qt工具包 1.3 配置环境变量 1.4 测试PyQt5 1.5 配置PyCharm 二、QtDesigner 窗口简单介绍 2.1 初始界面 2.2 控件介绍 三、相关函数 3.1 读取文件函数 3.1.1 打开本地图片 3.1.2 保存图片到本地 3.1.3 打开文件夹 3.1.4 打…

微信小程序|基于小程序+C#制作一个考试答题小程序

基于小程序+C#制作一个考试答题小程序打破传统线下考试答题的边界线问题,使考试不用再局限与某个统一的场所,只要有设备,哪里都能考试。 一、小程序

【动态规划】最长上升子序列、最大子数组和题解及代码实现

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…

功能测试用例多次录制后,我丢掉了selenium,选择龙测AI-TestOps云平台

目录一、如何使用龙测AI-TestOps云平台1、进入龙测AI-TestOps云平台2、新建项目3、新建流程图4、创建任务5、查看任务状态6、查看报告、图片7、下载流程图、测试报告、excel用例二、龙测AI-TestOps云平台AI功能介绍1、NLP2、视频AI转流程图三、总结功能测试用例多次录制后&…

写着简单跑得又快的数据库语言 SPL

数据库语言的目标SQL为什么不行SPL为什么能行 数据库语言的目标 要说清这个目标&#xff0c;先要理解数据库是做什么的。 数据库这个软件&#xff0c;名字中有个“库”字&#xff0c;会让人觉得它主要是为了存储的。其实不然&#xff0c;数据库实现的重要功能有两条&#xf…

【微信小程序】按钮还能这样用?

目录 &#x1f353;button 按钮的基本使用 &#x1f349;各种神奇的按钮 &#x1f353;button 按钮的基本使用 按钮组件 功能比 HTML 中的 button 按钮丰富 通过 open-type 属性可以调用微信提供的各种功能&#xff08;客服、转发、获取用户授权、获取用户信息等&#xff09;…

占有统治地位的Transformer究竟是什么

讲个有趣的小故事我高二那年从乙班考入了甲班&#xff0c;对于那时的我 偏科英语最高只有108班级平均英语成绩125暴躁难为人女英语老师&#xff0c;使我上英语课时战战兢兢。英语老师很时尚&#xff0c;喜欢搞花里胡哨的词语让我们放松&#xff0c;也很尊重我虽然暴躁但维护着我…