明确两者定位
MongoDB和Elasticsearch都属于NoSQL范畴的数据库,且都属于文档型数据存储数据库。
所以这两者的众多功能和特性高度重合, 但其实两者定位还是有所不同。
MongoDB是文档型数据库, 提供数据存储和管理服务。
Elasticsearch作为一个搜索引擎,定位是提供数据检索服务,也就是说重点是全文索引,即模糊匹配。
因此,Elasticsearch的设计会有所偏重,比如Mapping不可变,带来的代价就是es不特别擅长作为纯文档数据的管理者, es可以从其他数据源同步数据过来提供全文检索和查询,不特别擅长自己对数据进行存储和管理。
MongoDB有多个存储引擎可以选择, 而且MongoDB不仅看重数据的分析, 对数据的管理同样看重, 总的来说MongoDB更倾向于数据的存储和管理, 可以作为数据源对外提供。
Elasticsearch则有很多插件可以使用,相对来讲Elasticsearch更倾向于数据的查询, 一般情况下elasticsearch仅作为数据检索服务和数据分析平台, 不直接作为源数据管理者.
所以,如果系统中已有mongodb或其他数据库作为主要数据存储,而Elasticsearch主要负责从其中获取部分数据提供快速全文检索即可,即mongdob+Elasticsearch的方案.
此文我更想阐述的是,当项目考虑物理资源、运维成本等方面限制时,不想同时引入两套数据库时,二者只能选择一个时,我们选哪个呢??
全文检索的需求
首先,要仔细思考项目需求中,是否存在对全文检索的需求,如果存在,检索的条件是否复杂?是否很花式?检索的性能要求是否非常高?
如果答案都是yes,那么基本上可以确认就得选Elasticsearch了,一票否决mongodb。
Mongodb是可以满足基本的模糊查询功能的,我们在实际项目中,3个节点Mongodb集群内存有4000万业务数据,在一个业务内容上用regex模糊查询一个关键词,只模糊查前100条,基本可以1秒内返回。
但是更高级一点的模糊查询就很难支持了,并且涉及查询count总量时就非常慢,经常10秒以上才能返回结果。
所以评估项目是否对全文检索有比较高的需求要重点考量。
字段是否经常变换
如果业务重点在于数据的增删改查,全文检索的要求不高,那么Mongodb可能更适合。
比如,电商业务一个基本的功能模块就是存储各种品类的商品信息,各种商品的特性和参数各异,MongoDB灵活的文档模型非常适合于这类业务。由于商品的品类繁多,存入集合中的每一种商品在字段上都有差异,并且未来还会添加新品类的商品。
这种数据字段预期未来会经常变动,显然mongodb更好,ES字段变动时处理起来比较麻烦,需要经常变更mapping,代价很大,一般需要重新写入一个新的index,做reindexing来处理,在数据量达到一亿以上时,需要大半天才能完成,并且对线上写入的业务是有一定影响的。
所以对于数据结构经常频繁变化,一个集合中存储多种字段不同的数据时,用monggodb会更好!
硬件资源方面
如果从资源占用方面角度看,MongoDB可以支持存储文件类型的数据, 作为数据库也有数据压缩能力, es则因为大量的索引存在需要占用大量的磁盘和内存空间。
在mongodb不需要建太多索引的情况下,mongodb可能更节省一些资源,当然影响最后占用内存和磁盘空间的因素较多,这个也不完全绝对,所以需要根据实际情况去测一下。
运维部署
在运维部署方面,ES的一套工具ELK,现在叫Elastic Stash,自带对集群的状态监控,安装部署也较mongodb方便太多,对运维人员来说相比mongodb容易上手太多。
在弹性伸缩方面,ES相比mongodb也容易太多,真的容易太多,并且,ES水平扩展更容易,能够自动均衡!
可以负责的说mongodb对运维部署人员的要求要比ES明显要高很多。用ES集群,你会明显感觉你对它的掌控力更强。
所以,在监控运维方面,ES明显更具优势。
性能方面
写入性能与查询性能对比方面,mongodb在除了全文索引之外的绝大部分场景是会比ES要高一些的,尤其是写入性能!!!
在性能方面,我觉得如果追求极致的写入性能与写入实时性要求,那么应该选择mongdob,否则Elasticsearch也足够用啦。
我们在多个实际项目中,对ES集群的查询性能与写入性能还都是比较满意的。
总结
在日志应用领域,两者可以相互替代,但经过上述对比,明显选项ES更好。
如果你的业务场景就是需要一个文档型的业务数据库,比如我们目前负责建设的多个业务数据库,主要是基本的增删改查,那最好还是选mongodb。
如果你有要求复杂全文检索又并发性能要求较高的业务场景,类似搜索服务,那最好的选择还是elasticsearch。
但其实对大多数的中小公司来讲,这两者的数据管理能力并足够满足业务需求,都可以相互替代。
综合考量下来,绝大部分场景用ES相对就可以比较好的满足了,除非对写性能有极高的要求,除非字段未来会频繁变更。
最后,大家还是要根据自己项目的真实需求,进行综合评估和测试。