对MongoDB的一些评论
一直以来,我对MongoDB的感觉都是推广力道比较足,解决的问题有限。但是最近推出MongoDB的服务商越来越多了,这说明用户越来越多了,这让我颇奇怪,于是我仔细看看了MongoDB的文档。
MongoDB果然是一个文档数据库,其提供树形结构的存储,查询以及部分字段的全文索引,就像其web上给出的例子一样,blog类似的系统使用该数据库可能是合适的。闲话不说,下面从功能,性能,可用性,扩展性方面看看MongoDB。
功能:
1. K-V存储,其中V可以是结构化文档,所以V里可以是递归的K-V结构,所以将传统数据库的一行存成一个K-V是可以的(下面均以行进行解释)
2. 支持单行的写入,修改,查询;其中所有的修改都只能是一步完成的,不提供显式的事务控制,这是一个很大的不足。比如两个人同时更新一个doc,一个加入field A,另一个加入field B,则最终结果如何呢?
3. 支持大对象存储(Grid-FS)
4. 支持在各列上建立索引和组合索引,并对某些字段可以建立类全文索引(就是单词本身的索引,不关心内容,比如hold 和 held是两个完全不同的词)
5. 支持非常多的SQL语法,可以说,这大大降低了从MySql到MongoDB的学习和迁移成本,因为对大部分开发者而言,数据库就是SQL。
6. 支持服务端javascript脚本执行:这个功能不错,可以减少出口网络流量
性能和可用性:
1. 从文档介绍来看,MongoDB为其每个doc obj预留了一定的空间,如果之后该obj的update超过了这个空间,则会造成内部doc obj的重新分配和排序,这个会造成写入性能的下降
2. MongoDB为了解决数据安全性,在V1.8之后使用了journaling日志,而且为了高可用性,每个replica都要写日志(如果不是每个replica都写日志的话,假设primary 的磁盘坏掉了,那么数据就丢失了),这必然造成性能的下降。
3. MongoDB使用BTree做索引,这可能存在并发性的问题(当然有concurrent BTree,但是很复杂,查不到MongoDB是否使用了的消息)
可扩展性:
1. 当数据量变大的时候,MongoDB可以通过一些命令进行数据sharding,但是根据MongoDB的架构来看,这个时候是要做数据拷贝的,而且在这个过程中可能无法进行服务(snapshot看起来功能有限)。不过在大部分时候这个问题也并不严重,有多少人会常常扩容呢?
2. 多个replica本来是可以分担读流量的,但是如果使用非primary replica来读的话,那么就不能保证强一致性(使用secondOK来读取数据,满足eventually consitent ),我觉得这会让应用很为难。
3. MongoDB的架构上来看,其将机器的资源进行了硬绑定,也就是存储能力和计算能力绑在一起了,这意味着如果有两个应用,他们一个对存储量大,不常访问,一个是存储量小,常常访问,他们无法放在一个MongoDB instance上,因为存储和计算能力不能分开进行scale,这意味着MongoDB搭建起来的service成本不大可能降低很低。
整体来看,MongoDB对SQL和索引的内在支持还是不错的,但是其对事务的支持不明晰,性能和数据安全方面也做得不够好,可扩展性也不必MySql容易哪里去,而且也没有重量级的成功先例,我觉得MongoDB优势不大,很难做成一个大的服务。