作者简介:沈炼,蚂蚁集团技术风险部数据库高级专家
毕业于东南大学,2014年以来从事 OceanBase 在蚂蚁的架构工作,目前职责包括蚂蚁 OceanBase 高可用体系建设 和 OceanBaseKV 在蚂蚁的架构及研发工作,对标业界的“自治数据库”和“多模型数据库”,致力于让 OceanBase 走得更稳、更远、更快。在蚂蚁 OceanBase 体系中,沈炼先后负责 蚂蚁核心链路上 OceanBase 、 OceanBase 高可用体系建设、 OceanBaseKV 架构及研发。沈炼对互联网金融场景、数据库内核(关系型及 NoSQL )、数据库 PAAS 、高可用体系、安全体系 等方面有深入的理解,将会推出系列文章介绍 OceanBase 的存储引擎、高可用内核、高可用体系及理念、 OceanBase 多模型数据库等
本文将为大家详细讲解 OceanBase 存储引擎,回答关于 OceanBase 数据库的以下相关提问:
- OceanBase 是否依赖其他开源 KV 数据库(例如: LevelDB 、RocksDB )?
- OceanBase 底层引擎是什么?是 KV 吗 ?
- OceanBase 内存结构是 B+Tree 还是 LSMTree ?
- OceanBase 如何实现高性能服务?
背景
目前业界数据库存储引擎主要分为两种:
- update-in-place :原地更新,较常见于传统关系型数据库( MySQL 、Oracle )采用的 B+Tree 结构。优点:更新记录时对原有记录进行覆盖写。有较好的数据局部性,对扫描比较友好。缺点:是引入大量的随机写,同时还有一定的并发问题;并且与业务流量叠加,对业务流量有一定的影响;
- log-structure storage:日志更新,例如 LevelDB 、RocksDB 、HBase 、BigTable 等采用的 LSMTree 结构。优点:日志更新无锁,不会引入并发问题,能够保证高效写入,并且没有空间碎片。缺点:是读路径变长,例如 LSMTree 结构在扫描时需要读取 memtable 、L0层及其余层的数据,并进行归并,需要通过异步 compaction 进行GC以及均衡各个层级的数据来避免过多的读放大。
为追求极致的数据库性能,scan 操作需要良好的空间局部性,get/put 操作需要高效的索引来定位,version/gc/compaction 会提升读操作的性能但可能影响整体性能,目前的存储引擎都存在着一定的局限性。
为此 OceanBase 选择完全自主实现存储引擎,没有借助于任何其他已有的开源方案。
从架构上看,OceanBase 的存储引擎可分为两层:
①底层的分布式引擎实现了线性扩展、Paxos 复制、分布式事务等分布式特性从而达到持续可用;
②上层的单机引擎融合了传统关系数据库以及内存数据库的一些技术从而达到极致性能。
本文将从单机引擎和分布式架构视角分别介绍。
01 单机引擎
读写分离架构
OceanBase 的存储引擎采用分层 LSMTree 结构,数据分为两部分:基线数据和增量数据。
基线数据是持久到磁盘上的数据,一旦生成就不会再修改,称之为 SSTable。
增量数据存在于内存,用户写入都是先写到增量数据,称之为 MemTable,通过 Redo Log 来保证事务性。
当 MemTable 达到一定阈值时会触发冻结( Frozen MemTable ),并重新开启一个新的 MemTable ( Active MemTable ),Frozen MemTable 被转存到转储 SSTable 中,然后在合并( LSMTree 结构特有的 compaction 动作 )时将转储 SSTable 合并入基线 SSTable,生成新的 SSTable 。
在查询时,需要将 MemTable 和 SSTable 的数据进行归并,才能得到最终的查询结果。
系统为基线数据和增量数据指定不同的版本,