如何利用时间序列索引克服内存使用挑战
作者:社区 / 产品,用例,开发者
2019年9月17日
导航至
本文由Saiyam Pathak撰写,他是一位大规模多云Kubernetes项目的软件工程师,在沃尔玛实验室工作,专注于Kubernetes。
InfluxDB是一个领先的开源时间序列数据库。如果你不熟悉InfluxDB,它设计得很快,但使用内存索引,这会随着数据集的增长而消耗RAM。因此,为了最佳性能和RAM使用,InfluxData为InfluxDB引入了一种特殊的索引机制,称为时间序列索引(TSI)。TSI优化了大型数据集的RAM使用饱和度。
InfluxData支持使用InfluxDB的客户,他们的数据点达到数千万。然而,InfluxData的目标是将这一能力扩展到数亿甚至数十亿数据点。这就是为什么InfluxData添加了新的TSI。目的是支持大量时间序列(数据库存储的独特时间序列数量非常高)。基数是衡量你数据库中独特系列的一个度量。
时间序列索引(TSI)的背景
使用InfluxData的TSI存储引擎,用户可以拥有数百万个独特的时间序列。正如文档所述,目标是系列数量不应受服务器硬件内存数量的影响。重要的是,数据库中存在的系列数量也最好对数据库启动时间几乎没有影响。因此,TSI的开发代表了自2016年InfluxData发布时间序列合并树(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 监控、应用程序度量、物联网传感器数据和实时分析。
安装
> docker network create influxdb
> docker run -d –name=influxdb -p 8086:8086 -v $PWD:/var/lib/influxdb –net=influxdb –restart=always influxdb
Telegraf:Telegraf 是一个用 Go 语言编写的开源代理,用于收集其运行系统或其他服务上的指标和数据。Telegraf 将其收集的数据以正确格式写入 InfluxDB。
安装
将 telegraf.conf
文件导出以启用 docker 监控并更改 influx 终端。
> docker run --rm telegraf telegraf config > telegraf.conf
使用 InfluxDB 容器名称“influxdb”作为 URL 更新的主机来编辑 telegraf.conf
文件。为了启用 docker 监控,取消注释 docker 终端。
运行 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
Chronograf:Chronograf 是 InfluxData 的开源网络应用程序。使用 Chronograf 与 TICK Stack 的其他组件进行警报管理、数据可视化和数据库管理。
安装
> docker run -d --name=chronograf -p 8000:8888 --net=influxdb --restart=always chronograf --influxdb-url
现在我们已经运行了 TICK Stack,我们如何查看是否使用了 TSM 或 TSI?要检查 Influx 的索引版本是在内存中还是 TSI,我们可以简单地运行以下命令
> docker logs influxdb | grep index_version
如上图所示,“index_version=inmem” 显示 InfluxDB 未启用 TSI。
启用 TSI 索引的五个步骤
有一个 五个步骤 的程序来为 InfluxDB 容器启用 TSI 索引。
步骤 1: 停止容器
docker stop influxdb
docker rm influxdb
步骤 2: 再次启动容器,但以 bash 作为 entrypoint 并传递环境变量以启用 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
如果您只想转换一个数据库或一次转换一个数据库,也可以添加 -database
标志。
如您所见,所有分片都已索引,您还可以看到创建的索引文件夹。
find /var/lib/influxdb -type d -name index
<figcaption> 为数据库创建的索引文件夹</figcaption>
步骤 4: 退出并删除容器。
<figcaption> 删除容器</figcaption>
步骤 5: 不带 entrypoint 标志启动 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
<figcaption> TSI 检查</figcaption>
如上图所示,TSM 已成功更改为 TSI。
关于 TSI 的几个重要点
- 当前数据没有发生任何变化。
- 当一个分片正在索引时,会创建一个临时文件(
.index
)。如果由于任何原因此过程崩溃或失败,则会删除部分内容并重新尝试。完成后的索引将保持完好。如果在执行转换操作时虚拟机或容器崩溃,这有助于防止数据损坏。 - 可以使用
-database
标志转换特定数据库或逐个转换数据库。如果您不指定,则所有数据库都将被转换。 - 启动 InfluxDB 容器时,应传递
-e INFLUXDB_DATA_INDEX_VERSION="tsi1?"
。 - 或者,也可以通过 influxdb.conf 文件更改转换
docker run –rm influxdb influxd config > influxdb.conf
- 编辑
influxdb.conf
并将index-version = "inmem" > index-version = "tsi1"
- 使用此配置文件启动容器
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 领先走向超过十亿系列。