网易云背后的数据库:Facebook开源,完全兼容MySQL

MyRocks是完全兼容MySQL的一个关系型数据库系统,由Facebook于2016年下半年开源,网易杭研数据库内核团队在2018年初引入,在网易云音乐某些业务场景落地使用,取得了较好的效果,在这之后落地了更多地业务场景 。

自己整理的JAVA架构学习视频和大厂项目底层知识点,需要的同学欢迎私信我【资料】发给你~一起学习进步!
简述MyRocks是Facebook数据库工程团队将MySQL的默认存储引擎InnoDB(基于B+树)替换为自家的RocksDB(基于LSM树)后发展而来的MySQL分支版本,其继承了MySQL的SQL语法,数据高可用框架和配套工具 。
MyRocks具有较高的普适性,对于MySQL用户来说,将MySQL替换为MyRocks是透明的,在使用方面并没有差别 。最大的不同是DML操作(数据操作语句,如增、删、改)性能相比MySQL有明显优势;同样的数据量,所需的存储空间明显变少 。
网易云背后的数据库:Facebook开源,完全兼容MySQL

文章插图
 
目前MyRocks在云音乐内使用,业务场景包括云音乐实时推荐、离线推荐、历史听歌记录、P0核心库延迟从库和云计算NOS系统内部数据管理等等,累计节省了百万级的成本开销 。
 
项目介绍
网易云背后的数据库:Facebook开源,完全兼容MySQL

文章插图
 
MyRocks是MySQL和RocksDB的结合,MySQL是目前最流行的开源关系型数据库系统,RocksDB是Facebook在google的LevelDB基础上改进的KV存储引擎 。
RocksDB简介RocksDB基于Log Structured Merge Tree(LSM树)存储数据,下面简单介绍下RocksDB 。
网易云背后的数据库:Facebook开源,完全兼容MySQL

文章插图
 
如上图所示 。在RocksDB中,LSM可有多层,图中为4层(L0~L3),每一层都会独立进行Compaction操作;可以为每个用户数据表/索引创建一个列族(CF),每个CF都是一颗LSM树;每颗LSM树都会有数个Write Buffer(MemTable),用于缓存已经提交的事务数据;事务提交时会将WAL(Write Ahead Log)持久化到全局的日志文件中 。
网易云背后的数据库:Facebook开源,完全兼容MySQL

文章插图
 
每个事务都有一个writebatch对象,用于缓存该事务在提交前修改的所有数据 。在事务提交时,其修改的数据先写入WAL日志buffer,根据配置参数选择是否持久化 。然后将修改的数据有序写入到Active MemTable中 。当Active MemTable达到阈值后会变为Immutable,再新产生一个Active MemTable 。
数据写入MemTable后就意味着事务已经提交 。数据的持久化和Compaction都是异步进行的 。当Immutable MemTable个数达到所设置的参数阈值后,会被回刷成L0 SST文件 。在L0文件个数达到阈值后,合并到L1上并依次往下刷 。RocksDB中可以配置多个线程用于对每层数据文件进行Compaction 。
由于其优秀的特点,目前已经被集成到MySQL(即MyRocks)、MongoDB(即MongoRocks)、TiDB/TiKV和Nebula等关系型数据库、文档数据库、分布式KV、NewSQL和图数据库中,成为实际上的KV存储引擎标准 。
【MyRocks优缺点】MyRocks继承了MySQL优秀的基因,包括完全兼容的MySQL SQL语法、行级锁粒度、读已提交(RC)和可重复读(RR)两种事务隔离级别、多版本并发控制(MVCC,Multi-Version ConCurrent Control)、成熟的主从复制框架和完善的配套工具等功能和特性 。
核心竞争力
由于引入RocksDB,MyRocks具备比MySQL(相比基于B+树的InnoDB)更多优点,如更快的写入速度,更小的存储空间,更高的压缩效率等;这是MyRocks的核心竞争力,下面简单对比说明 。
  • 存储效率高,写性能好

网易云背后的数据库:Facebook开源,完全兼容MySQL

文章插图
 
InnoDB是典型的B/B+树存取方式,即使是顺序插入场景,也会在一个page还未完全填满时触发分裂,变为2个半空的page,也就是说InnoDB的page一定存在页内碎片 。
而RocksDB由于是追加(Append)方式,所以都是文件顺序写行为;MemTable从内存 Flush到磁盘后成为独立的sst文件,不同的sst文件间的Merge操作也是顺序读写,整个过程均不会产生内部碎片 。
  • 存储空间小

网易云背后的数据库:Facebook开源,完全兼容MySQL

文章插图
 
即使在非压缩模式下,RocksDB记录也进行了前缀压缩/编码,默认每16条记录才有一条是完整的,节省了后续15条记录的共同前缀所需的存储空间 。
此外,RocksDB每个索引占用7+1 bytes(seq id + flag)的元数据开销,而InnoDB每记录6+7 bytes (trx_id + undo ptr)空间开销,似乎在多个索引的场景下RocksDB更加费空间,但Ln SST文件seq id可置0,经过压缩等操作后绝大部分元数据开销是可节省的,只需占用1byte,因此RocksDB的元数据开销也比InnoDB更省 。


推荐阅读