LSM tree保证数据库是有序写入(memtable-skiplist),起高了写性能,但是因为其本身的分层结构,牺牲了读性能(一个key如存储在了低级别的level,从上到下每一层都要进行查找,代价极大)。所以,针对读的性能提升有了很多的优化:bloom filter (高效判读一个key是否不存在),index-filter(二分查找,消耗低内存的情况下)索引key-value数据。这一些数据库都需要存储在SST文件之中,用来进行k-v数据的有序管理。

SST文件格式概览

1)Footer : 固定48字节,指出 IndexBlock 和 MetaIndexBlock 在文件中的偏移量信息,它是元信息的元信息,它位于 sstable 文件的尾部

2)IndexBlock:占用一个 block 空间,记录了 DataBlock 相关的元信息

3)MetaIndexBlock:占用一个 block 空间,各个元信息的Block,包括Filter、Properties(整个table的属性信息)、Compression dictionary、Range deletion tombstone

4)MetaBlock:可能占用多个 block空间,存储布隆过滤器的二进制数据 及其他元信息数据

5)DataBlock:可能占用多个 block空间,存储实际的数据即键值对内容

Footer 结构

Footer固定48个字节大小,位于SSTable文件尾部;MetaBlockIndex和DataBlockIndex的offset和size组成BlockHandlel类型,用于寻址MetaBlockIndex和DataBlcokIndex的块所在的位置,size和offset采用varint变长编码,以节省空间,offset和size最少占用1个字节长度、最多占用9个字节长度,因此MetaBlockIndex和DataBlockIndex的offset和size最多占用4*9=36个字节,通过padding补齐到40个字节(8字节对齐);比如DataBlockIndex.offset = 64、DataBlockIndex.size=216,表示DataBlockIndex位于SSTable文件的第64个字节至280个字节。

Block 结构

5个部分的数据结构,除了 Footer,其他的物理结构都是 Block 形式。每个 Block 对应物理磁盘的一个存储块,因此, Block 的大小与磁盘存储块的大小一致.这也是Footer放到文件末尾的原因,Footer本身48个字节不能占用一个磁盘存储块.Block 在硬盘上存储的时候,会在实际数据之后加上5个字节的额外内容:compression type、crc。

Data Block 结构

DataBlcok Key 的存储采用了前缀压缩机制,前缀压缩,就是对于 key 的相同前缀,尽量只存储一次以节省空间。但是对于 SSTable 来说它并不是对整个 block 的所有 key 进行一次性地前缀压缩,而是设置了很多区段,处于同一区段的 key 进行一次前缀压缩,每个区段的起点就是一个重启点。前缀压缩机制导致每条记录需要记住它对应的 key 的共享长度和非共享长度。所 谓 key 的共享长度,是指当前这条记录的 key 与上一条记录的 key 公共前缀的长 度,非共享长度则是去掉相同部分后的不同部分的长度。这样当前这条记录只需要存储不同的那部分 key 的值即可。

第一部分(Entry)用来存储key-value数据。由于sstable中所有的key-value对都是严格按序存储的,用了节省存储空间,并不会为每一对key-value对都存储完整的key值,而是存储与上一个key非共享的部分,避免了key重复内容的存储。每间隔若干个key-value对,将为该条记录重新存储一个完整的key。重复该过程(默认间隔值为16),每个重新存储完整key的点称之为Restart point。

Restart point的目的是在读取sstable内容时,加速查找的过程。由于每个Restart point存储的都是完整的key值,因此在sstable中进行数据查找时,可以首先利用restart point点的数据进行键值比较,以便于快速定位目标数据所在的区域;当确定目标数据所在区域时,再依次对区间内所有数据项逐项比较key值,进行细粒度地查找;该思想有点类似于跳表中利用高层数据迅速定位,底层数据详细查找的理念,降低查找的复杂度。

KV 数据存储结构

  • shared key length: 与 restart point 相同的key前缀字节长度.
  • unshared key length: 当前key减去restart point 相同前缀长度后,剩余的字节长度
  • value length: 数值的字节长度
  • unshared key content: key与restart point中的key不相同部分的key内容.
  • value: 存储真实的数值

Index Block 结构

index block包含若干条记录,每一条记录代表一个data block的索引信息,用于快速定位到包含特定key的Data Block;Index Block首先是一个block,因此包含三部分KeyValue、Type(固定1字节)、CRC检验码(固定4字节);Type标识该部分数据是否采用压缩算法,CRC是KeyValue + Type的检验码。

一条索引包括以下内容:

  • key,取值是大于等于其索引block的最大key,并且小于下一个block的最小key;
  • 该data block起始地址在sstable中的偏移量;
  • 该data block的大小;

IndexBlock和 DataBlock 一样,采取了前缀压缩,只不过间隔为2(DataBlock 默认为16)。

为什么key不是采用其索引的DataBlock的最大key?

主要目的是节省空间;假设其索引的block的最大key为"acknowledge",下一个block最小的key为"apple",如果DataBlockIndex的key采用其索引block的最大key,占用长度为len("acknowledge");采用后一种方式,key值可以为"ad"("acknowledge" < "ad" < "apple"),长度仅为2,并且检索效果是一样的。

为什么BlockHandle的offset和size的单位是字节数而不是block?

因为SSTable中的block大小是不固定的,虽然option中可以指定block_size参数,但SSTable中存储数据时,并未严格按照block_size对齐,所以offset和size指的是偏移字节数和长度字节数。这样做主要有两个原因:

(1)可以存储任意长度的key和任意长度的value,而同一个key-value是不能跨block存储的,极端情况下,比如我们的单个 value 就很大,已经超过了 block_size,那么对于这种情况,SSTable 就没法进 行存储了。所以通常,实际的 Block 大小都是要略微大于 block_size 的;

(2)从另外一个角度看,如果严格按照block_size对齐存储数据,必然有很多block通过补0的方式对齐,浪费存储空间。

云原生数据库-开务分布式数据库SST文件结构相关推荐

  1. 技术沙龙 | 数据库技术大会开务分布式数据库专场

    对于数据库领域的业内人士来讲,一年一度的DTCC中国数据库技术大会承载了大家太多的期待,在这里有数据库大厂之间的PK较量,有业内专家的干货分享.然而受新冠疫情的影响,为响应北京市最新疫情防控要求,保障 ...

  2. 开务分布式数据库 Tracing(二)—— 源码解析

    按照[开务数据库 Tracing(一)]介绍的使用opentracing要求,本文着重介绍开务数据库(原:云溪数据库)Tracing模块中是如何实现Span,SpanContexts和Tracer的. ...

  3. PingCAP黄东旭:云原生、开源与分布式是数据库行业发展关键词

    12月23-24日,2021数据技术嘉年华(DTC)将在北京丽都皇冠假日酒店盛大开启.围绕"智能·创新·新生态--数据智领未来 生态共创价值"这一主题,来自数据领域的领军人物.学术 ...

  4. 【推荐】2020,2021网易数字+大会(云原生微服务+大数据数据库+网易AI实践集合+其他) - (共187份)

    [推荐]2020,2021网易数字+大会(云原生&微服务+大数据&数据库+网易AI实践集合+其他) - (共187份) 下载地址:https://download.csdn.net/d ...

  5. 腾讯云数据库TDSQL:分布式数据库,你真的了解吗?

    分布式数据库进入人们的视野已经很久了.相对于传统的集中式数据库,分布式数据库在高性能.高可用.平滑拓展.高可靠.低成本等许多方面具有优势. 但时至今日,关于分布式数据库,似乎一直缺少足够权威和客观的解 ...

  6. Zabbix+分布式数据库TiDB实现分布式数据库监控

    Zabbix+分布式数据库TiDB实现分布式数据库监控 一.Tidb的简介 1.什么是TiDB 2.TiDB 整体架构 2.主要模块简介 1) TiDB Server 2) PD Server 3) ...

  7. 数据库架构设计——分布式数据库设计

    摘要 现在互联网应用已经普及,数据量不断增大.对淘宝.美团.百度等互联网业务来说,传统单实例数据库很难支撑其性能和存储的要求,所以分布式架构得到了很大发展.一定要认识到数据库技术正在经历一场较大的变革 ...

  8. java数据库中间件实现,分布式数据库中间件DDM的实现原理

    随着数据量不断增大,传统的架构模式难以解决业务量不断增长所带来的问题,特别是在业务成线性.甚至指数级上升的情况.此时我们不得不通过水平扩展,把数据库放到不同服务器上来解决问题,也就是我们说的数据库中间 ...

  9. 云原生演进趋势下传统数据库升级实践

    简介:在数字化背景下,我们有许多思考.数据库跟以前那有什么不一样呢?什么是所谓的云原生数据库呢?作为使用数据库的开发者,对数据库的需求有什么变化?如今使用数据库我们一般会提什么样的诉求?本文将一一为大 ...

最新文章

  1. Centos下安装mysql 总结
  2. R语言使用pwr包的pwr.chisq.test函数对卡方检验进行效用分析(power analysis)、在已知效应量(effect size)、显著性水平、效用值的情况下计算需要的样本量
  3. win7安装omnetpp-4.6
  4. 微信开发-ACCESS TOKEN 过期失效解决方案
  5. 网狐荣耀版通过水浒传基础二开埃及拉霸和水果森林步骤
  6. 缓存淘汰算法 (http://flychao88.iteye.com/blog/1977653)
  7. 数字签名与HTTPS详解
  8. Python脚本模拟登录网页之CSDN篇
  9. SpringBoot项目集成Mybatis Plus(五)条件构造器
  10. C++ - 构造和析构 2018-01-10
  11. android开源SlidingMenu使用
  12. Android--›键盘表情切换的终极解决方案(已重构)
  13. 《Python与硬件项目案例》— 基于Python与指纹模块AS608的指纹识别签到考勤系统(上篇)(期末大作业、课程设计、毕业设计、结课项目)
  14. Kubernetes证书类型和适用场景
  15. 能上QQ无法打开网页
  16. scala 定义空的list_Scala List(列表)
  17. [论文阅读]PointRend: Image Segmentation as Rendering
  18. Cocos Shader入门基础七:一文彻底读懂深度图。
  19. MySQL 的read_only 只读属性说明
  20. Effective C++ T23:宁以non-member、non-friend替换member函数

热门文章

  1. 云计算的优势和未来发展
  2. 勉强算是面经——3.中软国际
  3. Leetcode-元素和小于等于阈值的正方形的最大边长(python)
  4. uni-app使用iconfont
  5. 移动电源解锁亚马逊要做62133和60950测试报告你知道吗?
  6. 数模混合监控,视频如何联动报警、消防、门禁?
  7. php淋巴,揭秘淋巴排毒有多重要,您看了就知道
  8. ABC157 D - Friend Suggestions 题解
  9. Java后端校验框架oval与hibernatevalidator的使用
  10. CF1569B. Chess Tournament 简单思维