Mongodb常见问题

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Mongodb常见问题
⼀.数据库级锁
MongoDB的锁机制和⼀般关系数据库如 MySQL(InnoDB), Oracle 有很⼤的差异,InnoDB 和 Oracle 能提供⾏级粒度锁,⽽ MongoDB 2.x 只能提供库级粒度锁,这意味着当 MongoDB ⼀个写锁处于占⽤状态时,其它的读写操作都得⼲等。

MongoDB 使⽤的是“readers-writer”锁,可以⽀持并发但有很⼤的局限性,当⼀个读锁存在,许多读操作可以使⽤这把锁,然⽽, 当⼀个写锁的存在,⼀个单⼀的写操作会 exclusively 持有该锁,同时其它读,写操作不能使⽤共享这个锁;举个例⼦,假设⼀个集合⾥有 10 个⽂档,多个 update 操作不能并发在这个集合上,即使是更新不同的⽂档。

初看起来库级锁在⼤并发环境下有严重的问题,但是 MongoDB 依然能够保持⼤并发量和⾼性能,这是因为 MongoDB 的锁粒度虽然很粗放,但是在锁处理机制和关系数据库锁有很⼤差异,主要表现在:
MongoDB 没有完整事务⽀持,操作原⼦性只到单个 document 级别,所以通常操作粒度⽐较⼩;
MongoDB 锁实际占⽤时间是内存数据计算和变更时间,通常很快;
MongoDB 锁有⼀种临时放弃机制,当出现需要等待慢速 IO 读写数据时,可以先临时放弃,等 IO 完成之后再重新获取锁
在MongoDB 3.0版本中锁的粒度就变得更细了,除了全局锁、数据库锁还加⼊了集合锁,⽽且对于WiredTiger存储引擎和MMAPv1存储引擎⽽⾔两者之间的锁机制也有不同。

 WiredTiger:对于⼤部分的读写操作,WiredTiger使⽤乐观锁。

WiredTiger对于全局、数据库、集合级别只会使⽤意向锁。

当存储引擎检测到两个操作之间的冲突,⼀个写冲突导致MongoDB透明地重试写操作。

⼀些全局操作,跟2.2版本⼀样还是会需要全局锁,例如,删除⼀个集合,那么仍然还是需要⼀个互斥的数据库锁的。

如何查看锁的状态
db.serverStatus()
db.currentOp()
mongotop
mongostat
产⽣数据库锁的操作
操作锁类型
Issue a query Read lock
Get more data from a cursor Read lock
Insert data Write lock
Remove data Write lock
Update data Write lock
Map-reduce Read lock and write lock, unless operations are specified as non-atomic. Portions of map-reduce jobs can run concurrently. Create an index Building an index in the foreground, which is the default, locks the database for extended periods of time.
db.eval() Write lock.
⼆.原⼦操作但不⽀持事务
所谓原⼦操作就是要么对这个⽂档操作全部成功,要么全部失败,不会出现查询到的⽂档没有保存完整的情况
mongodb不⽀持事务,所以,在你的项⽬中应⽤时,要注意这点。

⽆论什么设计,都不要要求mongodb保证数据的完整性。

但是mongodb 对单个⽂档的操作提供了许多原⼦操作,⽐如⽂档的保存,修改(包括对单个⽂档修改多个字段),删除等,都是原⼦操作。

三.插⼊删除更新瞬时完成
插⼊删除更新都是瞬时完成的,不需要等待数据库响应。

这不属于异步操作,发出指令后就不在操⼼之后的操作。

客户端将⽂档发给服务器端,就⼲别的去了,不等待响应。

优点速度快,缺点是操作发送到服务器之后,不管后续服务器是否操作成功,有可能丢数据,(⽇志,⽤户点击,或数据分析可以接受,但付费系统不适合)
安全性⾼的付费系统,可采⽤安全操作在执⾏完成之后需调⽤GETLastERROR检查执⾏是否成功,然后抛出异常,由前段进⾏处理
四.单个⽂件⼤⼩限制16M
习惯了使⽤mongodb中⽂档(document)存储⽅式, 可以灵活的将⼤量数据存⼊⼀个集合中的⼀条⽂档中, 这样可以减少⼤量的数据冗余, 不会出现关系性数据库, 如myslq中表的某⼀列的数据冗余. 不过这样存储虽好, 但其实也会存在⼀定的问题, 也就是mongodb中的⼤⼩限制, 即单个⽂档⼤⼩不能超过16M
对遇到过这个问题的⼈来说, 这个16M的'概念'很好理解, ⽽对于还未意识到这个问题的⼈来说, 这个'坑' 可能会让你花时间都难以发现, 因为这⼜要牵扯到mongodb的另⼀个存储机制 ---- ⽆返回码. 在 < mongodb 权威指南> ⼀书中, 作者称之为离弦之箭. 什么意思呢, 就是mongodb的
插⼊,删除等操作, 客户端向数据库发出请求之后, 是不需要等待数据库返回操作是否成功的返回结果. 这也是mongodb插⼊,更新等操作速度快的原因. 这就导致, 当单个⽂件超过16M之后, 程序并不会报错, 但此时, 数据已经⽆法插⼊数据库了。

相关文档
最新文档