SSTable 介绍(一)
如果说Protocol Buffers是Google内部表示独立数据记录的单元,那么排序的字符串表--Sorted String Table(SSTable)--是存储,处理和交换数据集的最流行的输出之一。正如名字本身所包含的意思一样,SSTable是一个简单的抽象,用来高效地存储大量的键-值对数据,同时做了优化来实现顺序读/写操作的高吞吐量。
2015.5.28 update 重读了一遍,做了一些小的修改:
SSTable的适用场景:
SSTable的产生背景:
假设我们需要处理输入量级在G或者T字节级别的一系列任务。而且我们需要执行很多步骤,这些步骤是不同的程序执行的--换句话说,假设我们在运行一系列的Map-Reduce任务。鉴于输入的数据量级很大,所以读取和写入数据就能够占运行时间的大头。因此,就不考虑随机读取和写入的情况了,相反我们流式处理输入数据,一旦处理完成,同样利用流式操作把结果数据写回到磁盘上。这样,我们可以摊薄磁盘I/O操作的成本。
所以SSTable是一个简单,但是非常有用的用来交换大量的、排好序的数据片段的数据结构。它的使用场景是:
- 需要高效地存储大量的键-值对数据
- 数据是顺序写入
- 要求高效地顺序读写
- 没有随机读取或者对随机读取性能要求不高
SSTable简介:
Google Bigtable论文中对SSTable的介绍:
SSTable提供一个可持久化[persistent],有序的、不可变的从键到值的映射关系,其中键和值都是任意字节长度的字符串。SSTable提供了以下操作:按照某个键来查询关联值,可以指定键的范围,来遍历其中所有的键值对。每个SSTable内部由一系列块(block)组成(通常每块大小为64KB,是可配置的)。使用存储在SSTable结尾的块索引(block index)来定位块;当SSTable打开时,索引会被加载到内存里。一次磁盘寻道(disk seek)就可以完成查询(lookup)操作:首先通过二分查找在存储在内存的索引中找到对应的块,然后从磁盘上读取这块内容。SSTable也可以完整地映射到内存里,这样在执行查询和扫描(scan)的时候就不用操作磁盘了.
所以可以简单的总结:
SSTable是一个键是有序的,存储字符串形式键值对的文件。
SSTable的设计:
"Sorted String Table"就如名字所言,它是一个内部包含了任意长度、排好序的键值对<key,value>集合的文件。其结构如上图所示,SSTable文件由两部分数据组成:索引和键值对数据。所有的key和value都是紧凑地存放在一起的,如果要读取某个键对应的值,需要通过索引中的key:offset来定位。
从上图可以看到,因为SSTable文件中所有的键值对<key,value>是存放到一起的,所以SSTable在序列化成文件之后,是不可变的,因为此时的SSTable,就类似于一个数组一样,如果插入或者删除,需要移动一大片数据,开销比较大。
顺序读取整个文件,就拿到了一个排好序的索引。如果文件很大,还可以为了加速访问而追加或者单独建立一个独立的key:offset的索引。
leveldb中,SSTable的实现
leveldb/目录是存放对外开放的API头文件的目录,对作用域等做了严格的限制,为了避免引入多余的依赖关系,比较多的使用了类和结构体的前置声明[forward declaration]。
SSTable对应的实现是Table类,头文件是:include/leveldb/table.h。通过Table类开头的注释可以看到Table是不可变的,可持久化的。SSTable由于是不可改变的,只读的,所以是线程安全的,不需要外界的同步操作。
Table对外接口:
Table类只提供了简单的3个操作:
- 通过文件来反序列化,读取SSTable的数据:
static Status Open(const Options& options, RandomAccessFile* file, uint64_t file_size, Table** table)
; - 获得用来访问SSTable数据的迭代器:
Iterator* NewIterator(const ReadOptions&) const
SSTable的数据读取都是通过迭代器进行的,迭代器也只允许读取操作,没有提供写入操作。 - 预估key[可能还没有写入到SSTable中]对应的数据存储到SSTable文件的偏移:
uin64_t ApproximateOffsetOf(const Slice& key) const
leveldb对外提供了GetApproximateSizes()
--通过指定key的范围来获取存储这些数据的文件大致大小的功能,所以需要底层的这些数据结构也来提供对应的功能。同时这类函数也能提高leveldb系统的可测性,通过文件的大小就可以判断写入数据是否正常。
可以看到SSTable的拷贝构造函数Table(const Table)
和赋值函数void operator=(const Table&)
都是私有的,这样就是禁止SSTable对象的拷贝了。Table类的使用方,只能通过Open
接口来反序列化SSTable对象。
Table需要知道的类和结构体
通过table.h头文件可以看到它需要打交道的类或者结构体主要有:
class Block:
上文提到每个SSTable文件由一系列可配置大小的块(block)组成。Block就是对block块数据的封装,对外提供size()和迭代器Iterator接口。class BlockHandle
定义在table/format.h中,代表了存储数据的文件的范围:偏移offset+大小sizeclass Footer:
定义在table/format.h中,封装了在每个SSTable文件尾部存储的固定大小的元数据信息(metadata),包含了两部分数据:metaindex和index数据。index数据就是上文中提到的SSTable的索引数据,而metaindex存储的是过滤器(例如布隆过滤器)的信息。利用过滤器,可以显著地减少磁盘访问。class RandomAccessFile:
SSTable关联的文件,是可以随机读取的文件:可以指定从哪里开始读,读取多少字节,方便SSTable按照需要去读取block的数据struct ReadOptions, Struct Options
把一堆选项相关的参数定义到结构体里,方便传递参数,也方便理解,否则看到的就是一堆参数了。class TableCache
一个SSTable的缓存(cache),每次需要对某个SSTable文件要做读取操作时,去对应的TableCache里面进行操作[如果没有命中缓存,会加载这个SSTable数据并更新缓存]。TableCache里面包含了SSTable的全部内容:索引+数据struct Table::Rep
定义在table.cc中[是Table类内部使用的结构体],存储了SSTable相关的一些元数据,例如当前SSTable实例对应的文件句柄[file]、在Table缓存中的句柄[cache_id]、过滤器的读取对象[filter]、过滤器的数据[filter_data]、元索引[metaindex_handle]和索引[index]数据。有了这些数据,就可以唯一地代表一个SSTable的数据了。
单独说一下迭代器Iterator,此接口类提供了丰富的数据访问操作,所有对SSTable和SSTable中block的读取操作都用迭代器来进行。迭代器定义在include/leveldb/iterator.h中,这里也只是定义了一个迭代器的接口类,规定了对外的统一接口函数,这些接口函数都是纯虚函数,需要子类去实现。在leveldb中可以看到很多这样的例子,这就是面向接口编程的思想。通过迭代器类Iterator的定义看到,table类对外的数据访问只能通过迭代器类Iterator来进行,而且迭代器只提供读取操作,key()和value()函数都是const类型,不允许修改Iterator类内部的数据。迭代器还提供了RegisterCleanup函数,可以用挂接多个CleanupFunction类型的回调函数并自定义两个参数。CleanupFunction是用来在迭代器销毁时,做自定义的清理工作。
从format.h中还可以看到Table定义了Table内部使用的类和结构体:
- struct BlockContents
封装了SSTable中每一个block的数据信息,包含实际存储的数据(Slice data), 是否可以缓存(bool cacheable), 是否需要调用方释放存储数据的内存这三类信息。
SSTable的特点
* 存储的是<键,值>格式的字节数据
* 字节数据的长度随意,没有限制
* 键可以重复, 键值对不需要对齐
* 随机读取操作非常高效
SSTable的限制
* 一旦SSTable写入硬盘后,就是不可变的,因为插入或者删除需要对SSTable文件进行大量的I/O操作
* 不适合随机读取和写入,因为效率很低,原因同上一条
关于SSTable的设计,还有一些东西没有介绍,例如在磁盘上存储的具体格式,如何序列化等,留待下一篇介绍。
回到本系列目录:leveldb源码学习系列
SSTable 介绍(一)的更多相关文章
- SSTable 介绍(二)
作者:Jack47 上一篇SSTable 介绍(一)介绍了SSTable的适用场景和leveldb中SSTable的设计.本篇介绍SSTable文件的结构组成. SSTable的特点 首先明确一下上文 ...
- leveldb源码学习系列
楼主从2014年7月份开始学习<>,由于书籍比较抽象,为了加深思考,同时开始了Google leveldb的源码学习,主要是想学习leveldb的设计思想和Google的C++编程规范.目 ...
- leveldb 学习记录(五)SSTable格式介绍
本节主要记录SSTable的结构 为下一步代码阅读打好基础,考虑到已经有大量优秀博客解析透彻 就不再编写了 这里推荐 https://blog.csdn.net/tankles/article/det ...
- leveldb源码分析--SSTable之Compaction
对于compaction是leveldb中体量最大的一部分,也应该是最为复杂的部分,为了便于理解我们首先从一些基本的概念开始.下面是一些从doc/impl.html中翻译和整理的内容: Level 0 ...
- LevelDb简单介绍和原理——本质:类似nedb,插入数据文件不断增长(快照),再通过删除老数据做更新
转自:http://www.cnblogs.com/haippy/archive/2011/12/04/2276064.html 有时间再好好看下整个文章! 说起LevelDb也许您不清楚,但是如果作 ...
- LevelDB系列之SSTable(Sorted Strings Table)文件
SSTable是Bigtable中至关重要的一块,对于LevelDb来说也是如此,对LevelDb的SSTable实现细节的了解也有助于了解Bigtable中一些实现细节. 本节内容主要讲述SSTab ...
- leveldb 学习记录(六)SSTable:Block操作
block结构示意图 sstable中Block 头文件如下: class Block { public: // Initialize the block with the specified con ...
- leveldb源码分析--SSTable之block
在SSTable中主要存储数据的地方是data block,block_builder就是这个专门进行block的组织的地方,我们来详细看看其中的内容,其主要有Add,Finish和CurrentSi ...
- leveldb源码分析--SSTable之TableBuilder
上一篇文章讲述了SSTable的格式以后,本文结合源码解析SSTable是如何生成的. void TableBuilder::Add(const Slice& key, const Slice ...
随机推荐
- [python] 创建临时文件-tempfile模块
This module generates temporary files and directories. It works on all supported platforms.In versio ...
- IIS配置excel 权限
http://www.cnblogs.com/zhuxiaohui/archive/2013/10/16/3371637.html
- make: Nothing to be done for `first'
在qt目录下make后出现以下错误: make: Nothing to be done for `first' 解决:将你当前目录下的,删除你程序主要的 *.cpp 和 *.h文件以外的所有文件. 接 ...
- 引用64位dll时候出现 未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项。试图加载格式不正确的程序。
引用64位dll时候出现 未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项.试图加载格式不正确的程序. 需要在web.config增加配置 <startup use ...
- ASP.NET操作ORACLE数据库之模糊查询
ASP.NET操作ORACLE数据库之模糊查询 一.ASP.NET MVC利用OracleHelper辅助类操作ORACLE数据库 //连接Oracle数据库的连接字符串 string connect ...
- python入门简介
Python前世今生 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC ...
- flask_分页
一.提交博客文章 1.定义一个单字段的表单对象(form.py) class PostForm(Form): post = StringField('post', validators=[DataRe ...
- 『TCP/IP详解——卷一:协议』读书笔记——16
2013-08-26 22:50:54 6.4 ICMP时间戳请求与应答 ICMP时间戳请求允许系统向另一个系统查询当前的时间.返回的建议值是自午夜开始计算的毫秒数(协调的统一时间,Coordinat ...
- Core Audio(二)
用户模式音频组件 在windows vista中,core audio apis充当用户模式音频子系统的基础,core audio apis作为用户模式系统组件的一个thin layer,它用来将用户 ...
- C# XMAL与WPF
通过老师上课的解释和我下课后的网上查询,我了解到了一些关于这三者的关系.XAML是.NET体系开发程序或者网页时前台编程的一种布局方式或者说开发语言,可以比较自由的用标签的方式进行布局,借鉴了HTML ...