在mongodb文档中,它说:
从版本2.2开始,MongoDB在每个数据库的基础上为大多数读和写操作实现锁。一些全局操作,通常是涉及多个数据库的短暂操作,仍然需要全局“实例”宽锁。在2.2之前,每个单神实例只有一个“全局”锁。
这是否意味着,在我有3个连接到mongodb的情况下://localhost/test来自网络上运行的不同应用程序--一次只能写一个?还是只是每个连接?
IOW:是每个连接,还是整个/test数据库在写入时都被锁定了?
发布于 2013-07-03 19:51:00
不是每个连接,而是每个mongod。换句话说,锁将存在于到该服务器上的test数据库的所有连接中。
它也是一个读/写锁,所以如果正在写,那么读必须等待,否则MongoDB怎么知道它是一致的读?
但是,我要指出的是,MongoDB锁与您获得的SQL/普通事务性锁非常不同,通常在平均更新之间保持一个锁的时间约为1微秒。
发布于 2013-07-03 23:04:42
MongoDB锁定是不同的
在MongoDB中锁定不像在关系数据库管理系统中锁定一样,因此需要进行一些解释。在MongoDB的早期版本中,只有一个全局读取器/写入器锁存器。从MongoDB 2.2开始,每个数据库都有一个读取器/写入器锁存器。
读写器闩锁
锁存器是多读取器,单一作者,而且是作家贪婪的.这意味着:
请注意,我称之为“闩锁”,而不是“锁”。这是因为它是轻量级的,并且在正确设计的模式中,写锁保持在十几微秒左右。有关读者-写入器锁定的更多信息,请参见这里。
在MongoDB中,您可以同时运行任意数量的查询:只要相关数据在内存中,它们都会满足,而不会发生锁定冲突。
原子文档更新
回想一下,在MongoDB中,事务级别是单个文档。对单个文档的所有更新都是原子化的。MongoDB通过保存写入锁存来实现这一点,只要它需要更新RAM中的单个文档。如果有任何运行缓慢的操作(特别是,如果需要从磁盘分页文档或索引条目),则该操作将产生写锁。当操作产生锁存器时,则下一个排队操作可以继续进行。
这意味着对单个数据库中所有文档的写入都会被序列化。如果您的模式设计很差,而且编写过程需要很长时间,那么这可能是一个问题,但是在设计正确的模式中,锁定并不是一个问题。
作家-贪婪
再多说几句关于作家贪婪的话:
一次只有一个作者可以持有锁存器;多个读者一次可以持有锁存器。在一个简单的实现中,如果只有一个阅读器在运行,作者可能会无限期地挨饿。为了避免这种情况,在MongoDB实现中,一旦任何单个线程对特定的闩锁发出写请求,
实际的行为是复杂的,因为这种贪婪的行为与屈服的方式是不明显的。回想一下,从第2.2版开始,每个数据库都有一个单独的锁存器,因此写入数据库'A‘中的任何集合将获得一个单独的锁存,而不是写入数据库'B’中的任何集合。
具体问题
关于具体问题:
虽然这听起来可能是一个很大的性能问题,但在实践中并没有放慢速度。有了一个设计得当的模式和一个典型的工作负载,MongoDB将在任何数据库的锁百分比超过50%之前饱和磁盘I/O容量--即使是SSD。
据我所知,容量最高的MongoDB集群目前每秒执行200万次写操作。
发布于 2015-03-04 18:07:36
Mongo3.0现在支持集合级锁定.
除此之外,Mongo还创建了一个允许创建存储引擎的API。Mongo 3.0配备了2个存储引擎:
MongoDB 3.0发行说明
WiredTiger
https://stackoverflow.com/questions/17456671
复制相似问题