话题讨论 | mongodb拥有十大核心优势,为何国内知名度不是很高?
1. 背景
mongodb是一款功能完善的分布式文档数据库,在高性能、动态扩缩容、高可用、易部署、易使用、海量数据存储、高压缩比等方面拥有天然优势。虽然mongodb有很多优势,但是在国内缺存在不少的误解,影响力有待提升。
2. mongodb历年数据库得分排名及得分趋势
DB-Engines是一个对数据库管理系统受欢迎程度进行排名的网站,近年来,MongoDB在DB-Engines数据库流行度排行榜稳居榜单前五。在DB-Engines排名可以看出,mongodb历年得分数据呈现持续增长的趋势,具体如下图所示:
得分趋势图形

近两年得分如下:

从历年得分排名可以看出,mongodb总体趋势呈现持续增长态势,稳固了它在数据库系统中的使用优势。
mongodb roadmap:不仅仅是文档数据库
mongodb-4.2版本开始已经支持分布式事务功能,当前对外文档版本已经迭代到version-4.2.11,分布式事务功能也进一步增强。此外,从mongodb-4.4版本产品规划路线图可以看出,mongodb官方将会持续投入开发查询能力和易用性增强功能,例如union多表联合查询、索引隐藏等。mongodb产品路线图如下:

从mongodb-4.2版本分布式事务功能支持以及4.4版本roadmap规划图可以看出,mongodb后续发展会持续朝着NewSQL方向前行,预计会为用户提供更全面的数据库服务功能。
3. 模式自由-加字段方便快捷
分布式mongodb核心优势特性主要如下:
模式自由-加字段方便快捷

从上面的操作可以看出,mongodb不需要提前建表,也不需要指定表中各个字段,使用灵活。
db.blog.update({"Title": "Title1"}, {$set: {tags: "tagxxx"}})

4. 天然高可用支持
当前开源数据库Mysql,当同一个分片复制集中(假设一主两从)中的主服务器异常或者实例异常退出后,需要依赖第三方MHA插件来实现新主的选举。如果没有第三方MHA插件,或者第三方MHA插件异常,则无法选举新主节点,最终造成写失败。
相比Mysql对第三方MHA插件的依赖,mongodb数据库自带天然高可用选举功能,具体架构图如下:


如上图所示,当主节点异常后,两个mongod从节点的保活报文会探测到该异常,然后2个从节点会进行一轮新的主节点投票选举(raft协议)。主节点异常,剩余两个节点可以进行正常投票选举,因为满足raft多数派要求,最终会在两个主节点中快速选择一个新的主节点。
5. 分布式弹性扩缩容(解决分库分表及海量数据存储痛点)
扩容过程业务无感知,扩容新分片触发数据balance过程如下图所示(假设从3分片扩容到6分片):

有了分片水平扩容能力,就可以突破前面单分片复制集架构的容量限制、写入能力受限等瓶颈,基本上可以实现数据容量和写入能力成倍增长。
6. 完善的数据均衡机制、不同分片策略、多种片建类型支持
完善的数据balance均衡机制


不同分片策略及预分片功能支持
为了满足不同业务查询场景需求,mongodb支持两种类型的分片策略:hash分片和范围分片。这两种分片策略再不同业务场景,各自有不同的优缺点,这样业务可以根据实际情况来完成分片策略选择。具体如下:
hash分片策略:通过对指定shard key进行hash计算,从而快速实现数据随机散列到不同分片,从而规避数据不均衡问题,适合单条数据查询相关业务场景。
范围分片策略:范围分片方式,比较适合业务有范围查询的场景,如果业务查询中带有范围查询,可以考虑该分片策略实现性能最大化。注意:范围分片策略方式,数据均衡性相比hash分片一般稍差。
此外,为了尽量提高性能,mongodb默认还支持预分片功能,这样可以保证数据写入集群的适合尽量均衡,避免balance数据迁移过程对整个集群性能的影响,做到读写性能的最大化。hash分片策略和范围分片策略都支持预分片,只是hash分片策略方式可以支持自动预分片,同时也支持手动预分片方式;范围分片策略方式只支持手动预分片。具体如下:
自动预分片支持:如果分片集群选用hash分片策略,则支持shardCollection时提前对片建进行自动预备分片。
手动预分片支持:hash分片策略和范围分片策略都可以通过mongodb自有的splitAt等接口进行手动人工预分片,分片接口的支持确保预分片更加弹性自由。
此外,除了支持常用的范围分片及hash分片策略外,mongodb还支持shardTag分片模式,对一些极端特殊需求做定制化流量转发(例如对带有某种标记的数据转发到指定的节点)。
7. 完善的数据一致性及安全性保证
数据一致性有较高要求场景

数据一致性要求不高场景

8. 高并发、高性能
mongodb为了满足不同业务链接需求(链接数多少、是否短链接、是否很多空闲链接等),支持两种线程模型:一个链接一个线程和adaptive动态线程池模型。
一个链接一个线程

adaptive动态线程模型

wiredtiger高性能存储引擎设计
WT和innodb存储引擎性能比较曲线如下:

WT和levelDb存储引擎性能比较曲线如下:


9. 成本节省-WT引擎高压缩比支持
mongodb对数据的压缩支持snappy、zlib算法,针对存储层中的数据分类又可以分为以下几种:
普通collection数据:对用户写入collection的数据是否需要压缩,支持snappy、zlib算法,4.2增加支持。
index索引数据:对索引数据是否进行压缩,默认只支持前缀压缩,这样相同前缀的索引数据,共同的前缀只会存储一次,这样即可减少内存和磁盘消耗。
在以往线上真实的文本数据空间大小与真实磁盘空间消耗进行对比,可以得出以下结论:
① mongodb默认的snappy压缩算法压缩比约为2.2-3.5倍
② zlib压缩算法压缩比约为4.5-7.5倍(本次迁移采用zlib高压缩算法)
也就是,如果collection数据和journal日志数据采用默认的snappy压缩算法,当数据量为3.5T时,真实的磁盘消耗约为1-1.5T;如果采用zlib算法,3.5T的数据量,真实的磁盘消耗为500-700G左右,不同数据类型会有差别,如下表所示:

说明:1.不同数据类型会有差别;2.最新4.2以后版本引入了新的算法,性能会更好,由于没有真实使用过zstd算法,因此不做具体数据对比。
10. 天然机房多活容灾支持





11. 完善的客户端均衡访问策略
mongodb客户端访问路由策略由客户端自己指定,该功能通过Read Preference实现,具有如下几个配置方式:
primary :只从primary主节点读数据,这个是默认设置,所有读只走主节点。
primaryPreferred :优先从primary读取,如果复制集没有主节点则通过从节点读数据。
secondary :只从scondary节点读数据。
secondaryPreferred :优先从secondary读取,当没有secondary从节点成员时,才从primary读数据。
nearest :选择离自己最近的节点读数据,也就是就近访问。
通过在客户端driver中配置不同的读方式,可以方便实现读写分离、就近读数据等,如果对数据一致性要求高,也可以直接读主节点。我们以复制集nearest 配置为例,架构图如下:

12. 分布式事务支持
mongodb-4.2版本开始已经支持分布式事务功能,当前对外文档版本已经迭代到version-4.2.11,分布式事务功能也进一步增强。此外,从mongodb-4.4版本产品规划路线图可以看出,mongodb官方将会持续投入开发查询能力和易用性增强功能,例如union多表联合查询、索引隐藏等。mongodb产品路线图如下:

从mongodb-4.2版本分布式事务功能支持以及4.4版本roadmap规划图可以看出,mongodb后续发展会持续朝着NewSQL方向前行,预计会为用户提供更全面的数据库服务功能。
13. 最后:mongodb这么多优势,为何国内影响力不高?
当前mongodb已经为我司提供了数万亿级数据库存储服务,从业务场景和业务接入情况来看,当前至少有90%以上业务场景可以mongodb和mysql相互替代,这一部分业务使用mongodb也非常合适,业务切换到mongodb后也得到了一致性的认可,主要为业务解决了如下痛点:
分库分表痛点:业务最大的痛,mongodb可以理解为无限大的表,彻底解决该痛点。
机房多活痛点:传统mysql双向同步具有物理服务器成本高(多副本情况下,又多了一倍)、人力成本高(你得找几个人来开发和运维双向同步系统)、数据一致性很难保证等。mongodb分片及复制集架构可以天然支持机房多活,包括南北双机房,三机房,甚至更多国内国外机房多活都可解决。
成本高,mysql官方版本默认没有压缩等功能,同样得数据,默认配置,mongodb磁盘相比mysql就可以节省70%左右。
分布式弹性扩缩容:有了该功能,除了可以解决分库分表痛点外,对业务容量评估也减轻了很大的工作量。例如如果mysql,你不知道后续数据量就近多大,一般一次性就申请很多套,造成了资源浪费。
mongodb分布式事务支持,突破了单机事务的限制。
其他
如上,可以看出mongodb确实在部分业务场景有很多的优势,那为什么在国内影响力不高,甚至误解很深,个人理解如下:


影响力不是很高原因
个人认为除了上面图形中总结的原因外,还有另外几个很大的原因:
后续分享出mongodb踩过的所有坑到社区,让更多的人学习了解学习mongodb。