• 84874

    文章

  • 744

    评论

  • 18

    友链

  • 最近新加了换肤功能,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

时序数据库 Apache-IoTDB 源码解析之文件格式简介(三)

撸了今年阿里、腾讯和美团的面试,我有一个重要发现.......>>

上一章聊到在车联网或物联网中对数据库的需求,以及 IoTDB 的整体架构,详情请见:

时序数据库 Apache-IoTDB 源码解析之系统架构(二)

打一波广告,欢迎大家访问IoTDB 仓库,求一波 Star 。欢迎关注头条号:列炮缓开局,欢迎关注 OSCHINA博客

这一章主要想聊一聊:

  1. 行式存储、列式存储的区别
  2. TsFile 的格式

行式与列式存储的区别

假如我们的逻辑上的数据表格式及数据为:

时间戳 人名 体温
1580950800 张三 36.5
1580950800 李四 36.9
1580950800 王五 36.7

那么他出现在硬盘格式就是:

硬盘行列存储差异图

行式数据

在我理解上,行式数据是把逻辑相关的数据在硬盘上放到一起,比如上面的例子,我们可以称之为体温表,所以在逻辑上:时间、人、体温,就成为了逻辑上紧密相关的数据。

所以把相关的数据的硬盘上的组织方式也变成连续的,假如我需要取 张三 的数据,那么当你读出 R1 文件块的时候,就是读出了所有 张三 相关的数据。

列式数据

列式数据在我理解是将物理相关的数据放到一起,比如时间是一类(long 类型)、名字是一类(string 类型)、体温是一类(float 类型)。当然这种硬盘的组织方式,相比起行式数据库,在取拼回体温表的结构的时候,速度就慢了很多,因为你要分别取 C1、C2、C3 文件块,然后还要写个容器往里 Set()。那么列式数据存储方式相比于行式存储优势在哪里呢?

1.1 取数据方式

有一种叫法是只读投影列,避免查询无关列的读取。列式存储的优势在于查询的列数远小于总属性数量,就能少读很多数据。可能读起来非常绕口,举个例子:比如我需要查体温大于 36 度的体温值,sql : select 体温 FROM table WHERE 体温 > 36 。这时候如果是列式存储只需要读出 C3 数据块就可以一次性查到所有数据。而行式数据库中,则需要读出 R1、 R2、 R3。在第二章中介绍到物联网中的时序数据的特点:存量数据非常大,如果遍历几百亿数据,时间差距明显就拉开了。

1.2 数据编码和压缩

因为物理相关的数据他们类型相同,可以使用多种多样的编码方式,比如 IoTDB 中就提供了 8 种编码方式,这个不具体聊,等后面章节再说。

我们继续拿时间列举例子,我们可以把时间列改造为差值存储: 比如 C1 文件块中先存储基础值 1580950800 那么他后面的数据值只需要存储 0 就可以,存储的数字小了,那么占用的存储空间肯定也就小了,当数字特别大且差值比较小的时候,这用编码方式就非常有意义。当然还有很多好玩儿的编码方式,欢迎持续关注。

TsFile 文件格式

为什么叫 TsFile ?我听意思应该是作为 TimeSeriresFile 的缩写,也就是时序数据文件的意思。那么接下来请看图: TsFile文件结构

看起来比较乱,但想一次解释明白不太可能,所以我写了一个意义对照表,希望能够介绍明白一个大体意思。解释从下到上翻译,这也是 IoTDB 中读取文件的方式:

  1. Magic :这里其实是一个有意义String,它代表了 6个字节的 TsFile + 6个字节的文件版本信息
  2. TsFileMetaData : 这里存储的是文件内的 1 级索引信息,大致描述列包含哪些逻辑表,表内数据的开始和结束时间(时间序列),在表的 2 级索引所在的文件位置,使用什么压缩、编码方式等等。
  3. TsDeviceMetaData: 2 级索引,存储的是逻辑表(IoTDB 中称为 device) 中包含了多少 Chunk ,每个Chunk的开始结束时间、在文件中的开始位置,以及数据的类型。
  4. ChunkGroup Footer: 主要是一种校验信息,能够在后续读取时完成区块内的自检。主要存储的是包含了多少 Chunk 以及数据大小。
  5. Chunk Header: 主要存储的是 chunk 内的数据类型,压缩、编码方式。
  6. Marker:1 个 byte 分隔符,没啥用就是分隔作用。
  7. Chunk Data:Chunk 中包含了多个 page ,page中包含了一个时间序列、一个值序列,也就是实际的数据,见下图:

chunk数据格式

到这里,基本介绍完了 TsFile 的存储格式:里面有地方记录编码和压缩格式,用来完成不同的编码压缩功能;有不同的 ChunkGroup 用来存储一类数据,如:姓名、体温。

回想上面提到的 SQL : select 体温 FROM table WHERE 体温 > 36 , 在 TsFile 中,只要通过 1 级索引到 2 级索引的筛选,找到第一个 Chunk Header 位置,然后开始遍历就完成了。

有兴趣的朋友可以查看:官方 Github 中的 TsFile 文档,了解更多详细信息。接下来会用几章来解析 IoTDB 项目中是如何实现 TsFile 模块,都定义了哪些接口等,欢迎持续关注。。。


695856371Web网页设计师②群 | 喜欢本站的朋友可以收藏本站,或者加入我们大家一起来交流技术!

欢迎来到梁钟霖个人博客网站。本个人博客网站提供最新的站长新闻,各种互联网资讯。 还提供个人博客模板,最新最全的java教程,java面试题。在此我将尽我最大所能将此个人博客网站做的最好! 谢谢大家,愿大家一起进步!

转载原创文章请注明出处,转载至: 梁钟霖个人博客www.liangzl.com

1条评论

Loading...
  • 刘涛华908L

    您好,您的转载速度也有些太快了,我刚发布就同步到这里, 能不能在原文上加个转载 ??



发表评论

电子邮件地址不会被公开。 必填项已用*标注

自定义皮肤
注册梁钟霖个人博客