MONGODB Wiredtiger 为什么那么快?

2020-05-09 16:57:04 浏览数 (1)

如果有人说我精通ORACLE ,MYSQL ,那我信,但如果有人说特别精通MONGODB 的原理以及源代码,那就真的佩服了。这方面的书比较少,所以说精通MONGODB 的原理,那真是比较不容易。

为什么是胡想瞎猜,是因为如果说错了,那就等着您来指正,互相提高技术水平。

首先看一个可能被看烂了的mongodb 的整体架构图,从图中可以总结出以下list

1 mongodb 支持行 和 列存储,目前大部分状态下使用的是行存储

2 数据存储在磁盘和cache中的数据的格式应是不一样的,需要压缩,解压

3 数据的处理都是处理无压缩的数据

4 系统通过snapshot 的方式进行 MVCC 的多版本控制,减少锁的产生

5 事务产生则最先要落LOG日志,数据则在缓冲中在刷入到磁盘

由于大部分的数据处理在内存中,并且尽量降低锁,和并发之间的互斥操作,使得MONGODB 的结构相对于其他传统数据库要简单,这也是使得MONGODB 的操作相对其他数据库要快的一个原因。这就要提到 in memory ,mongodb 的寻址设计中并没有使用传统的文件系统的偏移量作为指针。如果是B 树三层的展现,则在内存中,非叶子节点的信息会在内存中

所以寻址都是在内存中进行的,这就会带来更高的性能,这也是有些文字中提到的,给与MONGODB 的内存不要太吝啬的一个原因。

总结 in memory 的架构

1 系统会cache trees 并且将部分page 优化,在内存中访问

2 指针遍历B 树时,不会锁定读和写,

3 保证原始的数据与更新的数据分开

4 结构化的改变 (例如 页面的merge 和 splits)都是在后台线程中处理的

当然有些数据库也在这么做,那wiredtiger 会变得更快的原因在于另一个词 no locking no lock manager ,其他的传统数据库都有锁的概念,有的数据库类似 sql server 的锁还有锁升级的概念,可想而知,越复杂的东西,其速度必然也不会快到哪里去。MONGODB 摒弃了所,通过MVCC 以及自身的特征,对正在读的数据创建snapshot ,而写的数据创建新的版本,这样读和写就分开了,通过时间戳的概念(参见之前的一篇文字),将整体的 MONGODB 与锁这个词分开。速度自然就会更快,更强。当然由于本身的设计原因,也就不用太多考虑回滚的事情。

MONGODB 快的原因还要归功于block manager ,Block mananger 主管 ,将数据在写入时就进行最大化的压缩,这样的好处是,目前的机器都拥有很强大的CPU ,但实际上大部分的瓶颈还在于磁盘,而由于将压力转到CPU 对数据的压缩LEVEL 变的很高,则读取数据 和写入数据的负担就会降低。很巧妙的利用了当前硬件的优势。同时也可以根据当前机器和所处的环境对压缩进行选择。

snappy是默认的压缩方式,LZ4 更适合 page layout , zlib 拥有高压缩比。

而有效的checkpoint 的方式也是促使 mongodb wiredtiger 处理速度很快的一个因素。

从上图可以看到,页面的修改并不是在原有的空间进行,而是将改变的页面在新的页面生成,在通过指针从新的生成的页面,指向未改变的页面。将新的根地址写入到 metadata 中。这样的处理的速度要比加锁,然后改变数据的方式要快的多。并且大部分MONGODB 处理的方式多是写,和读,大量的UPDATE 的并不多见。

上面讲过的MVCC ,则系统中必然有一个旧版本的读取器,这样就算一边读取数据,一边写入数据,之间也不会进行干扰,而将这个事情变得简单的事情就是MONGODB 没有 UNDO LOG REDO 这样会导致系统变得更复杂和缓慢的东西(参见 MYSQL ORALCE UNDO REDO )。

所以MONGODB WIREDTIGER 为什么这么快

1 本身的架构设计,因为没有事务需要进行逻辑上的回滚需求,写入具有原子性

2 大量使用内存的方式来处理读写数据

3 对写入数据的压缩,对I/o方面是很有帮助的

4 MVCC 以及相关的设计,无锁化的设计

5 特殊的数据更新的方式,不会有其他数据库的 page merge page split 等影响性能的困扰。

以上仅仅是个人的理解,如有失误,错误,还请您不吝赐教。

感谢

0 人点赞