Bitcask存储模型
----《大规模分布式存储系统:原理解析与架构实战》读书笔记
近期一直在分析OceanBase的源代码,恰巧碰到了OceanBase的核心开发人员的新作《大规模分布式存储系统:原理解析与架构实战》.看完样章后决定入手,果然物有所值。
对于准备学习分布式的同学,这是一本不错的书籍,相对系统,全面的介绍了分布式的相关技术和项目,基本都是干货。
另一半是在介绍OceanBase的内容,对我来说,正是踏破铁鞋无觅处。接下来会有几篇专门研究存储引擎的读书笔记哟。废话不多说,转入正题。
1.存储的介质与读写
谈存储。那么理解存储的介质的特性显然非常重要。书中谈了非常多硬件结构,但最重要的结论,都浓缩在存储介质对照这张表中了。
磁盘介质对照
| 类别 | 每秒读写(IOPS)次数 | 每GB价格(元) | 随机读取 | 随机写入 |
|---|---|---|---|---|
| 内存 | 千万级 | 150 | 友好 | 友好 |
| SSD盘 | 35000 | 20 | 友好 | 写入放大问题 |
| SAS磁盘 | 180 | 3 | 磁盘寻道 | 磁盘寻道 |
| SATA磁盘 | 90 | 0.5 | 磁盘寻道 | 磁盘寻道 |
从表中能够看出,内存的随机读写能力最强,远超SSD盘和磁盘。可是我们都知道。内存无法持久化。如今很多公司在性能要求高的地方都使用了SSD盘。相对SAS和SATA磁盘,随机读取速度有了非常大的提升。
可是对于随机写入,存在写入放大问题。
写入放大问题与SSD盘的特性有关,SSD盘不能随机写入,仅仅能整块整块的写入。最简单的样例,比方要写入一个4KB的数据。最坏的情况就是,一个块里已经没有干净空间了,可是有无效数据能够擦除,所以主控就把全部的数据读出来。擦除块,再加上这个4KB新数据写回去,这个操作带来的写入放大就是: 实际写4K的数据,造成了整个块(512KB)的写入操作,那就是128倍放大。此外,SSD盘的寿命也有写入次数相关。
假设使用SSD来作为存储引擎的存储介质。最好从设计上降低或避免随机写入,使用顺序写入取而代之。
2.Bitcask存储模型介绍
存储系统的基本功能包含:增、删、读、改。当中读取操作有分为顺序读取和随机读取。
整体来说,大部分应用使用读的功能最多,解决读的性能是存储系统的重要命题。一般来说。高速查找的思想基本源自二分查找法和哈希查询。
比如关系数据库中经常使用的B+存储模型就是使用二分查找的思想,当然,实际实现比二分查找复杂非常多。B+存储模型支持顺序扫描。另外一类则是基于哈希思想的键值模型,这类模型不支持顺序扫描,仅支持随机读取。
今天要讨论的Bitcask模型是一种日志型键值模型。
所谓日志型,是指它不直接支持随机写入。而是像日志一样支持追加操作。
Bitcask模型将随机写入转化为顺序写入。有两个优点:
- 提高随机写入的吞吐量,由于写操作不须要查找。直接追加就可以
- 假设使用SSD作为存储介质,可以更好的利用新硬件的特性
Bitcask中存在3种文件,包括数据文件,索引文件和线索文件(hint file,姑且就叫线索文件吧)。数据文件存储于磁盘上,包括了原始的数据的键值信息;索引文件存在于内存,用于记录记录的位置信息,启动Bitcask时。它会将所有数据的位置信息所有读入一个内存中的哈希表,也就是索引文件;线索文件(hint file)并非Bitcask的必需文件,它的存在是为了提供启动时构建索引文件的速度。
2.1 日志型的数据文件
Bitcask的数据文件组织例如以下图:随意时刻。系统中仅仅有一个数据文件支持写入。称为active data file。其余的数据文件都是仅仅读文件,称为older data file。
文件里的数据结构很easy,是一条一条的数据写入操作。每一条数据的结构例如以下:
上面数据项分别为:后面几项的crc校验值,时间戳,key,value,key的大小。value的大小。
数据文件里就是连续一条条上面格式的数据,例如以下图:
2.2 索引哈希表
索引哈希表记录了所有记录的主键和位置信息,索引哈希表的值包括了:记录文件的编号,value长度,value的在文件里的位置和时间戳。Bitcask的整体数据结构例如以下图:
2.3 线索文件(hint file)
Bitcask启动时要重建索引哈希表。假设数据量特别大。则会导致启动非常慢。
而线索文件(hint file)则是用来加速启动时重建哈希表的速度。线索文件(hint file)的记录与数据文件的格式基本同样,唯一不同的是数据文件记录数据的值。而线索文件(hint file)则是记录数据的位置。
这样在启动的时候就能够不用读数据文件,而是读取线索文件(hint file)。一行行重建就可以,大大加快了哈希表的重建速度。
3. Bitcask功能介绍
上节提到,存储系统的基本功能包含:增、删、读、改。
那么Bitcask中怎样实现的呢?
怎样添加记录?
用户写入的记录直接追加到活动文件,因此活动文件会越来越大。当到达一定大小时。Bitcask会冻结活动文件。新建一个活动文件用于写入,而之前的活动文件则变为了older data file。写入记录的同一时候还要在索引哈希表中加入索引记录。
怎样删除记录?
Bitcask不直接删除记录。而是新增一条同样key的记录,把value值设置一个删除的标记。原有记录依旧存在于数据文件里。然后更新索引哈希表。怎样改动记录?
Bitcask不支持随机写入。由于对于存储系统的基本功能中的增和改。实际上都是一样的。都是直接写入活动数据文件。同一时候改动索引哈希表中相应记录的值。
(这个时候。实际上数据文件里同一个key值相应了多条记录,依据时间戳记录来推断,以最新的数据为准。
)
怎样读取记录?
读取时,首先从索引哈希表中定位到记录在磁盘中位置,然后通过IO读取出相应的记录。合并(Marge)操作
Bitcask这样的仅仅增不减地不断写入,必定会是数据文件不断的膨胀。而当中有很多是被标记删除和改动后留下的无用记录。合并操作就是为了剔除这部分数据,减小数据文件大小。
merge操作。通过定期将全部older data file中的数据扫描一遍并生成新的data file(没有包含active data file 是由于它还在不停写入)。假设同一个Key有多条记录。则仅仅保留最新的一条。从而去掉数据文件里的冗余数据。并且进行合并(Marge)操作时,还能够顺带生成线索文件(hint file)。合并(Marge)操作一般会在数据库较闲的时候进行。比方凌晨一两点等。
4.总结
Bitcask是一个精炼的键值存储模型。採用日志型的数据结构。仅仅追加不改写就记录,提高了随机写入的吞吐量,通过建立哈希表来加快查询速度,定期合并数据文件。并生成线索文件(hint file),提高启动时重建哈希表的速度。
这是我參考了网上的一个python实现。并添加了部分功能后的代码: dest=https%3A%2F%2Fgithub.com%2FWinnerhust%2FCode-of-Book%2Fblob%2Fmaster%2FLarge-Scale-Distributed-Storage-System%2Fbitcask.py" style="margin:0px; padding:0px; border:0px; line-height:1.428571em; word-break:break-all; color:rgb(4,122,198); background-color:transparent">
除了增删读写外,主要还实现了:
- 数据文件合并,合并时能够选择生成线索文件(hint file)
- 能够使用线索文件(hint file)启动
參考:
bitcask
优雅的Bitcask
Bitcask存储模型的更多相关文章
- Bitcask 存储模型
Bitcask 存储模型 Bitcask 是一个日志型.基于hash表结构的key-value存储模型,以Bitcask为存储模型的K-V系统有 Riak和 beansdb新版本. 日志型数据存储 何 ...
- LSM树存储模型
----<大规模分布式存储系统:原理解析与架构实战>读书笔记 之前研究了Bitcask存储模型,今天来看看LSM存储模型,两者尽管同属于基于键值的日志型存储模型.可是Bitcask使用哈希 ...
- Entity Framework 6 Recipes 2nd Edition(10-5)译 -> 在存储模型中使用自定义函数
10-5. 在存储模型中使用自定义函数 问题 想在模型中使用自定义函数,而不是存储过程. 解决方案 假设我们数据库里有成员(members)和他们已经发送的信息(messages) 关系数据表,如Fi ...
- SQLite剖析之存储模型
前言 SQLite作为嵌入式数据库,通常针对的应用的数据量相对于DBMS的数据量小.所以它的存储模型设计得非常简单,总的来说,SQLite把一个数据文件分成若干大小相等的页面,然后以B树的形式来组织这 ...
- LSM存储模型
LSM存储模型 数据库有3种基本的存储引擎: 哈希表,支持增.删.改以及随机读取操作,但不支持顺序扫描,对应的存储系统为key-value存储系统.对于key-value的插入以及查询,哈希表的复杂度 ...
- SQLite入门与分析(八)---存储模型(1)
写在前面:SQLite作为嵌入式数据库,通常针对的应用的数据量相对于通常DBMS的数据量是较小的.所以它的存储模型设计得非常简单,总的来说,SQLite把一个数据文件分成若干大小相等的页面,然后以B树 ...
- 剖析Elasticsearch集群系列第一篇 Elasticsearch的存储模型和读写操作
剖析Elasticsearch集群系列涵盖了当今最流行的分布式搜索引擎Elasticsearch的底层架构和原型实例. 本文是这个系列的第一篇,在本文中,我们将讨论的Elasticsearch的底层存 ...
- 剖析Elasticsearch集群系列之一:Elasticsearch的存储模型和读写操作
转载:http://www.infoq.com/cn/articles/analysis-of-elasticsearch-cluster-part01 1.辨析Elasticsearch的索引与Lu ...
- 并发编程学习笔记之Java存储模型(十三)
概述 Java存储模型(JMM),安全发布.规约,同步策略等等的安全性得益于JMM,在你理解了为什么这些机制会如此工作后,可以更容易有效地使用它们. 1. 什么是存储模型,要它何用. 如果缺少同步,就 ...
随机推荐
- centos源更新
.备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup .下载新的CentOS-Base.r ...
- sessionStorage 的使用
sessionStorage 的使用: sessionStorage.removeItem("data"); sessionStorage.getItem("data&q ...
- day03_12/13/2016_bean的管理之初始化和销毁
- Mac使用bootcamp安装win8.1出现网卡驱动没有安装问题
问题:没有网络连接 原因:在bootcamp烧的u盘里面其实附带了驱动,只是没有自动安装 解决:D:\BootCamp\Drivers\Broadcom\BroadcomWirelessWin8x64 ...
- SpringBoot 搭建
1.使用Eclipse 建立Maven项目(webapp OR quickstart) 2.配置Maven,如下: <parent> <groupId>org.springfr ...
- JS高级——原型链
构造函数 构造函数是特殊的函数,里面没有returen返回值 new的过程中,会自动将对象返回,不需要return new的过程中,会执行函数中的代码,会将创建的对象赋值给构造函数中的this 基本概 ...
- html5——web存储
基本概念 1.传统方式我们以document.cookie来进行存储的,但是由于其存储大小只有4k左右,并且解析也相当的复杂,给开发带来诸多不便 2.h5存储设置.读取方便,而且容量较大,sessio ...
- [Windows Server 2012] IIS自带FTP配置方法
★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频.★ 本节我们将带领大家:IIS自带FT ...
- 【译】x86程序员手册21-6.3.5为操作系统保留的指令
6.3.5 Some Instructions are Reserved for Operating System 为操作系统保留的一些指令 Instructions that have the po ...
- AcGePoint3d ads_point 转换
AcGePoint3d (AcGePoint2d )转换 ads_point 用:asDblArray函数. ads_point 转换AcGePoint2d 用asPnt2d(const doubl ...