作者简介:海芊,OceanBase 文档工程师。
各位 OceanBase 社区的小伙伴们大家好呀!今天是轻松的一天,让我们借助本宝宝的灵魂之笔,先用几张图讲清楚内存数据库和磁盘数据库的区别。然后再聊聊 OceanBase 的架构。
我们先看这张图,它展示了内存数据库和磁盘数据库的主要区别。
图中我们可以看到,内存数据库是把数据存储在内存中,使用磁盘进行备份。而磁盘数据库将数据存储在磁盘上,使用内存进行缓存。
由于内存比磁盘快得多,所以内存数据库的优势很明显,就是快呗!但是,内存数据库的数据持久性又怎么样呢?我们早就知道内存上的数据不是永久的。所以这里的答案是:我们使用磁盘来备份数据。
如果同步备份数据,那写入就要等待磁盘数据落盘。如果异步备份数据,当系统在写入内存并落盘后,在磁盘上备份之前崩溃时,那就可能丢失数据。这样的数据备份,不就与通过内存来加快速度背道而驰了吗?那内存数据库如何在保证 RAM 的高速的同时,保证数据的持久性呢?
要想保证数据持久性,就得用 NVM,也就是非易失性内存。因此,即使是内存数据库也必须要把数据写入到 NVM,比如磁盘。且写入要在查询请求返回客户端之前就完成。但是,磁盘上的延迟开销并不仅仅来自于向磁盘写入数据。更多延迟来自于在磁盘上维护数据的结构,如 B 树。如果只是简单地将数据追加到一个文件,那内存数据库还是更快一些。我们可以批量把数据写入到一个磁盘块上,但并不是所有的磁盘访问都是一样的。依次把数据写入到块中和定位块中文件并更新数据的流程很不一样。因此,为了保证持久性,内存数据库首先简单地将数据追加到一个只追加日志中,然后再把数据写入内存并返回。此时,当系统从崩溃中恢复时,就可以使用磁盘上的日志数据了。
这个我们可以看看图二,内存数据库的待久性。
不过貌似哪里不对的样子,那日志不是随着时间的推移而变得非常长吗?如果只是简单地追加数据,而不是更新现有的数据,数据确实会持续增长。冗余的日志有两个比较大的问题:一,它浪费存储空间。二,它会让恢复时间变得很长,因为系统要读取整个日志来重建内存上的数据库。为了防止这种情况,内存数据库维护了一个磁盘数据结构,如 B-tree,并定期向 B-tree 写入日志条目。在将日志条目应用到 B 树上后,再把条目从日志里删除。这就是所谓的检查点。现在,当系统重新启动时,首先加载检查点,然后再把检查点中没有的最新日志条目写入到内存。
这就是图三我想说明的内容了。
磁盘数据库中还有 WAL (预写日志)和 B-tree,而且 RAM 也能缓存数据。那是不是就能得到结论,内存数据库不就是一个有大缓存的普通磁盘数据库吗?妙啊,但也不全是这么回事。与内存数据库相比,磁盘数据库中仍然有序列化和数据布局的开销。假设内存数据库的全部数据总是在内存中。而磁盘数据库就不是这样了,因此数据结构和索引的设计也会有所改变。说完了内存和磁盘的区别,再给大家举几个例子吧。ArangoDB 和 Redis 是内存数据库,那 OceanBase 又属于哪种呢?大家可以猜猜看。
OceanBase 是“基线数据(硬盘)”+“修改增量(内存)”的架构,OceanBase 以SSD 硬盘为载体。
增、删、改的数据放在内存,它的基线数据是保存在硬盘上的。因此可以把 OceanBase 看成是一个准内存数据库。OceanBase 不会像前面说的传统数据库那样,不定期把检查点写到硬盘中。增量数据在 OceanBase 中会保存较长时间。当内存快满的时候,或者到了某个固定的阈值,或者由人工触发,把内存的脏数据批量写回到硬盘上,这就是我们平常说的转储了。为什么要这样做呢?写事务在内存,可以提升性能。没有随机写硬盘,那硬盘随机读就不受干扰,这也是为什么 OceanBase 性能这么好的原因。
最后的最后,您有任何疑问都可以通过以下方式联系到我们~
联系我们
欢迎广大 OceanBase 爱好者、用户和客户随时与我们联系、反馈,方式如下:
社区版官网论坛
社区版项目网站提 Issue
钉钉群:33254054