百万级写入 vs 低成本存储,时序数据库 TDengine 如何扛住 AIOps?

本篇文章详细讲述了七云团队在运维平台中如何利用 TDengine 解决海量时序数据存储与查询的实际业务需求。内容涵盖了从数据库选型、方案落地到业务挑战及解决办法的完整过程,特别是分享了升级 TDengine 3.x 时的实战经验,给到有需要的小伙伴参考阅读。

此前,我带领的团队负责过一个 AIOps 项目,核心任务是存储和查询大量时序数据,包括各种系统和性能指标。经过深入调研,我们最终选择了 TDengine 作为指标数据的存储引擎。目前,相关业务已稳定运行数年。本文将重点分享我们如何利用 TDengine 实现业务落地,以及过程中遇到的挑战与解决方案。

项目介绍

在展开分享之前,我先简单介绍一下指标采集业务和 TDengine,以便帮助大家更好地理解背景和技术选型。

1. 指标采集业务

在运维平台中,核心的三大基础功能包括:采集、监控和告警。采集是首要环节,需要通过多种方式将服务器、应用等关键指标数据汇集到平台中,随后实现监控图表展示、告警策略触发等一系列运维操作。

百万级写入 vs 低成本存储,时序数据库 TDengine 如何扛住 AIOps? - TDengine Database 时序数据库

2. TDengine

TDengine 是一款开源、高性能、云原生的时序数据库。它针对物联网、车联网、工业互联网、金融和 IT 运维等场景进行了专门优化设计,同时集成了缓存、流式计算、数据订阅等系统功能。这些特性不仅显著降低了系统设计的复杂度,还有效减少了研发和运维成本,是一个极简高效的时序数据处理平台。

为什么选择 TDengine

由于采集业务的点位众多且频率较高,数据存储需要处理高并发的写入(TPS)和监控、告警等场景下较高的查询并发(QPS)。因此,选择一个高性能、时序化、且易于横向扩展的数据存储引擎是必然的需求。

在调研了常见的时序数据库解决方案(如 InfluxDB、TimescaleDB、OpenTSDB 和 TDengine)后,我们最终选择了 TDengine,主要基于以下几点考虑:

1. 设计理念契合

TDengine 的设计高度贴合我们的数据采集需求:每个设备对应一张超级表,每个指标对应一张子表。这种设计极大简化了数据存储和管理的复杂度,让我们能够更高效地组织和处理数据。

2. 卓越的性能表现

在性能方面,TDengine 明显优于其他主流时序数据库。我们参考了官方文档中基于 TSBS 标准数据集的测试报告,数据显示 TDengine 在写入和查询性能上都具有显著优势。

报告链接:https://www.taosdata.com/performance-comparison-influxdb-and-timescaledb-vs-tdengine

3. 强大的分布式架构

TDengine 从设计之初便以分布式高可靠架构为核心,具备天然的横向扩展能力。正如官方文档所述:

TDengine 的设计是基于单个硬件、软件系统不可靠,基于任何单台计算机都无法提供足够计算能力和存储能力处理海量数据的假设进行设计的。因此 TDengine 从研发的第一天起,就按照分布式高可靠架构进行设计,是支持水平扩展的,这样任何单台或多台服务器发生硬件故障或软件错误都不影响系统的可用性和可靠性。同时,通过节点虚拟化并辅以负载均衡技术,TDengine 能最高效率地利用异构集群中的计算和存储资源降低硬件投资。

业务落地方案

1. 库设计

我们采用以用户为单位进行库的拆分,每个用户对应一个独立的数据库。在创建库时,建议对相关参数进行手动指定,确保对每个配置项的含义和用途有明确的了解。使用默认配置可能在未来使用中因缺乏规划而引发问题。

如果库中的表数量非常多,建议适当增加 vgroup 参数的值(默认仅为 2)。合理规划 vgroup 的数量,可以有效提高系统性能并降低后续扩展和维护的复杂性。

2. 表设计

我们的设计方案是一个设备创建一张超级表,一个指标创建一张子表。

3. 集群方案

根据不同业务体量我们划分了不同的集群设施,我以其中一个集群的要求举例说明:

  •   写入TPS大约在3w/s
  •   查询QPS大约在1k/s
  •   单条指标数据的大小约为0.5KB
  •   库中存储的数据保留1年

在容量规划上,我们主要参考了官方提供的规划方案——https://docs.taosdata.com/operation/planning/

做了下面的规划内容:

  • 内存规划

官方推荐的计算公式:vgroups × replica × (buffer + pages × pagesize + cachesize) 参数对号入座,10 * 1 * (32MB + 256MB * 4KB + 1MB) = 340MB 还需要再加上 OS 自身的一些内存消耗,并且冗余一定的 buffer 空间。我们最终每台节点分配了 8GB 内存。

  • CPU 规划

我们来大概计算一下数据分片 & 数据写入所需要的 CPU 资源:3w/s ÷ 单核1w/s = 3,即只考虑写入请求次数(每次写入只写1条数据,无批量写入)只需要 3 个 CPU 核心即可。再给几个用来满足查询需求的计算资源冗余,并且保持 CPU 使用率不超过 50%,我们最终每台节点分配了 8 个 CPU 核心。

  • 磁盘规划

在不考虑 TDengine 对落盘数据进行压缩的情况下,那么每秒的写入速率是 30000/s * 0.5KB = 15000KB/s,约等于 14.65MB/s,这个数量级的磁盘 IO,哪怕是机械硬盘也很容易满足性能要求,所以只需要保证磁盘总量足够即可。我们最终每台节点先给了 500GB 的数据盘,随着数据的增长还在扩容。

  • 网络带宽规划

由于业务与服务器均部署在同一内网环境中,数据传输可以直接使用内网带宽。根据上述写入速率计算,集群间的流量需求完全可以由常见的千兆网卡轻松满足,无需额外升级网络配置。

  • 节点数量规划

我们根据多个 vgroup 的资源需求,对总资源进行了均衡分配,同时在生产环境中预留了充分的冗余。最终选用了 3 台配置为 8 核 CPU / 8 GB 内存 / 500 GB 存储 的服务器,确保系统的高可用性和稳定性。

自制小工具:TD-GUI

基于 TDengine 提供的 REST-API,我开发了一款便捷的查询小工具,专为业务需求设计。同事们在实际工作中广泛使用这一工具,大大提升了工作效率,并获得了普遍好评。其实现原理非常简单:通过拼接 SQL 请求,利用 REST-API 向 TDengine 发送查询请求并解析响应结果。虽然工具设计轻量,但在实际应用中展现了强大的实用性。

百万级写入 vs 低成本存储,时序数据库 TDengine 如何扛住 AIOps? - TDengine Database 时序数据库

遇到的挑战&解决办法

  1. 老版本集群 2.x 存在库、表信息异常的现象

在使用 TDengine 2.x 集群时,我们偶尔会遇到库和表信息异常的现象。经过反馈至开源社区,问题可能源于元数据管理的 Bug。短期解决方案是重启 TDengine 恢复正常运行,长期是通过升级到 3.x 版本彻底解决了问题,目前已不再复现。

  1. 老版本集群 2.x 迁移至新版本 3.x

由于 2.x 和 3.x 版本之间存在不兼容情况,迁移需要将 2.x 数据导出后重新导入至 3.x 集群。然而,面对 2.x 的海量数据,导出速度和数量难以接受,同时还需保证生产系统正常运行。我们采用了数据双写策略:新上报的数据同时写入 2.x 和 3.x 两套集群,并通过后台程序逐步将 2.x 的历史数据读取并写入到 3.x 集群,最终实现了数据的平滑迁移。

百万级写入 vs 低成本存储,时序数据库 TDengine 如何扛住 AIOps? - TDengine Database 时序数据库

在双写过程中,我们开发了一个后台程序,从 2.x 集群中逐步读取历史数据,并慢慢写入到 3.x 集群,实现了对 2.x 的平滑替换。最终,顺利完成了版本迁移。这种方法不仅保证了生产系统的正常运行,还有效规避了 2.x 和 3.x 数据格式不兼容的问题。升级到 3.x 后,我们还遇到了一些小问题,简单总结如下:

  1. 老代码与新版本兼容性问题迁移过程中,部分代码需要调整。例如,由于 value 成为保留关键字,如果字段名为 value,则在 SQL 中需要使用反引号进行引用。不过,这类问题对整体迁移影响不大。
  2. 新版本配置项变动问题虽然 3.x 的大部分配置项与 2.x 基本相同或相似,但仍存在一些细微差异。经过适当调整后,对业务运行未造成实质性影响。

结语

通过实践,我们成功将 TDengine 应用于高频时序数据的存储与查询,并在版本迁移和性能优化中积累了丰富的经验。这不仅帮助我们提升了业务系统的稳定性和效率,也验证了 TDengine 在应对复杂运维场景时的强大能力。希望我们的经验能为更多技术团队提供有价值的参考,共同探索时序数据处理的无限可能。

关于七云网络

七云网络(上海叠念信息科技有限公司)于 2017 年 1 月份成立于上海,是一家创新型 SDWAN 及网络运维解决方案服务商。企业核心成员源自阿里巴巴、思科、中国电信等技术型企业,拥有丰富的互联网及企业信息化服务的经验。

关于作者

王凯(kaamil Wang),七云网络 AIOps 产品部主管,热爱开源,立志成为一名 IT 武林高手。