ES

MongoDB和Elasticsearch的对比

Posted by JustDoDT on June 27, 2019

MongoDB vs Elasticsearch


特性 MongoDB Elasticsearch 备注
主要定位 (文档型)数据库 (文档型)搜索引擎 一个管理数据,一个检索数据
次要定位 无 文档存储  
资源占用 一般 高 MongoDB使用C++开发,ES使用Java开发
写入延迟 低 高 es的写入延迟默认1s,可配置,但是要牺牲一些东西
全文索引支持度 一般 非常好 es本来就是搜索引擎,这个没有啥可比性
有无Schema 无 无 两者都是无Schema
支持的数据量 PB+ TB+ ~ PB 两者支持的量并不好说得太死, 都支持分片和横向扩展, 但是相对来说MongoDB的数据量支持要更大一点
性能 非常好 好 MongoDB在大部分场景性能比es强的多得多
索引结构 B树 LSM树 es追求写入吞吐量, MongoDB读写比较均衡
操作接口 TCP Restful(Http)  
是否支持分片 是 是  
是否支持副本 是 是  
选主算法 Bully(霸凌) Bully(霸凌) 相比于Paxos和Raft算法实现更简单并有一定的妥协
扩展难度 容易 非常容易 es真的是我用过的扩展最方便的存储系统之一
配置难度 难 非常容易  
地理位置 支持 支持  
运维工具 丰富 一般  
插件和引擎 有多个存储引擎供选择 有大量插件可以使用  

定位

  • MongoDB和Elasticsearch都属于NoSQL大家族,且属于文档型数据存储,但是这两者虽然有很多功能和特性高度重合,但是定位完全不同。

  • MongoDB是文档型数据库,提供数据存储和管理服务

  • Elasticsearch是搜索引擎,提供数据检索服务

  • 两者的最大区别在于元数据(没有写错,不是源数据)的存储和管理,MongoDB作为一个数据库产品,是可以作为元数据管理者的。Elasticsearch作为一个搜索引擎,定位是提供数据检索服务,也就是说我只管查,不管写,Elasticsearch的Mapping不可变也是为此服务的,带来的代价就是ES不适合作为数据管理者,ES可以从其他数据源同步数据过来提供查询,但是不适合自己对数据进行存储和管理。

ps: 修改Mapping的代价非常高, 所以我们一般都是把新数据重新写入一份然后直接切换别名到新的索引

由此可见, 如果你有一批数据要看, 但是不经常进行修改, 这个时候毫无疑问可以用es, 但是如果你还打算继续修改数据, 最好就是使用MongoDB。

全文索引, 读取性能和写入延迟

  • MongoDB和Elasticsearch都支持全文索引, 虽然MongoDB的全文索引完全无法跟ES相提并论, ES毕竟是专业的搜索引擎产品, 着重提供数据的检所支持, 这方面吊打MongoDB也是可以理解的。

  • MongoDB虽然在支持的部分查询功能上稍微弱于ES, 但是在大部分场景下性能方面完爆es, 不管是读性能, 还是写性能。

  • ES的写入延迟默认为1s, 这个虽然不能算入写入性能, 但是毫无疑问是一大缺点, 虽然可以配置为更短的时间, 但是这样就要牺牲一定的数据吞吐量, 和更频繁的磁盘刷新操作。

  • ES底层使用Lucene作为核心引擎, 很多设计就是为了匹配Lucene中的概念, 其实es可以看成一个Lucene的proxy层包装, 整体来说两个系统有一定的嫌隙。

  • MongoDB则是完整的一个单体数据库产品, 内部的存储引擎也是可插拔式的, 产品之间的结合相对更紧密一点。

MongoDB支持多种存储引擎, 这里只谈默认的WiredTiger引擎, 其他还有某些方面更优秀的引擎,例如: MongoRocks等

部署和资源占用

  • 单机部署的话其实MongoDB和Elasticsearch都十分的方便, 不过ES相对来说资源占用更多一点, 性能也比MongoDB要弱一点

  • 集群化的部署, 我们一般都会选择分片+副本的部署方式, 这种方式下, ES部署起来比MongoDB方便太多, MongoDB要部署一套完整的分片 + 副本模式还是比较麻烦的

  • 资源占用方面, MongoDB可以支持存储文件类型的数据, 作为数据库也有数据压缩能力, ES则因为大量的倒排索引需要占用大量的磁盘和内存空间

分片(sharding)和副本(replica)

  • MongoDB和Elasticsearch作为天生分布式的代表产品都支持分片和副本,两者都通过分片支持水平扩展, 同时都通过副本来支持高可用(HA)

  • 分片就是一个数据集的数据分为多份, 同时分布在多个节点上存储和管理, 主流分片方式有两种: hash分片和range分片, 两种分片方式各有优势, 适合不同的场景。ES主要是hash分片

  • 副本就是一份数据集同时有一个或者多个复制品(有些地方叫主从), 每份复制品都一模一样, 但是为了保证数据的一致性, 往往多个副本中只有一个作为Primary副本(通过选主从多个副本中选出Primary), 提供写服务, 其他副本只提供读, 或者只提供备份服务

MongoDB和ES的不同

MongoDB和Elasticsearch虽然都是分布式服务,但是还是有很多不同

  • 分片和副本单位划分

MongoDB是以节点为单位划分角色, 一旦一个节点被指定为副本, 其上面的数据都是副本

Elasticsearch是以分片为单位划分角色, 一个节点上即可以拥有某分片的主分片和可以同时拥有另一个分片的副本分片, 同时ES还支持自动的副本负载均衡, 如果一个新节点上面什么数据都没有, 系统会自动分配分片数据过来

  • 架构模式

MongoDB的副本和分片是两种不同的模式, 虽然可以同时使用但是依然有各自的架构设计, 用户可以任意选择选型进行搭配, 每个节点的职责更加转一, 方便据此调整机器配置

Elasticsearch中则是分片 + 副本是一套统一的架构设计, 每个节点具有接近同等的地位, 配置使用起来更加简单, 但是如果要针对节点所负责的功能对机器进一步做定制就不如MongoDB灵活

文档型数据库的问题

无schema

文档型数据存储既能享受无schema限制的灵活, 又能享受索引查询的快速和类SQL查询的便捷

使他们用起来不像传统的RDBMS, 图数据库(Neo4j)那么麻烦, 又不像 Redis,HBase这种数据库查询功能不够强大, 处于一个传统RDBMS和经典K-V存储之间的位置

我个人很喜欢这个特性, 没有schema的限制, 存储数据更方便也更灵活了

但是有得有失, 很多固定schema的好处就无法享受到了, 比如: 对数据的高效压缩

鸡肋的Collection和Type

对于文档型数据库来讲, collection/type的意义其实不大, Nosql数据库中极少有数据库跟传统的关系型数据库一样保持类似( 库->表 ) 的对应关系, 因为这个真的没有什么必要 ^_^

Elasticsearch从6.x版本开始强制只允许一个索引使用一个type, 其实就是意识到这个这个设计失误, 不想让你用这个type类型, 到了es的7.x版本会默认取消type类型, 就说明这个type字段真的是鸡肋的不行

弱事务

MongoDB以前只是支持统一文档内的原子更新,以此来实现伪事务功能, 不过Mongo4.0支持Replica Set事务, 大大加强了事务方面的能力

无join支持

文档型数据库大多数都不支持join(也有少量支持的), 但是我也用不上join的功能 ,不过据说未来MongoDB4.2版本会带来对join的支持

不支持join带来的问题就是我们需要自己对数据进行连接, 但是这并非不能解决的问题, 相应的缺少join功能对善于使用SQL的数据分析师就不大友好

Bully的选主算法的缺陷

elasticsearch和MongoDB选择的选主算法实现很简单, 但是有几率出现脑裂的情况, 当然, 具体情况跟配置也有关系(比如:你有三个es节点但是设置的最小主节点数为1, 将最小主节点数设置为2可以避免脑裂情况)

即使出现了脑裂的情况, 使用重启大法一般就能解决 ^_^

总体来说, 这方面不如使用Paxos和Raft算法的其他分布式系统靠谱

其他

  • 运维工具

两者背后都有商业公司的支持

MongoDB的很多客户端和运维工具更丰富, 但是MongoDB作为一个数据库产品, 相对应的对运维人员的要求也要更高一点

Elasticsearch则有整套的数据分析和收集工具提供, 配套的kibana就是一个很不错的管控es的工具

  • 操作接口

es使用Restful来提供统一的操作接口, 屏蔽了各种语言之间的障碍

但是同样带来了表达能力和性能的损失

MongoDB则使用TCP, 降低了序列化和网络这一层的性能损耗, 并最大程度保留了接口的内容表达能力

适用场景

两者其实在很多使用场景上有重合之处, 可以互相替代, 比如日志收集

进一步来说

MongoDB有多个存储引擎可以选择, 而且MongoDB不仅看重数据的分析, 对数据的管理同样看重, 总的来说MongoDB更倾向于数据的存储和管理, 可以作为数据源对外提供

Elasticsearch则有很多插件可以使用, 相对来讲Elasticsearch更倾向于数据的查询, 一般情况下Elasticsearch仅作为数据检索服务和数据分析平台, 不直接存储源数据

  • MongoDB适合
  1. 对服务可用性和一致性有高要求
  2. 无schema的数据存储+需要索引数据
  3. 高读写性能要求, 数据结构简单的海量数据场景
  4. 有热点数据, 有数据分片需求的数据存储
  5. 日志, html, 爬虫数据等半结构话或非结构化数据的存储
  6. 有js使用经验的人员(MongoDB内置操作语言为js)
  • Elasticsearch适合
  1. 已经有其他系统负责数据管理
  2. 无schema的大数据量的数据检索
  3. 对查询性能有要求, 对写性能要求不高
  4. 监控信息/日志信息检索

参考文档