Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: 删除没被识别出来的markdown格式TODO

...

  • 大端存储

    • 比如: int0x8 将会被存储为 00 00 00 08, 而不是 08 00 00 00

  • 可变长的字符串类型

    • 存储的方式是以一个 int 类型的 Size + 字符串组成。Size 的值可以为 0。

    • Size 指的是字符串所占的字节数,它并不一定等于字符串的长度。

    • 举例来说,"sensor_1" 这个字符串将被存储为 00 00 00 08 + "sensor_1" (ASCII编码)。

    • 另外需要注意的一点是文件签名 "TsFile000001" (Magic String + Version), 因为他的 Size(12) 和 ASCII 编码值是固定的,所以没有必要在这个字符串前的写入 Size 值。

  • 数据类型

    • 0: BOOLEAN

    • 1: INT32 (int)

    • 2: INT64 (long)

    • 3: FLOAT

    • 4: DOUBLE

    • 5: TEXT (String)

  • 编码类型

    • 0: PLAIN

    • 1: DICTIONARY

    • 2: RLE

    • 3: DIFF

    • 4: TS_2DIFF

    • 5: BITMAP

    • 6: GORILLA_V1

    • 7: REGULAR

    • 8: GORILLA

  • 压缩类型

    • 0: UNCOMPRESSED

    • 1: SNAPPY

    • 2: GZIP

    • 3: LZO

    • 4: SDT

    • 5: PAA

    • 6: PLA

    • 7: LZ4

1.2 TsFile 概述

<!-- TODO

下图是关于TsFile的结构图。

Image Removed

此文件包括两个设备 d1、d2,每个设备包含两个测点 s1、s2,共 4 个时间序列。每个时间序列包含两个 Chunk。

-->

TsFile 整体分为两大部分:数据区索引区

数据区所包含的概念由小到大有如下三个:

...

一个 Chunk 存储了一个物理量(Measurement) 一段时间的数据,Chunk 内数据是按时间递增序存储的。Chunk 是由一个字节的分隔符 0x01, 一个 ChunkHeader 和若干个 Page 构成。

ChunkHeader 数据块头
成员类型解释
measurementIDString传感器名称
dataSizeintchunk 大小
dataTypeTSDataTypechunk的数据类型
compressionTypeCompressionType压缩类型
encodingTypeTSEncoding编码类型
numOfPagesint包含的page数量
Page 数据页

一个 Page 页存储了一段时间序列,是数据块被反序列化的最小单元。 它包含一个 PageHeader 和实际的数据(time-value 编码的键值对)。

PageHeader 结构:

成员类型解释
uncompressedSizeint压缩前数据大小
compressedSizeintSNAPPY压缩后数据大小
statisticsStatistics统计量

这里是statistics的详细信息:

成员描述DoubleStatisticsFloatStatisticsIntegerStatisticsLongStatisticsBinaryStatisticsBooleanStatistics
count数据点个数longlonglonglonglonglong
startTime开始时间longlonglonglonglonglong
endTime结束时间longlonglonglonglonglong
minValue最小值doublefloatintlong--
maxValue最大值doublefloatintlong--
firstValue第一个值doublefloatintlongBinaryboolean
lastValue最后一个值doublefloatintlongBinaryboolean
sumValuedoubledoubledoubledouble--
extreme极值doublefloatintlong--
ChunkGroupFooter 数据块组结尾
成员类型解释
entityIDString实体名称
dataSizelongChunkGroup 大小
numberOfChunksint包含的 chunks 的数量

1.2.3 索引区

1.2.3.1 ChunkIndex 数据块索引

第一部分的索引是 ChunkIndex

成员类型解释
measurementUidString传感器名称
offsetOfChunkHeaderlong文件中 ChunkHeader 开始的偏移量
tsDataTypeTSDataType数据类型
statisticsStatistics统计量
1.2.3.2 TimeseriesIndex 时间序列索引

第二部分的索引是 TimeseriesIndex

成员类型解释
measurementUidString物理量名称
tsDataTypeTSDataType数据类型
startOffsetOfChunkIndexListlong文件中 ChunkIndex 列表开始的偏移量
ChunkIndexListDataSizeintChunkIndex 列表的大小
statisticsStatistics统计量
1.2.3.3 IndexOfTimeseriesIndex 时间序列索引的索引(二级索引)

第三部分的索引是 IndexOfTimeseriesIndex

成员类型解释
IndexTreeIndexNode索引节点
offsetOfIndexArealong索引区的偏移量
bloomFilterBloomFilter布隆过滤器

索引节点 (IndexNode) 的成员和类型具体如下:

成员类型解释
childrenList<IndexEntry>节点索引项列表
endOffsetlong此索引节点的结束偏移量
nodeTypeIndexNodeType节点类型

索引项 (MetadataIndexEntry) 的成员和类型具体如下:

成员类型解释
nameString对应实体或物理量的名字
offsetlong偏移量

所有的索引节点构成一棵类B+树结构的索引树(二级索引),这棵树由两部分组成:实体索引部分和物理量索引部分。索引节点类型有四种,分别是INTERNAL_ENTITYLEAF_ENTITYINTERNAL_MEASUREMENTLEAF_MEASUREMENT,分别对应实体索引部分的中间节点和叶子节点,和物理量索引部分的中间节点和叶子节点。 只有物理量索引部分的叶子节点(LEAF_MEASUREMENT) 指向 TimeseriesIndex

...

  • 例6:1个实体,30个物理量,2个多元时间序列组,每个多元时间序列组分别有15个物理量

  • 例7:2个实体,每个实体的物理量如下表所示

d0d1
【一元时间序列】s0,s1...,s4【一元时间序列】s0,s1,...s14
【多元时间序列】v0.(s5,s6,...,s14)【多元时间序列】v0.(s15,s16,..s18)
【一元时间序列】z15,z16,..,z18

索引采用树形结构进行设计的目的是在实体数或者物理量数量过大时,可以不用一次读取所有的 TimeseriesIndex,只需要根据所读取的物理量定位对应的节点,从而减少 I/O,加快查询速度。有关 TsFile 的读流程将在本章最后一节加以详细说明。

...