时间序列索引 (TSI) 详细信息
当 InfluxDB 摄取数据时,我们不仅存储值,还索引测量和标签信息,以便能够快速查询。 在早期版本中,索引数据只能存储在内存中,但是,这需要大量的 RAM,并对机器可以容纳的系列数量设定了上限。 这个上限通常在 1 - 4 百万系列之间,具体取决于使用的机器。
时间序列索引(TSI)用于让我们超越上限。 TSI 将索引数据存储在磁盘上,以便我们不再受限于 RAM。 TSI 利用操作系统的页面缓存将热数据拉入内存,并让冷数据保留在磁盘上。
启用TSI
要启用TSI,请在InfluxDB配置文件(influxdb.conf)中设置以下行:
index-version = "tsi1"
(确保包含双引号。)
InfluxDB 企业版
要将您的数据节点转换为支持TSI,请参见 升级InfluxDB企业集群。
有关配置的详细信息,请参见 配置 InfluxDB 企业集群。
工具
influx_inspect dumptsi
如果您正在排查索引的问题,可以使用 influx_inspect dumptsi 命令。
这个命令允许您打印有关索引、文件或一组文件的汇总统计信息。
这个命令一次只能处理一个索引。
有关此命令的详细信息,请参见 influx_inspect dumptsi。
influx_inspect buildtsi
如果您想将现有的分片从内存索引转换为TSI索引,或者如果您有一个已经损坏的现有TSI索引,您可以使用 buildtsi 命令从底层TSM数据创建索引。 如果您有一个想要重建的现有TSI索引,请首先删除分片内的 index 目录。
此命令在服务器级别工作,但您可以选择添加数据库、保留策略和分片过滤器,以仅应用于部分分片。
有关此命令的详细信息,请参见 influx inspect buildtsi。
理解TSI
文件组织
TSI (时间序列索引) 是一个基于日志结构合并树的数据库,用于 InfluxDB 系列数据。 TSI 由几个部分组成:
索引: 包含单个分片的整个索引数据集。
分区: 包含分片的数据的分片分区。
日志文件: 包含新写入的系列作为内存中的索引,并作为WAL持久化。
IndexFile:包含一个不可变的、内存映射的索引,该索引是从一个 LogFile 构建的或是从两个连续的索引文件合并而成。
还有一个 SeriesFile,它包含整个数据库中所有系列键的集合。数据库中的每个分片共享同一个系列文件。
写入
当写入操作进入系统时,会发生以下情况:
- 系列被添加到系列文件中,或者如果已经存在,则被查找。这将返回一个自动递增的系列ID。
- 该系列被发送到索引。索引维护一个现有系列ID的嘶吼位图,并忽略已经创建的系列。
- 该系列被哈希并发送到适当的分区。
- 分区将系列作为条目写入日志文件。
- LogFile将系列写入磁盘上的预写日志文件,并将系列添加到一组内存索引中。
压缩
一旦日志文件超过阈值(5MB),则会创建一个新的活动日志文件,之前的文件开始压缩成索引文件。 第一个索引文件位于级别1(L1)。 日志文件被视为级别0(L0)。
索引文件还可以通过将两个较小的索引文件合并在一起来创建。 如果存在两个连续的 L1 索引文件,则可以将它们合并为一个 L2 索引文件。
读取
该索引提供多个API调用用于检索数据集,例如:
MeasurementIterator(): 返回一个排序的测量名称列表。TagKeyIterator(): 返回测量中标签键的排序列表。TagValueIterator(): 返回一个按标签键排序的标签值列表。MeasurementSeriesIDIterator(): 返回测量的所有系列ID的排序列表。TagKeySeriesIDIterator(): 返回标签键的所有系列ID的排序列表。TagValueSeriesIDIterator(): 返回一个包含标签值的所有系列ID的排序列表。
这些迭代器可以使用几个合并迭代器进行组合。对于每种类型的迭代器(测量、标签键、标签值、系列ID),有多种合并迭代器类型:
- 合并: 从两个迭代器中去重项目。
- 交集: 仅返回在两个迭代器中存在的项目。
- 差异: 仅返回第一个迭代器中不存在于第二个迭代器中的项。
例如,具有region != 'us-west'的WHERE子句的查询在两个分片上操作时,将构造出一组迭代器,如下所示:
DifferenceSeriesIDIterators(
MergeSeriesIDIterators(
Shard1.MeasurementSeriesIDIterator("m"),
Shard2.MeasurementSeriesIDIterator("m"),
),
MergeSeriesIDIterators(
Shard1.TagValueSeriesIDIterator("m", "region", "us-west"),
Shard2.TagValueSeriesIDIterator("m", "region", "us-west"),
),
)
日志文件结构
日志文件简单地结构为按顺序写入磁盘的LogEntry对象列表。日志文件写入直到达到5MB,然后它们被压缩成索引文件。日志中的条目对象可以是以下任何类型:
- 添加系列
- 删除系列
- 删除测量
- 删除标签键
- 删除标签值
内存中的索引在日志文件上跟踪以下内容:
- 按名称测量
- 通过测量标记键
- 通过标签键标记值
- 按测量分类
- 按标签值系列
- 系列、测量、标签键和标签值的墓碑。
日志文件还维护了系列ID存在和墓碑的位集。这些位集在启动时与其他日志文件和索引文件合并,以重新生成完整的索引位集。
索引文件结构
索引文件是一个不可变的文件,它跟日志文件跟踪类似的信息,但所有数据都是被索引并写入磁盘,以便可以直接从内存映射中访问。
索引文件包含以下部分:
- TagBlocks: 为单个标签键维护标签值的索引。
- MeasurementBlock: 维护测量值及其标签键的索引。
- 尾部: 存储文件的偏移信息以及用于基数估计的HyperLogLog草图。
清单
MANIFEST 文件存储在索引目录中,列出了属于索引的所有文件及其应被访问的顺序。每次发生压缩时,该文件都会更新。任何在目录中但不在索引文件中的文件是正在被压缩的索引文件。
文件集
文件集是一个内存快照,在InfluxDB进程运行时获得的清单。 这是为了提供在某一时刻对索引的一致视图。 文件集还便于对其所有文件进行引用计数,以便在所有读取该文件的操作完成之前,不会通过压缩删除任何文件。