热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

一种Bitcask存储模型的实现

引言Bitcask是一种key-value存储实现模型,其中心思想是Append写文件,内存索引加速文件读,通过闲时Merge文件减少数据冗余。下面我们从存储方式、索引和缓存三个方

引言

Bitcask 是一种 key-value 存储实现模型,其中心思想是 Append 写文件,内存索引加速文件读,通过闲时 Merge 文件减少数据冗余。下面我们从存储方式、索引和缓存三个方面学习 Bitcask 的具体实现方法。

数据存储方式

Bitcask 中,数据以文本的形式存储,增删改的数据以 Append 的形式追加到数据文件结尾,在数据存放目录下,我们定义两类文件:

xxx.w:数据存储文件,xxx 是一个数值,写满1G数据将新建文件,数值自增,程序往数值最大的一个文件 Append 数据

write.pos:记录当前数值最大的 xxx.w 文件(FileNo),以及该文件的写位移(Offset)

定义了数据文件和记录写位移的文件后,我们通过以下方式实现数据写:

  1. 检查当前 xxx.w 文件写位移 + 当前要写入的数据长度是否大于MAX_FILE_SIZE(即一个数据文件的最大size,这里我们定义为1G);如果大于则创建一个序号增 1 的 .w 文件
  2. 调用 open、write 函数将数据追加到当前 .w 文件结尾
  3. 更新 write.pos 中 FileNo、Offset 的值

读操作同样很简单,对该条数据所在文件的偏移位置读取定长数据。

那问题来了,写操作有 write.pos 文件指明要写入的 FileNo 和 Offset;对于读操作,如何快速地从浩瀚的数据中,找到某个 key 对应数据所在的文件和文件位移呢?挖掘技术到底哪家强?

数据索引

快速地获取 skey 对应的数据,依赖于内存中的数据索引。skey 对应的 FileNo、Offset 以索引的方式存在内存中,下图说明了数据索引的具体实现:

,

实现数据索引的数据结构主要有:

m_pArray数组:长度为 KeySlotSize、以 unsigned int 为元素的数组,负责存储数据索引(MemIdx_t)的索引

KeyBlock组:由 MaxKeyBlock 个 KeyBlock 组成,每一个 KeyBlock 由一个 BlockMetaData 和 MAX_INDEX_PER_BLOCK 个 MemIdx_t 组成

BlockMetaData:存放该 KeyBlock 中有多少个空闲 MemIdx_t 索引等统计数据

MemIdx_t:数据索引,其中 skey(字符串,chat*类型)即为数据的 key,FileNo 和 Offset 分别为 skey 对应数据所在的文件和位移

MetaData:指示 KeyBlock 总数、当前使用的 KeyBlock

m_pArray数组中的 key 作为索引 MemIdx_t 的索引,其与 skey 存在这样的关系:

  1. 根据 skey 计算出一个 hash 值 ihash
  2. 对 key 赋值,m_Array[ihash % KeySlotSize] = iCurBlock <<24 | iIndex,其中 iIndex 为 MemIdx_t 在所在 KeyBlock 的偏移

建立 key 后,根据 skey 找到对应的磁盘数据块就变得简单了:

  1. 根据 skey 计算出一个 hash 值 ihash
  2. myKeyBlock = m_pArray[ihash % KeySlotSize] >> 24,myMemIdx_Offset = m_pArray[ihash % KeySlotSize] ^ (1<<24)
  3. 根据 myKeyBlock、myMemIdx_Offset 找到对应 MemIdx_t,取得 FileNo、Offset

数据缓存

像很多其他数据库一样,我们也可以实现自己的缓存,即访问 skey 对应数据的时候,不是直接走以上步骤从磁盘读取数据,而是先看内存中有没有相应数据,有的话取内存数据,减少磁盘访问。实现缓存的数据结构如下:

,

有了缓存,读取数据变成了以下过程:

  1. 根据 skey 算出一个 hash 值 ihash
  2. 判断 m_pstMemData[ ihash % KeySlotSize ].skey == skey,是则表示缓存中有相应数据,从缓存中读取返回
  3. 如在缓存中查不到 skey 对应的数据,则执行以上从硬盘读取数据的过程
  4. 读取完硬盘数据后,将 skey 对应的数据放入缓存中

同样在新增数据的时候,完成写盘后会更新数据缓存中 skey 相应的数据。

小结

本文从数据存储方式、索引、缓存三方面介绍了 Bitcask 的一种具体实现方法。增删改都用 Append 的实现方式简洁、提高了写盘效率,其通过闲时 Merge 消除数据冗余。

一种 Bitcask 存储模型的实现


推荐阅读
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文介绍了指针的概念以及在函数调用时使用指针作为参数的情况。指针存放的是变量的地址,通过指针可以修改指针所指的变量的值。然而,如果想要修改指针的指向,就需要使用指针的引用。文章还通过一个简单的示例代码解释了指针的引用的使用方法,并思考了在修改指针的指向后,取指针的输出结果。 ... [详细]
  • 在project.properties添加#Projecttarget.targetandroid-19android.library.reference.1..Sliding ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
author-avatar
php.net
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有