张甦 数据和云

前两天,我熬夜看完了整场国足对阵伊朗的亚洲杯八分之一决赛,最后的比分是国足0:3告负,无缘8强。结果确实不尽人意,其实每个中国球迷心里都知道,这场比赛凶多吉少,但为啥还是想看,因为一颗不死的心,因为希望有奇迹的发生。因为我心中有国足队长郑智。

 

想看这位真爱足球的国足老队长踢完国家队的这最后一场比赛。整场比赛的三个丢球现在再去抱怨是由于后卫的低级失误所导致的,已经变得很索然无味了。    我们要敢于承认差距,敢于接受错误与批评。

 

有些事儿想要成功,并不是简简单单通过花钱请一个高水平的教练就能解决的。像我们这些做技术的兄弟们也一样,做好技术是一条漫长而又艰辛的道路。怎么理解什么叫技术呢?“技”:就是我们所学习的专业知识;“术“:就是要把所学习知识到发扬出去,让更多的人受益。

 

今天选择给大家介绍一下MongoDB的核心Wired Tiger插件式存储引擎。也宣告我的个人公众号”我不叫那谁”正式成立。未来会与大家一起学习主流技术,后续会陆续更新MySQL,PG,MongoDB,python,go,hadoop等学习文章。(有兄弟抱怨我说,老分享MySQL和MongoDB的文章,能不能分享点PG,python等相关知识,放心各位老铁,下次就会更新!)

 

Wired Tiger存储引擎架构模型图如下:

催人泪下!做技术打铁还需自身硬_Java

 

MongoDB从3.0开始引入了WiredTiger存储引擎,但对于原来的MMAP V1(3.0版本默认)也有改动。

 

但WiredTiger无论是从锁的粒度(库级别锁提升为文档级别锁)通过MVCC实现文档级别的并发控制,允许多个客户端请求同时更新一个集合内存的多个文档,再也不需要在排队等待库级别的写锁。这在提升数据库读写性能的同时,也大大提高了系统的并发处理能力。

 

还有在存储方式上(WiredTiger在集合和索引级别分配文件,数据库中的所有集合和索引均存储在单独的文件中,集合或者索引删除后,对应的存储文件随即删除。方便回收磁盘空间)、还支持磁盘数据压缩也大大节约了磁盘使用成本。

 

所以从3.2版本起把WiredTiger作为默认的存储引擎。到此4.0版本支持多文档事务,4.2要支持分片级别的事务。

 

既然说到支持事务,那么就必须满足事务的ACID特性和应该有的事务隔离级别。

 

WiredTiger支持快照型的事务隔离级别(snapshot)

 

什么是事务的snapshot?这里给大家简单聊一些,其实就是事务开始或者进行操作之前对整个wired tiger存储引擎内部正在执行或者将要执行的事务进行一次快照,

保存当时整个引擎所有事务的状态,确定哪些事务是自己可见的,哪些事务是不可见。然后通过MVCC来实现事务的冲突检测。如图所示;

催人泪下!做技术打铁还需自身硬_Java_02

每个事务开始操作,都会记录它所操作的该条记录的版本号信息。事务a更新完之后,会把事务标号加1。然而这时的事务b就需要在加1的基础上去更新新的数据,来实现冲突检测。

 

Wired Tiger对内存的管理;

wiredTiger对内存使用会分为两大部分,一部分是内部内存,另外一部分是文件系统的缓存。如下图

催人泪下!做技术打铁还需自身硬_Java_03

内部内存可以默认值是物理内存的50%(忽略内存小于1G的情况)。那么剩下来的内存交由文件系统使用,对于wired tiger数据保存是压缩完之后的状态。所以数据从磁盘读到内存,是需要经历如下图;数据所呈现的格式是不一样的。MongoDB会把经常使用到的数据放到IC中,WiredTiger会通过文件系统缓存,自动使用其他所有的空闲内存,放在文件系统缓存里面的数据,与磁盘上的数据格式一致,可以有效减少磁盘I/O。

催人泪下!做技术打铁还需自身硬_Java_04

cache结构梳理图:

催人泪下!做技术打铁还需自身硬_Java_05

数据在内存中是以btree的结构形式进行存储,会通过wired tiger块管理器把数据先读取到IC中,然后更新它之后,页会变成脏页。最后再次调用块管理器,MongoDB内部默认60s会把脏data刷到磁盘。

 

以上就是我对于Wired Tiger的理解分析。

 

我们做技术的兄弟们,很不容易,每天面临各种各样的挑战与生活压力带给我们的心酸与痛楚。想要成功,自己的基本功还是要过硬。希望国足的失利能带给你我一些深刻的反思与未来成功的启示。