【分布式系统工程实现】Bigtable Merge-Dump存储引擎

单机存储引擎解决单机读写问题,Merge-Dump存储引擎设计成一种通用的存储引擎,同时支持数据写入,随机读取和顺序扫描功能。顺序扫描功能应用很广,比如MapReduce批处理,同一个广告主的所有关键词广告统计,用户浏览所有的收藏信息,淘宝卖家管理大量的商品等。简单的KV系统只需要支持随机读取,而类似Bigtable这样的通用表格系统需要考虑基于主键的顺序扫描功能。Bigtable中的Merge-Dump存储引擎结构如下:

用户的操作首先写入到MemTable中,当内存中的MemTable达到一定的大小,需要将MemTable dump到持久化存储中生成SSTable文件。这里需要注意,除了最早写入的SSTable存放了最终结果以外,其它的SSTable和MemTable存放的都是用户的更新操作,比如对指定行的某个列加一操作,删除某一行等。每次读取或者扫描操作都需要对所有的SSTable及MemTable按照时间从老到新进行一次多路归并,从而获取最终结果。为了防止机器宕机,将用户的操作写入MemTable之前,会先写入到操作日志(commit log)中,这时一般会用到group commit操作,即将大量并发写操作聚合成一块一次性写入到commit log。由于写commit log为顺序追加,很好地利用了磁盘的顺序访问特性。

为了防止磁盘中的SSTable文件过多,需要定时将多个SSTable通过compaction过程合并为一个SSTable,从而减少后续读操作需要读取的文件个数。Bigtable中将compaction分为三种:minor compaction,merge compaction以及major compaction。其中,minor compaction指的是当内存中的MemTable达到一定的大小以后需要生成SSTable;merge compaction将连续多个大小接近的SSTable及Memtable合并生成一个SSTable;major compaction合并所有的SSTable和Memtable生成最终的SSTable文件。Minor和Merge compaction生成的SSTable文件中包含的还是用户的更新操作,只有Major compaction生成的SSTable才包含最终结果。一般来说,线上服务的写操作比较少,我们总是能以很大概率使得每个子表只包含一个SSTable和MemTable,也就是说,读取操作基本只需要访问一个SSTable文件和内存;而线下或者半线下服务,比如网页库,虽然写入操作多,可能经常出现一个子表包含多个SSTable的情况,不过这种类型的服务一般用于大数据量顺序扫描,对延时要求不高。SSTable的compaction有几个需要注意的点:

1, 限制SSTable的数量,必要时限制写入速度。如果写入速度持续大于compaction消化的速度,也就是大于系统的承载能力,SSTable将越积越多从而compaction永远无法成功。比如Cassandra存储节点采用了类似Bigtable的Merge-dump的做法,不过据说可能因为没有控制SSTable的最大个数也出现永远合并不成功的问题;

2, Compaction及写操作并发控制。Compaction的过程很长,compaction不能阻塞写操作,并且minor compaction和merge/major compaction可能同时进行。Compaction成功提交的时候需要互斥修改子表记录的SSTable结构数组,多个compaction同时进行的时候有些麻烦;

3, Minor compaction时机。当Memtable达到一定大小,比如4MB时,需要冻结Memtable并生成SSTable数据dump到磁盘中;同时,由于所有子表的操作日志写入到同一个commit log文件,当MemTable距离第一条数据写入超过一定的时间也需要执行minor compaction,否则,会出现机器宕机回放的commit log过多的问题;

4, Merge compaction如何选取SSTable文件。Merge compaction合并SSTable以减少读取的文件个数,每次merge compaction都是把相应的SSTable文件分别读写一次。为了提高性能,一般会要求Merge compaction选取连续的大小接近的SSTable文件。举个例子,如果有4个大小为4MB的SSTable文件,如果merge的策略为((s1 & s2) & s3) & s4 (&表示merge操作),读取的文件大小为s1 * 3 + s2 * 3 + s3 * 2 + s4 * 1 = 4M * 9 = 36M,如果merge的策略为(s1 & s2) & (s3 & s4),读取的文件大小为s1 * 2 + s2 * 2 + s3 * 2 + s4 * 2 = 32M,并且SSTable文件个数越多差别越明显;

数据在SSTable中连续存放,需要同时随机读取和顺序读取两种需求。SSTable被分成大小约为64KB的块(SSTable block),由于单个tablet的大小一般为100MB ~ 200MB,我们可以认为SSTable的大小不超过256MB,包含的block个数为256MB / 64KB = 4KB,每个block需要包含起始行,结束行相关的索引信息,假设索引信息大小平均为256Byte,每个SSTable的索引大小为4KB * 256Byte = 1MB,磁盘内存比为256 : 1,16GB的索引可以存放16GB * 256 = 4TB的数据。SSTable的索引数据全部存放到内存中,随机读取需要先通过二分查找找到相应的block,然后从磁盘中读取相应的block数据。Bigtable系统使用的SATA盘的磁盘寻道时间一般为10ms左右,一次随机读取整个64KB的块造成的overhead是可以接受的。按照64KB划分块还带来了一个好处,数据量膨胀对性能的影响很小。顺序读取的做法类似,在Merge-dump引擎中是很高效的。与传统的数据库的数据格式不同,SSTable存放的数据一般都是稀疏的,大多数列可能都没有更新操作。

按列存储&压缩:数据仓库的应用场景中需要支持按列存储,有两个好处:第一个好处是减少读取的数据量,第二个好处是提高压缩比率。Bigtable支持指定locality group,每个locality group中的列在SSTable中连续存储,每一个locality group之内按照行有序存储,当然,数据在MemTable中是不需要区分locality group的。这样,compaction是按照locality group进行的,读取每一个待归并的SSTable中相应的locality group的数据,合并生成一个新的SSTable locality group。某些跨多个locality group的更新操作,比如删除一行,需要将更新操作同时写入到多个locality group中。

总之,Merge-dump是一种同时满足随机和顺序读取的通用存储引擎,可以广泛应用在各种NOSQL存储系统中,另外,Merge-dump存储引擎往commit log文件追加操作日志以及compaction过程都是顺序写文件,非常符合SSD的特性,天然适应硬件的发展趋势。

时间: 2024-08-03 10:38:32

【分布式系统工程实现】Bigtable Merge-Dump存储引擎的相关文章

【分布式系统工程实践】随机访问KV存储引擎

Key-Value系统只需要支持简单的随机读(Get),写(Put)和删除(Del)操作.由于磁盘是顺序存储介质,因此可以往数据文件追加Key-Value记录并在内存中存放记录所在的磁盘位置,即索引信息.由于对同一个Key的更新(Put)操作以最后一个为准,内存中的索引只需要记录最新的Key-Value对位置即可,而对于删除操作,也是往数据文件追加一个删除记录.由于内存的大小有限,需要尽可能减小索引记录的大小,比如只支持64位的整数Key(其它类型的Key可以通过md5运算得到64位的整数值).

关于mysql的MERGE存储引擎简单例子

关于mysql的MERGE存储引擎简单例子 作用:可以将多个表结构相同的表 和合并到一个表中 版本支持:mysql5.1 如下例子: 假设有如下几个表:结构完全相同 article_0,article_1,article_2,article_3,   -- Table "article_0" DDL CREATE TABLE `article_0` (   `id` bigint(20) NOT NULL,   `subject` varchar(200) NOT NULL,   `c

【Mysql 学习】MERGE存储引擎(一)

MERGE存储引擎(一) MERGE表的问题    MERGE存储引擎,也被认识为MRG_MyISAM引擎,是一个相同的可以被当作一个来用的MyISAM表的集合."相同"意味着所有表同样的列和索引信息.你不能合并列被以不同顺序列于其中的表,没有恰好同样列的表,或有不同顺序索引的表.而且,任何或者所有的表可以用myisampack来压缩.表选项的差异,比如AVG_ROW_LENGTH, MAX_ROWS或PACK_KEYS都不重要.    当你创建一个MERGE表之时,MySQL在磁盘上

【分布式系统工程实现】系统可扩展性演化

一般来说,只要多台机器通过互相协调共同执行某项任务,我们都会将这套系统称为"分布式系统",这样显得更有技术含量.从这个意义上讲,Memcache集群,Mysql sharding集群,Yahoo PNUTS,Google GFS&Bigtable,Amazon Dynamo以及国内众多专用的NOSQL系统都是分布式系统.分布式系统的难点主要在于可扩展性,随着机器数量的增多,集群能力是否能够接近线性扩展,因集群规模扩大而产生的容错需求,负载的动态迁移,对系统的设计和实现是一个巨大

MySQL存储引擎简介及MyISAM和InnoDB的区别_Mysql

MyISAM:默认的MySQL插件式存储引擎,它是在Web.数据仓储和其他应用环境下最常使用的存储引擎之一.注意,通过更改 STORAGE_ENGINE 配置变量,能够方便地更改MySQL服务器的默认存储引擎. InnoDB:用于事务处理应用程序,具有众多特性,包括ACID事务支持. BDB:可替代InnoDB的事务引擎,支持COMMIT.ROLLBACK和其他事务特性. Memory:将所有数据保存在RAM中,在需要快速查找引用和其他类似数据的环境下,可提供极快的访问. Merge:允许MyS

如何选择合适的MySQL存储引擎_Mysql

MySQL支持数个存储引擎作为对不同表的类型的处理器.MySQL存储引擎包括处理事务安全表的引擎和处理非事务安全表的引擎: ◆ MyISAM管理非事务表.它提供高速存储和检索,以及全文搜索能力.MyISAM在所有MySQL配置里被支持,它是默认的存储引擎,除非你配置MySQL默认使用另外一个引擎. ◆ MEMORY存储引擎提供"内存中"表.MERGE存储引擎允许集合将被处理同样的MyISAM表作为一个单独的表.就像MyISAM一样,MEMORY和MERGE存储引擎处理非事务表,这两个引

MySQL数据库存储引擎和分支现状分析_Mysql

MySQL随着相应的各主创和内部开发人员的离去,缔造了各个不同的引擎和分支,让MySQL有希望继续发扬光大起来.  在MySQL经历了2008年Sun的收购和2009年Oracle收购Sun的过程中,基本处于停滞发展的情况,在可以预见的未来,MySQL是肯定会被Oracle搁置并且逐步雪藏消灭掉的.MySQL随着相应的各主创和内部开发人员的离去,缔造了各个不同的引擎和分支,让MySQL有希望继续发扬光大起来. 本文大致讲解一下MySQL目前除了主要的 MyISAM.InnoDB.Heap(Mem

MySQL数据库三种常用存储引擎特性对比_Mysql

MySQL 的存储引擎可能是所有关系型数据库产品中最具有特色的了,不仅可以同时使用多种存储引擎,而且每种存储引擎和MySQL之间使用插件方式这种非常松的耦合关系. 由于各存储引擎功能特性差异较大,这篇文章主要是介绍如何来选择合适的存储引擎来应对不同的业务场景. MyISAM 特性 不支持事务:MyISAM存储引擎不支持事务,所以对事务有要求的业务场景不能使用 表级锁定:其锁定机制是表级索引,这虽然可以让锁定的实现成本很小但是也同时大大降低了其并发性能 读写互相阻塞:不仅会在写入的时候阻塞读取,M

MySql数据库插入式的多存储引擎机制

什么是MySql数据库? 通常意义上,数据库也就是数据的集合,具体到计算机上数据库可以是存储器上一些文件的集合或者一些内存数据的集合. 我们通常说的MySql数据库,sql server数据库等等其实是数据库管理系统,它们可以存储数据,并提供查询和更新数据库中的数据的功能等等.根据数据库如何存储数据和如何操作数据的实现机制不同,这些数据库之间即有区别又有共同点. MySql数据库是开放源代码的关系型数据库.目前,它可以提供的功能有:支持sql语言.子查询.存储过程.触发器.视图.索引.事务.锁.