如何使用时间序列索引克服内存使用挑战

导航至

本文由大型多云 Kubernetes 项目的软件工程师 Saiyam Pathak 撰写,他在 Walmart Labs 从事 Kubernetes 工作。

InfluxDB 是领先的开源 时间序列数据库。如果您不熟悉 InfluxDB,它被设计为速度快,但它使用内存索引,这会随着数据集的增长而增加 RAM 使用量。因此,为了获得最佳性能和 RAM 使用率,InfluxData 为 InfluxDB 引入了一种特殊的索引机制,称为 时间序列索引 (TSI)。TSI 优化了大型数据集的 RAM 使用率饱和问题。

InfluxData 支持客户使用 InfluxDB 处理数千万个时间序列数据点。然而,InfluxData 的目标是将此能力扩展到数亿,最终达到数十亿个数据点。这就是 InfluxData 添加新 TSI 的原因。目的是支持大量时间序列(数据库存储的唯一时间序列数量非常多)。基数是衡量数据库中唯一序列数量的指标。

上下文中的时间序列索引 (TSI)

借助 InfluxData 的 TSI 存储引擎,用户能够拥有数百万个唯一的时间序列。正如 文档 所述,目标是序列的数量不应受到服务器硬件内存量的影响。重要的是,数据库中存在的序列数量也应理想地对数据库启动时间产生可忽略不计的影响。因此,TSI 的开发代表了自 InfluxData 在 2016 年发布时间序列合并树 (TSM) 存储引擎以来,数据库领域最重大的技术进步。

如前所述,当 InfluxDB 摄取数据时,它不仅存储值,还索引测量和标签信息,以便可以快速查询。在早期版本中,索引数据只能存储在内存中——同样,这需要大量 RAM,并限制了机器可以容纳的序列数量上限。开发 TSI 的目的是为了使其超过该上限。TSI 将索引数据存储在磁盘上,因此我们不再受 RAM 的限制。TSI 使用操作系统的页面缓存将热数据拉入内存,让冷数据保留在磁盘上。

在本文中,我们重点介绍将 TSM 存储引擎的内存索引转换为时间序列索引 (TSI) 索引。这种转换提高了性能并减少了内存问题。我们还将提供一些技巧来减少 InfluxDB 的内存过载。本文使用容器。

让我们首先讨论 InfluxData 开源平台的默认安装,即 TICK Stack (平台组件 Telegraf、InfluxDB、Chronograf 和 Kapacitor 的首字母缩写)。

先决条件

  • 安装了 Docker 的虚拟机: 如果您之前没有安装过 Docker,可以使用官方 Docker 文档 进行安装。
  • TICK Stack 安装: 在我们解释从 TSM 到 TSI 索引的转换之前,我们首先需要安装 TICK Stack。TICK Stack 是 InfluxData 的开源平台,由 Telegraf、InfluxDB、Chronograf 和 Kapacitor 组成。

平台组件定义和安装

InfluxDB: InfluxDB 是一个从头开始构建的时间序列数据库,用于处理高写入和查询负载。InfluxDB 旨在用作任何涉及大量时间戳数据的用例的后备存储,包括 DevOps 监控、应用程序指标、IoT 传感器数据和实时分析。

安装

> docker network create influxdb

InfluxDB - 从 TSM 到 TSI 的转换 - docker 网络创建<figcaption> Docker 网络创建</figcaption>

> docker run -d –name=influxdb -p 8086:8086 -v $PWD:/var/lib/influxdb –net=influxdb –restart=always influxdb

InfluxDB TSM 到 TSI 的转换 - InfluxDB 正在运行<figcaption> InfluxDB 正在运行</figcaption>

Telegraf: Telegraf 是一个用 Go 编写的开源代理,用于收集在其运行的系统上或来自其他服务的指标和数据。Telegraf 以正确的格式将收集到的数据写入 InfluxDB。

安装

转储 telegraf.conf 文件以启用 docker 监控并更改 influx 端点。

> docker run --rm telegraf telegraf config > telegraf.conf

使用 InfluxDB 容器名称“influxdb”作为 URL 更新的主机来编辑 telegraf.conf 文件。为了启用 docker 监控,请取消注释 docker 端点。

InfluxDB url 更新<figcaption> InfluxDB url 更新</figcaption>

 

InfluxDB - 取消注释端点<figcaption> 取消注释端点</figcaption>

运行 Telegraf 容器

> docker run -d --name=telegraf --net=influxdb -v /var/run/docker.sock:/var/run/docker.sock -v $PWD/telegraf.conf:/etc/telegraf/telegraf.conf:ro telegraf

Telegraf 容器 - Telegraf 正在运行<figcaption> Telegraf 正在运行</figcaption>

Chronograf: Chronograf 是 InfluxData 的开源 Web 应用程序。将 Chronograf 与 TICK Stack 的其他组件一起使用,以进行警报管理、数据可视化和数据库管理。

安装

> docker run -d --name=chronograf -p 8000:8888 --net=influxdb --restart=always chronograf --influxdb-url

Chronograf 安装<figcaption> Chronograf 正在运行</figcaption>

现在我们已经运行了 TICK Stack,我们如何查看是否正在使用 TSM 或 TSI?要检查 Influx 的索引版本是内存中还是 TSI,我们可以简单地运行以下命令

TICK Stack 正在运行<figcaption> TICK Stack 正在运行</figcaption>

> docker logs influxdb | grep index_version

Index version - inmem

如上所示,“index_version=inmem”表明 InfluxDB 未启用 TSI。

启用 TSI 索引的五个步骤

有一个五步程序来为 InfluxDB 容器启用 TSI 索引。

步骤 1: 停止容器

docker stop influxdb
docker rm influxdb

移除容器<figcaption> 移除容器</figcaption>

步骤 2: 再次启动容器,但入口点为 bash,并传递环境变量以启用 TSI 索引版本。

> sudo docker run -it --name influx-db --restart unless-stopped \
-e INFLUXDB_DATA_INDEX_VERSION="tsi1" \
-v $PWD:/var/lib/influxdb \
--entrypoint=bash -it \
-p 8086:8086 -p 8083:8083 \
influxdb

步骤 3: 运行从 TSM 到 TSI 的转换。

> influx_inspect buildtsi -datadir=/var/lib/influxdb/data -waldir=/var/lib/influxdb/wal

InfluxDB - 运行从 TSM 到 TSI 的转换<figcaption> TSM 到 TSI</figcaption>

如果您只想转换一个数据库或一次转换一个数据库,您还可以添加 -database 标志。

如您所见,所有分片都已编入索引,您还可以看到创建的索引文件夹

find /var/lib/influxdb -type d -name index

索引文件夹已创建<figcaption> 为两个数据库创建的索引文件夹</figcaption>

步骤 4: 退出并移除容器。

移除容器<figcaption> 移除容器</figcaption>

步骤 5: 启动不带入口点标志的 InfluxDB 容器。

sudo docker run -itd --name influx-db --restart unless-stopped \
-e INFLUXDB_DATA_INDEX_VERSION="tsi1" \
-v $PWD:/var/lib/influxdb \
-p 8086:8086 -p 8083:8083 \
influxdb

InfluxDB - TSI 检查<figcaption> TSI 检查</figcaption>

如您在上面看到的,TSM 已成功更改为 TSI。

关于 TSI 的几个要点

  • 当前数据没有变化。
  • 在索引分片时,会创建一个临时文件 (.index)。如果由于任何原因此过程崩溃或失败,则会移除部分索引并再次尝试。已完成的索引保持不变。这有助于防止 VM 或容器在执行转换操作时崩溃,从而防止数据损坏。
  • -database 标志可用于转换特定数据库或一次转换一个数据库。如果您未指定,则会转换所有数据库。
  • -e INFLUXDB_DATA_INDEX_VERSION="tsi1? 应在启动 InfluxDB 容器时传递。
  • 或者,也可以使用 influxdb.conf 文件更改转换
    • docker run –rm influxdb influxd config > influxdb.conf
    • 编辑 influxdb.conf 并更改 index-version = "inmem" > index-version = "tsi1"
    • 使用此 conf 文件启动容器
docker run -p 8086:8086 \
      -v $PWD/influxdb.conf:/etc/influxdb/influxdb.conf:ro \
      influxdb -config /etc/influxdb/influxdb.conf
  • 索引仍然随着序列数量的增加而增长,但内存不需要随着这些索引线性增长。这就是 TSI 的作用。
  • 预期的一般行为是 InfluxDB 将使用尽可能多的内存来维护内存索引,并回退到磁盘以处理其他任何内容。
  • 在没有 TSI 的情况下,每个数据库只有一个索引,它会消耗所有存在的内存,并且无法执行任何其他操作。现在,在 TSI 之后,当达到内存限制时,InfluxDB 开始引用这些索引。此外,它会将 WAL 加载到内存中,并根据需要分页索引。

如果您在 TSM 到 TSI 的转换方面遇到任何问题或有任何疑问,请前往 InfluxDB 的 Slack 频道 并开始讨论。TSI 正在开辟新天地,并帮助 InfluxDB 引领走向超过十亿个序列的道路。