InfluxDB 存储引擎
InfluxDB存储引擎确保:
- 数据安全地写入磁盘
- 查询的数据完整且正确
- 数据是准确的(第一)和高效的(第二)
本文档概述了存储引擎的内部工作原理。此信息既作为参考,也帮助那些希望最大化性能的人。
存储引擎包括以下组件:
从API写入数据到磁盘
存储引擎处理从接收到API写入请求到将数据写入物理磁盘的整个过程。
数据是通过HTTP POST请求以行协议的形式写入到InfluxDB的/api/v2/write端点或/write 1.x 兼容端点。
一批点被发送到InfluxDB,压缩,并写入WAL以实现即时持久性。
点也被写入内存缓存,并立即可以查询。
内存缓存定期以TSM文件的形式写入磁盘。
随着TSM文件的累积,存储引擎将它们组合并压缩为更高层次的TSM文件。
虽然可以单独发送点,但出于效率考虑,大多数应用程序将点批量发送。
POST主体中的点可以来自任意数量的系列、测量和标签集。
批量中的点不必来自同一测量或标签集。
前写日志 (WAL)
写前日志Write Ahead Log (WAL) 在存储引擎重启时保留了InfluxDB数据。 WAL确保数据在意外故障时的持久性。
当存储引擎收到写请求时,以下步骤将发生:
- 写请求被附加到WAL文件的末尾。
- 数据被写入磁盘使用
fsync()。 - 内存缓存已更新。
- 当数据成功写入磁盘时,响应确认写请求成功。
fsync() 负责将文件的所有待处理写入操作推送到磁盘。作为一个系统调用,fsync() 具有昂贵的内核上下文切换,但可以保证数据在磁盘上的安全。
当存储引擎重新启动时,WAL文件会被读取回内存数据库。 InfluxDB 然后回答对 /read 端点的请求。
缓存
缓存是当前存储在WAL中的数据点的内存副本。WAL和缓存是独立的实体,彼此之间没有交互。存储引擎协调对两者的写入。
缓存:
- 按键(测量、标签集和唯一字段)组织点。每个字段存储在其自己的时间顺序范围内。
- 存储未压缩的数据。
- 每次存储引擎重启时从WAL获取更新。运行时查询缓存,并与存储在TSM文件中的数据合并。
- 使用最多
maxSize字节的内存。
缓存快照是当前正在写入TSM文件的缓存对象。 它们在刷新期间保留在内存中,以便可以与缓存一起查询。 对存储引擎的查询将缓存中的数据与TSM文件中的数据合并。 查询在查询处理时从缓存中制作的数据副本上执行。 这样,在查询运行时发生的写入不会影响结果。 发送到缓存的删除操作会清除指定键或指定键的时间范围。
时间结构合并树 (TSM)
为了有效地压缩和存储数据,存储引擎通过系列键对字段值进行分组,然后按照时间对这些字段值进行排序。 (一个 系列键 是由度量、标签键和值以及字段键定义的。)
存储引擎使用时间结构合并树(TSM)数据格式。 TSM文件以列式格式存储压缩序列数据。 为了提高效率,存储引擎仅存储序列中值之间的差异(或增量)。 列式存储允许引擎按序列键读取并省略多余数据。
在字段安全存储在TSM文件后,WAL被截断,缓存被清除。 压缩过程创建了面向读取的TSM文件。TSM压缩代码相当复杂。 然而,高层目标相当简单: 将一系列的值组织在一起形成长序列,以最佳优化压缩和扫描查询。
有关TSM引擎的更多信息,请观看下面的视频:
时间序列索引 (TSI)
随着数据基数(系列的数量)的增加,查询读取更多的系列键并变得更慢。 时间序列索引 确保查询在数据基数增加时仍然保持快速。 TSI 按照测量、标签和字段对系列键进行分组存储。 这使得数据库能够很好地回答两个问题:
- 存在哪些测量、标签、字段? (这发生在元查询中。)
- 给定一个测量、标签和字段,存在哪些系列键?