本节主要记录SSTable的结构 为下一步代码阅读打好基础,考虑到已经有大量优秀博客解析透彻 就再也不编写了 算法
这里推荐 https://blog.csdn.net/tankles/article/details/7663905app
SSTable是Bigtable中相当重要的一块,对于LevelDB来讲也是如此,对LevelDB的SSTable实现细节的了解也有助于了解Bigtable中一些实现细节。
本节内容主要讲述SSTable的静态布局结构,SSTable文件造成了不一样Level的层级结构,至于这个层级结构是如何造成的咱们放在后面Compaction一节细说。本节主要介绍SSTable某个文件的物理布局和逻辑布局结构,这对了解LevelDB的运行过程颇有帮助。
LevelDB不一样层级都有一个或多个SSTable文件(之后缀.sst为特征),全部.sst文件内部布局都是同样的。上节介绍Log文件是物理分块的,SSTable也同样会将文件划分为固定大小的物理存储块Block,可是二者逻辑布局大不相同,根本缘由是:Log文件中的记录是Key无序的,即前后记录的key大小没有明确大小关系,而.sst文件内部则是根据记录的Key由小到大排列的,从下面介绍的SSTable布局能够体会到Key有序是为什么如此设计.sst文件结构的关键。 布局
图1 .sst文件的分块结构
图1展现了一个.sst文件的物理划分结构,同Log文件同样,也是划分为固定大小的存储块,每一个Block分为三个部分,包括Block、Type和CRC。Block为数据存储区,Type区用于标识Block中数据是否采用了数据压缩算法(Snappy压缩或者无压缩两种),CRC部分则是Block数据校验码,用于判别数据是否在生成和传输中出错。
以上是.sst的物理布局,下面介绍.sst文件的逻辑布局,所谓逻辑布局,就是说尽管你们都是物理块,可是每一块存储什么内容,内部又有什么结构等。图2展现了.sst文件的内部逻辑解释。 .net
图2 逻辑布局
从图2能够看出,从大的方面,能够将.sst文件划分为数据存储区和数据管理区,数据存储区存放实际的Key:Value数据,数据管理区则提供一些索引指针等管理数据,目的是更快速便捷的查找相应的记录。两个区域都是在上述的分块基础上的,就是说文件的前面若干块实际存储KV数据,后面数据管理区存储管理数据。管理数据又分为四种不一样类型:紫色的Meta Block,红色的MetaBlock Index和蓝色的Index block以及一个文件尾部块Footer。
LevelDB 1.2版对于Meta Block尚无实际使用,只是保留了一个接口,估计会在后续版本中加入内容,下面咱们看看Index block和文件尾部Footer的内部结构。设计
图3 Index block结构
图3是Index block的内部结构示意图。再次强调一下,Data Block内的KV记录是按照Key由小到大排列的,Index block的每条记录是对某个Data Block创建的索引信息,每条索引信息包含三个内容:Data Block中key上限值(不必定是最大key)、Data Block在.sst文件的偏移和大小,以图3所示的数据块i的索引Index i来讲:红色部分的第一个字段记载大于等于数据块i中最大的Key值的那个Key,第二个字段指出数据块i在.sst文件中的起始位置,第三个字段指出Data Block i的大小(有时候是有数据压缩的)。后面两个字段好理解,是用于定位数据块在文件中的位置的,第一个字段须要详细解释一下,在索引里保存的这个Key值未必必定是某条记录的Key,以图3的例子来讲,假设数据块i 的最小Key=“samecity”,最大Key=“the best”;数据块i+1的最小Key=“the fox”,最大Key=“zoo”,那么对于数据块i的索引Index i来讲,其第一个字段记载大于等于数据块i的最大Key(“the best”),同时要小于数据块i+1的最小Key(“the fox”),因此例子中Index i的第一个字段是:“the c”,这个是知足要求的;而Index i+1的第一个字段则是“zoo”,即数据块i+1的最大Key。
文件末尾Footer块的内部结构见图4,metaindex_handle指出了metaindex block的起始位置和大小;inex_handle指出了index Block的起始地址和大小;这两个字段能够理解为索引的索引,是为了正确读出索引值而设立的,后面跟着一个填充区和魔数(0xdb4775248b80fb57)。 3d
图4 Footer 指针
上面主要介绍的是数据管理区的内部结构,下面咱们看看数据区的一个Block的数据部份内部是如何布局的,图5是其内部布局示意图。 blog
图5 Data Block内部结构
从图中能够看出,其内部也分为两个部分,前面是一个个KV记录,其顺序是根据Key值由小到大排列的,在Block尾部则是一些“重启点”(Restart Point),实际上是一些指针,指出Block内容中的一些记录位置。
“重启点”是干什么的呢?简单来讲就是进行数据压缩,减小存储空间。咱们一再强调,Block内容里的KV记录是按照Key大小有序的,这样的话,相邻的两条记录极可能Key部分存在重叠,好比key i=“the car”,Key i+1=“the color”,那么二者存在重叠部分“the c”,为了减小Key的存储量,Key i+1能够只存储和上一条Key不一样的部分“olor”,二者的共同部分从Key i中能够得到。记录的Key在Block内容部分就是这么存储的,主要目的是减小存储开销。“重启点”的意思是:在这条记录开始,再也不采起只记载不一样的Key部分,而是从新记录全部的Key值,假设Key i+1是一个重启点,那么Key里面会完整存储“the color”,而不是采用简略的“olor”方式。可是若是记录条数比较多,随机访问一条记录,须要从头开始一直解析才行,这样也产生很大的开销,因此设置了多个重启点,Block尾部就是指出哪些记录是这些重启点的。 索引
在Block内容区,每一个KV记录的内部结构是怎样的?图6给出了其详细结构,每一个记录包含5个字段:key共享长度,key非共享长度,value长度,key非共享内容,value内容。好比上面的“the car”和“the color”记录,key共享长度5;key非共享长度是4;而key非共享内容则实际存储“olor”;value长度及内容分别指出Key:Value中Value的长度和存储实际的Value值。
上面讲的这些就是.sst文件的所有内部奥秘。
原文:https://blog.csdn.net/tankles/article/details/7663905?utm_source=copy