您现在的位置是:首页 >技术杂谈 >mongodb并发和锁的问题总结网站首页技术杂谈
mongodb并发和锁的问题总结
MongoDB 允许多个客户端读写相同的数据。为了确保一致性,MongoDB 使用锁定和并发控制
来防止客户端同时修改相同的数据。对单个文档的写入要么完整发生,要么根本不发生,并且客户端始终看到一致的数据。
1、MongoDB 如何管理并发?
MongoDB 使用读写锁,允许并发读者共享访问资源,例如数据库或集合。
WiredTiger 使用乐观并发控制。 WiredTiger 仅在全局、数据库和集合级别使用意图锁。当存储引擎检测到两个操作之间的冲突时,会引发写入冲突,导致 MongoDB 透明地重试该操作。
2、MongoDB 使用什么类型的锁定?
MongoDB 使用多粒度锁定,允许操作锁定在全局、数据库或集合级别,并允许各个存储引擎在集合级别以下(例如,在 WiredTiger 中的文档级别)实现自己的并发控制。
除了用于读取的共享 (S) 锁定模式和用于写入操作的独占 (X) 锁定模式之外,意向共享 (IS) 和意向独占 (IX) 模式表示使用更细粒度的锁读取或写入资源的意向. 当以特定粒度锁定时,所有更高级别都使用意向锁锁定。
例如,当锁定一个集合用于写入(使用模式 X)时,相应的数据库锁和全局锁都必须以意向排他 (IX) 模式锁定。单个数据库可以同时在 IS 和 IX 模式下加锁,但排他(X)锁不能与任何其他模式共存,共享(S)锁只能与意向共享(IS)锁共存。
锁是公平的,读写的锁请求按顺序排队。但是,为了优化吞吐量,当一个锁请求被授予时,所有其他兼容的锁请求将同时被授予,可能会在执行冲突的锁请求之前释放锁。例如,考虑刚刚释放 X 锁并且冲突队列包含这些锁的情况:
IS → IS → X → X → S → IS
在严格的先进先出 (FIFO) 排序中,只会授予前两个 IS 模式。相反,MongoDB 实际上会授予所有 IS 和 S 模式,一旦它们全部耗尽,它将授予 X,即使同时有新的 IS 或 S 请求排队。由于授权总是将队列中的所有其他请求移到前面,因此任何请求都不可能饿死。
3、MongoDB 中的锁有多细化?
对于大多数读写操作,WiredTiger 使用乐观的并发控制。WiredTiger 仅在全局、数据库和集合级别使用意向锁。当存储引擎检测到两个操作之间存在冲突时,其中一个将引发写入冲突,从而导致 MongoDB 透明地重试该操作。
一些全局操作,通常是涉及多个数据库的短期操作,仍然需要全局“实例范围”锁。其他一些操作,如collMod
,仍然需要独占数据库锁。
4、读取或写入操作是否会产生锁定?
在某些情况下,读取和写入操作可以放弃它们的锁。
长时间运行的读写操作(例如查询、更新和删除)在许多情况下都会产生锁定。MongoDB 操作还可以在影响多个文档的写入操作中的各个文档修改之间产生锁定。
对于支持文档级并发控制的存储引擎,例如WiredTiger,在访问存储时不需要屈服,因为意向锁在全局、数据库和集合级别持有,不会阻止其他读者和作者。但是,操作会定期产生,例如:
- 避免长期存储事务,因为这些事务可能需要在内存中保存大量数据;
- 作为中断点,以便您可以终止长时间运行的操作;
- 允许需要独占访问集合的操作,例如索引/集合删除和创建。