深入解析MongoDB中的锁机制

目录

一、MongoDB简介

二、MongoDB锁机制

三、锁的实践影响

        3.1 高并发写入导致的写锁案例


一、MongoDB简介

       MongoDB 作为一种非关系型文档数据库,在现代应用中扮演着极其重要的角色,尤其在处理大规模、高并发、灵活数据模型的场景下。MongoDB 具有如下特点:

  • MongoDB 拥有丰富的数据模型,而且文档没有固定的模式,这为扩展性提供了便利
  • 高可扩展性:MongoDB 设计之初就考虑到了扩展性,支持分片(sharding),可以轻松跨越多台服务器分配数据和处理请求,从而实现水平扩展。这对于处理海量数据等场景只管重要。
  • 高性能:MongoDB 支持各种索引,能够加锁数据的查询;采用异步非阻塞 I/O 模型,避免了线程的同步等待,从而实现高效的读写性能;水平扩展能力也能提高性能,通过添加分片可来分散负载,保持高性能;采用预分配数据机制来提高性能,当要写入新数据时,不会等到写入时才去请求磁盘空间,而是提前预留一定空间;同时还支持批量操作,减少交互来提升性能。
  • 高可用性:使用副本集来对数据进行冗余保存,当主节点故障时,数据也不会丢失。

        MongoDB 作为一个多用户、多线程的 NoSQL 数据库,确保其在高并发访问下数据的一致性和完整性至关重要。如果没有有效的并发控制机制,可能会产生如脏读、不接重复度、幻读等一系列问题。

        那如何确保 MongoDB 在并发环境下能够保障数据一致性和完整性呢?那就是 MongoDB 的锁机制。

二、MongoDB锁机制

        MongoDB 锁机制是其并发控制的重要组成部分,目的是为了确保多线程多用户访问下数据的完整性和一致性,主要分类两大类:MMAPv1 引擎的锁机制和 WiredTiger 引擎的锁机制。

        在使用 MMAPv1 存储引擎的 MongoDB 版本中,全局锁时其主要的并发控制手段。全局锁有两种模式:

  • 读锁:允许多个读操作共享,但组织任何写操作
  • 写锁:独占锁,一旦获取将组织其他读写操作,直至锁释放

        WiredTiger 引擎使用了更细粒度的锁机制,主要为:

  • 文档锁:锁定单个文档,允许多个并发读操作,但写操作会互斥。这大大减少了锁竞争,提高了并发写入能力,从而使得在高并发场景下也能保持较好的性能。
  • 多版本并发控制(MVCC):WiredTiger 实现了一种 MVCC 机制,为每个事务创建数据的多个版本。这样,读操作可以不受写操作的影响,看到事务开始时的一致性视图,而写操作则在新版本上进行,直到事务提交后才会对外可见。这增强了系统的并发能力,同时保证了事务的隔离性。
  • 范围锁:在某些情况下,为了保持数据一致性,WiredTiger可能会锁定一个文档范围,防止其他操作修改该范围内的数据。
  • 乐观锁:除了传统的锁机制,WiredTiger还采用了乐观锁策略,尤其在处理读写操作时。乐观锁依赖于文档版本控制,每个文档都有一个内部版本号。写操作前先读取版本号,写入时检查版本号是否改变,若未变则成功,否则重试。这种方式减少了锁的使用,提高了并发效率

三、锁的实践影响

        WiredTiger 提供文档级锁,减少了写操作之间的锁竞争,提高了并发性能。支持压缩,能够减少存储空间需求和I/O操作,进而提升读写速度。使用多版本并发控制(MVCC),允许读操作不阻塞写操作,提升了读取性能。支持事务,增强了数据一致性。

        但是有更高的内存需求,因为其缓存策略会占用较多内存。在极端并发写入场景下,虽然概率较低,但仍有可能遇到锁竞争导致的性能瓶颈。

        MongoDB 使用 WiredTiger 存储引擎时,具备一定的死锁检测和处理能力,旨在减少乃至避免死锁对系统的影响。

        WiredTiger 存储引擎具有内置的死锁检测机制。当事务等待资源超过一定时间阈值,引擎会尝试检测是否存在死锁情况。如果检测到死锁,WiredTiger 会选择一个或多个事务进行回滚,通常是那些影响较小或者等待时间较长的事务,从而解除死锁状态。

        可以通过以下方式避免死锁

  • 尽可能缩短事务运行时间,减少对锁的持有时间,可以降低与其他事务冲突的概率。使用原子操作和批量操作可以减少单独锁的次数和持续时间。
  • 设计事务时,尽量按照一致的顺序访问资源,减少循环等待的可能性。例如,如果多个事务总是按照相同的资源访问顺序执行,那么死锁就不会发生。
  • 在应用层面实施适当的并发控制策略,如乐观锁或悲观锁的合理使用,以及合理的重试逻辑,可以在遇到锁冲突时优雅地处理,避免直接导致死锁。

        3.1 高并发写入导致的写锁案例

        在使用MongoDB 时,由于有高并发的写入,突然出现了大量获取链接的报错,具体报错信息如下:

org.springframework.data.mongodb.UncategorizedMongoDbException: Too many operations are already waiting for a connection. Max number of operations (maxWaitQueueSize) of 500 has been exceeded.; nested exception is com.mongodb.MongoWaitQueueFullException: Too many operations are already waiting for a connection. Max number of operations (maxWaitQueueSize) of 500 has been exceeded.at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:138)at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:2902)at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:587)at org.springframework.data.mongodb.core.MongoTemplate.doUpdate(MongoTemplate.java:1636)at org.springframework.data.mongodb.core.MongoTemplate.upsert(MongoTemplate.java:1570)

        通过监控发现是高并发写入引起了写锁,导致某些操作长时间占用写锁,最终获取不到连接导致出现上面的问题。下面来分析下原因。

        并发写入操作频繁且锁等待时间较长时,连接可能会被长时间占用,无法及时归还到连接池,导致可用连接耗尽。那如何来解决呢?

        我们最后如何处理的呢?其实也很简单,可以采用批量写入来减少锁竞争或锁等待时间,或者采用异步的方式来进行写入操作。

        还需要检查下设置的连接池是否合理,可以根据情况适当的调整连接池的大小。

往期经典推荐

Sentinel与Nacos强强联合,构建微服务稳定性基石的重要实践_sentinel和nacos-CSDN博客

云原生:Kubernetes下的Java应用部署实战详解_kubernetes部署java-CSDN博客

全面解读MongoDB高可用、高性能与高可扩展架构-CSDN博客

深入剖析MongoDB集群架构设计_mongodb 架构-CSDN博客

TiDB存储引擎TiKV揭秘-CSDN博客

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

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

相关文章

【STM32】µC/OS-III多任务程序

【STM32】C/OS-III多任务程序 一、探究目的二、探究原理2.1 嵌入式操作系统2.1.1 RTOS2.1.2 前后台系统2.1.2 C/OS-III 三、探究过程(实验一)3.1 μC/OS-III环境配置3.1.1 CubeMX配置3.1.2 下载μC/OS-III源码3.1.3 KEIL环境配置3.1.4 KEIL代码更改3.1.5…

大模型应用:基于Golang + 大模型构建简易的电商售前对话服务

1.背景 某X互联网电商公司为了解决当前大量用户的售前咨询问题,需要建设一个不需要客服介入的简易电商售前机器人,用于回答用户的售前问题,并给出基本可靠的咨询回答。 当前大模型如gpt、baichuan、文心等均有开放使用的OpenAPI接口&#xf…

ROS学习记录:栅格地图格式

一、机器人导航所使用的地图数据,就是ROS导航软件包里的map_server节点在话题 /map 中发布的消息数据,消息类型是nav_msgs消息包中的OccupancyGrid,它的中文意思的占据栅格,是一种正方形小格子组成的地图。 二、对障碍物进行俯视&…

1-什么是护网行动

1.什么是护网行动 2016年,公安部会同民航局、国家电网组织开展了“护网2016”网络安全攻防演习活动。同年,《网络安全法》颁布,出台网络安全演练相关规定:关键信息基础设施的运营者应“制定网络安全事件应急预案,并定期进行演练”…

Django框架中Ajax GET与POST请求的实战应用

系列文章目录 以下几篇侧重点为JavaScript内容0.0 JavaScript入门宝典:核心知识全攻略(上)JavaScript入门宝典:核心知识全攻略(下)Django框架中Ajax GET与POST请求的实战应用VSCode调试揭秘:L…

电子电气架构——车载诊断DTC一文通

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无需有人关注你。你必须承认自己的价值,你不能站在他人的角度来反对自己。人生在世,最怕的就是把别人的眼光当成自己生活的唯一标…

springcloud第4季 springcloud-gateway网关filter案例场景

一 filter作用 1.1 filter搭建流程 1.1.1 网关配置 1.1.2 服务提供者 1.1.3 测试验证 1.启动consul 2.启动zipkin 3.启动应用微服务 4.进行访问: http://localhost:6666/pay/wg/filter 1.2 其他常见API RemoveRequestHeadersec-fetch-site # 删除请求…

[word] word表格如何设置外框线和内框线 #媒体#笔记

word表格如何设置外框线和内框线 点击表格的左上角按钮从而选中表格 点击边框按钮边上的下拉箭头,选择边框和底纹 点击颜色边上的下拉箭头,选择红色 点击取消掉中间的边框,只保留外围边框 点击颜色边上的下拉箭头,选择另外一个颜…

Linux CGroup资源限制(概念限制进程CPU使用)

Linux CGroup资源限制(详解) 最近客户认为我们程序占用cpu过高,希望我们限制,排查之后发现是因为程序频繁gc导致,为了精细化、灵活的的限制,想到了使用Linux CGroup。 0 前置知识 ①概念及作用 官网&#…

Llama模型家族之使用 ReFT技术对 Llama-3 进行微调(三)为 ReFT 微调准备模型及数据集

LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 (一) 基于 LlaMA 3 LangGraph 在windows本地部署大模型 (二) 基于 LlaMA 3 LangGraph 在windows本地部署大模型 (三) 基于 LlaMA…

逻辑这回事(四)----时序分析与时序优化

基本时序参数 图1.1 D触发器结构 图1.2 D触发器时序 时钟clk采样数据D时,Tsu表示数据前边沿距离时钟上升沿的时间,MicTsu表示时钟clk能够稳定采样数据D的所要求时间,Th表示数据后边沿距离时钟上升沿的时间,MicTh表示时钟clk采样…

Nginx(openresty) 查看连接数和并发送

1 通过浏览器查看 #修改nginx配置文件 location /status {stub_status on;access_log off;allow 192.168.50.0/24;deny all;} #重新加载 sudo /usr/local/openresty/nginx/sbin/nginx -s reloadActive connections //当前 Nginx 当前处理的活动连接数。 server accepts handl…

如何在springboot项目中使用Mybatisplus

文章目录 1.mybatisplus的作用2.mybatisplus使用流程2.1pom.xml文件中增加依赖(点击右上角蓝色按钮下载依赖)2.2navicat新建数据库,增加application.properties数据库配置2.3 启动类添加注解,增加mapper包操作数据库2.5添加实体类…

【python报错】TypeError: dict.get() takes no keyword arguments

【Python报错】TypeError: dict.get() takes no keyword arguments 在Python中,字典(dict)是一种非常灵活的数据结构,用于存储键值对。dict.get()方法是用来从字典中获取与给定键(key)相关联的值&#xff0…

【安装笔记-20240608-Linux-免费空间之三维主机免费空间】

安装笔记-系列文章目录 安装笔记-20240608-Linux-免费空间之三维主机免费空间 文章目录 安装笔记-系列文章目录安装笔记-20240608-Linux-免费空间之三维主机免费空间 前言一、软件介绍名称:三维主机免费空间主页官方介绍 二、安装步骤测试版本:openwrt-…

03-3.5.1~4 特殊矩阵的压缩存储

👋 Hi, I’m Beast Cheng👀 I’m interested in photography, hiking, landscape…🌱 I’m currently learning python, javascript, kotlin…📫 How to reach me --> 458290771qq.com 喜欢《数据结构》部分笔记的小伙伴可以订…

HarmonyOS(二十三)——HTTP请求实战一个可切换的头条列表

在前一篇文章,我们已经知道如何实现一个http请求的完整流程,今天就用官方列子实战一个简单的新闻列表。进一步掌握ArkTS的声明式开发范式,数据请求,常用系统组件以及touch事件的使用。 主要包含以下功能: 数据请求。…

Spark 性能调优——分布式计算

前言 分布式计算的精髓,在于如何把抽象的计算流图,转化为实实在在的分布式计算任务,然后以并行计算的方式交付执行。今天这一讲,我们就来聊一聊,Spark 是如何实现分布式计算的。分布式计算的实现,离不开两个…

2024 年最新 Python 基于百度智能云实现短语音识别详细教程

百度智能云语音识别 采用国际领先的流式端到端语音语言一体化建模算法,将语音快速准确识别为文字,支持手机应用语音交互、语音内容分析、机器人对话等场景。百度短语音识别可以将 60 秒以下的音频识别为文字。适用于语音对话、语音控制、语音输入等场景…

【kubernetes】k8s集群中的ingress(对外服务)规则详解

目录 一、Ingress 简介 1.1service的作用 1.2外部访问方案 (四种)🌹🌹🌹 部署externalIPs 1.3Ingress 是什么 二、Ingress 组成🌹🌹🌹 三、Ingress 工作原理🐱&#x1f…