MongoDB锁定写入的级别是多少?(或:"每个连接"是什么意思

nic*_*ler 58 concurrency locking mongodb

在mongodb文档中,它说:

从2.2版本开始,MongoDB在每个数据库的基础上实现了大多数读写操作的锁.一些全局操作(通常是涉及多个数据库的短期操作)仍然需要全局"实例"广泛锁定.在2.2之前,每个mongod实例只有一个"全局"锁.

这是否意味着在我拥有3个与mongodb:// localhost/test的连接的情况下来自网络上运行的不同应用程序 - 一次只能写一个?或者只是每个连接?

IOW:它是每个连接,还是整个/测试数据库在写入时被锁定?

Wil*_*m Z 240

MongoDB锁定是不同的

在MongoDB中锁定不像锁定RDBMS那样工作,因此需要进行一些解释.在早期版本的MongoDB中,只有一个全局读/写锁存器.从MongoDB 2.2开始,每个数据库都有一个读/写锁存器.

读者 - 作家闩锁

锁存器是多读者,单一写入者,并且是作家贪婪的.这意味着:

  • 数据库上可以有无限数量的同时读取器
  • 在任何一个数据库中的任何集合中一次只能有一个编写器(稍后会详细介绍)
  • 作家封杀了读者
  • 通过"作家贪婪",我的意思是一旦写入请求进入,所有读者都被阻止,直到写入完成(稍后将详细介绍)

请注意,我称之为"闩锁"而不是"锁定".这是因为它是轻量级的,并且在正确设计的模式中,写锁定保持在十几个微秒的量级.有关读者 - 作者锁定的更多信息,请参见此处

在MongoDB中,您可以根据需要运行任意数量的同步查询:只要相关数据在RAM中,它们都将得到满足而不会发生锁定冲突.

原子文档更新

回想一下,在MongoDB中,事务级别是单个文档.对单个文档的所有更新都是Atomic.MongoDB通过只保留更新RAM中的单个文档所需的写锁存器来实现这一点.如果存在任何缓慢运行的操作(特别是,如果需要从磁盘中分页文档或索引条目),则该操作将产生写锁存器.当操作产生锁存器时,则可以继续下一个排队操作.

这意味着对单个数据库中所有文档的写入进行序列化.如果您的架构设计很差,并且您的写入需要很长时间,那么这可能是一个问题,但在正确设计的架构中,锁定不是问题.

作家贪婪

关于作家贪婪的几句话:

只有一个作家可以同时握住闩锁; 多个读卡器可以一次握住闩锁.在一个天真的实现中,如果有一个读者在运行,作者可能会无限期地饿死.为了避免这种情况,在MongoDB实现中,一旦任何单个线程对特定锁存器发出写请求

  • 所有后续需要该锁存器的读卡器都会阻塞
  • 那位作家将等到所有当前的读者都完成
  • 写入器将获取写锁存器,执行其工作,然后释放写锁存器
  • 所有排队的读者现在都将继续

实际行为是复杂的,因为这种作家贪婪的行为与屈服的方式相互作用是非显而易见的.回想一下,从2.2版开始,每个数据库都有一个单独的锁存器,因此写入数据库'A'中的任何集合将获得一个单独的锁存器,而不是写入数据库'B'中的任何集合.

具体问题

关于具体问题:

  • 锁(实际上是锁存器)由MongoDB内核保留,只要更新单个文档即可
  • 如果您有多个连接进入MongoDB,并且每个连接正在执行一系列写入,则锁存器将基于每个数据库保留,只要该写入完成所需的时间
  • 执行写入(更新/插入/删除)的多个连接将全部交错

虽然这听起来像是一个很大的性能问题,但在实践中它并没有减慢速度.通过适当设计的架构和典型的工作负载,MongoDB将使磁盘I/O容量饱和 - 即使是SSD - 在任何数据库的锁定百分比超过50%之前.

我所知道的容量最高的MongoDB集群目前每秒执行200万次写入.

  • 甚至死亡并不能阻止这个人帮助别人!RIP威廉 (16认同)
  • 对于那些想知道威廉发生了什么的人,请在这里阅读:http://blog.mongodb.org/post/99566492653/announcing-the-william-zola-outstanding.RIP (16认同)
  • @FredMériot目前它将在数据库级别阻止它,但文档级锁定已经在dev分支中.是的,读者操作可以阻止写入,MongoDB无法一致地读取正在写入的内容 (2认同)

Sam*_*aye 37

它不是每个连接,它是每个mongod.换句话说,锁将存在test于该服务器上与数据库的所有连接上.

它也是一个读/写锁,所以如果发生写,那么读必须等待,否则MongoDB怎么知道它是一致的读?

但是我应该提到MongoDB锁与你得到的SQL /普通事务锁非常不同,通常锁定将在平均更新之间保持大约一微秒.

  • `通常锁定将保持大约一微秒`如果您持有一微秒的锁定,那么根据物理定律,您不能保证写入耐用性**. (3认同)
  • 截至2015年,没有持续时间为1μs的持久设备,如果您释放锁定的时间不足,则该值不会持续存在. (3认同)

小智 20

Mongo 3.0现在支持集合级锁定.

除此之外,现在Mongo创建了一个允许创建存储引擎的API.Mongo 3.0附带2个存储引擎:

  1. MMAPv1:默认存储引擎和以前版本中使用的引擎.附带集合级锁定.
  2. WiredTiger:新的存储引擎,带有文档级锁定和压缩功能.(仅适用于64位版本)

MongoDB 3.0发行说明

WiredTiger


Muh*_*Ali 10

我知道这个问题已经很老了,但仍然有些人感到困惑....

从MongoDB 3.0开始,WiredTiger存储引擎(使用文档级并发)在64位版本中可用.

WiredTiger使用文档级并发控制进行写操作.因此,多个客户端可以同时修改集合的不同文档.

对于大多数读写操作,WiredTiger使用乐观并发控制.WiredTiger仅在全局,数据库和集合级别使用意图锁.当存储引擎检测到两个操作之间的冲突时,会发生写入冲突,导致MongoDB透明地重试该操作.

一些全局操作(通常是涉及多个数据库的短期操作)仍然需要全局"实例范围"锁定.其他一些操作(例如删除集合)仍需要独占数据库锁.

文档级并发