演讲干货整理:泛能网能碳产业智能平台基于 TDengine 的升级之路

在 7 月 26 日的 TDengine 用户大会上,新奥数能 / 物联和数据技术召集人袁文科进行了题为《基于新一代时序数据库 TDengine 助力泛能网能碳产业智能平台底座升级》的主题演讲。他从泛能网能碳产业智能平台的业务及架构痛点出发,详细分享了在数据库选型、平台架构改造、新旧底座替换以及数据迁移等多个维度的经验,为与会者提供了宝贵的参考。本文据此演讲内容整理而成。

平台痛点及架构痛点

新奥数能科技有限公司成立于 2018 年,隶属于新奥集团。公司基于新奥集团过去 30 多年在能源行业的经验积累,以及 10 多年来对泛能理念的深刻理解,结合物联网、大数据和人工智能技术,打造了一个智能能碳产业平台,我们称之为“泛能网”。

泛能网的核心聚焦于公建、工厂、园区等应用场景。我们的客户,尤其是他们的管理层以及能源部门或运维部门,在日常节能降本、设备运营和运维方面,经常会遇到难以解决的问题。而我们正是围绕这些客户的痛点,提供一体化的智能平台解决方案。

泛能网的建设理念是从底层物联设备中采集客户需要解决的关键设备数据,汇总到平台,经过大规模的数据处理后,生成监控和运维的指标。接着,通过智能算法和仿真能力,我们为客户提供包括实时监控、运营管理,甚至未来的碳交易等一系列应用产品。

自 2018 年平台建设启动以来,至今已经有五六年的发展历程。在这个过程中,我们遇到了一些行业内普遍存在的痛点。第一个痛点是海量物联设备的数据采集问题。以一个简单的例子来说明:我们服务于 5000 多家客户,每个客户有约 50 台设备,每台设备每分钟采集 10 到 20 个数据点,那么每秒的数据处理量(TPS)就达到 9 万左右。如果涉及到电力等领域,数据采集的频率还可能更高,达到秒级甚至毫秒级,数据量会成倍增加。

第二个痛点在于数据查询的多维度要求。客户可能基于时间维度,需要查看最大值、最小值、平均值,甚至差值分析。同时,他们对查询结果的响应速度有很高的要求。此外,数据的长期存储也是一大挑战。有些客户希望保留 5 年甚至 10 年的数据,这对存储空间和查询索引带来了不小的压力。

除了数据采集和查询,另一个挑战是指标的计算。过去我们遇到的两大问题,一是指标计算不准确:典型问题是日、月、年数据不能互相印证,日月不等用电约 7%,用水及蒸汽约 18%,用燃气超过 31%;月年不等超过 50%,是长期以来的全局性问题。另外测点数据延迟、互相依赖的指标执行先后不同等也会使指标计算不准确。

二是指标计算不及时,这主要源于过去采用的计算方式依赖于任务调度和公式计算。这种方式不可避免地会导致计算延迟,因为调度过程本身就存在一定的延时,尤其是当涉及大量历史数据计算时,频繁的调度会造成更显著的延时。此外,某些数据测点如果出现断数或数据丢失,也会进一步影响数据的及时性。

为了解决这些问题,经过分析,我们从两个方面进行了改进。首先,原有的平台架构虽然在当时能够满足需求,但随着客户数量和数据量的增长,现有架构已经无法支撑当前和未来的业务发展。其次,过去选用的一些存储方案已经逐渐过时,不能再满足现有需求。

具体来说,我们曾基于 OpenTSDB 的存储方式,结合任务调度来完成数据处理。这种方式的核心问题是任务调度的不及时性和频率不一致,导致了数据加工的延迟和不准确。此外,数据采集和处理共用同一套存储资源,造成了资源瓶颈。下图展示了我们过去的资源使用情况,尽管我们用了十多台物理服务器,每台服务器拥有 60 多个计算核心,依然无法满足需求。

数据方案选型及落地应用

基于以上所提到的痛点,我们针对性地提出了相应的解决方案。首先,我们需要考虑两个核心问题:一是如何选择新的基础设施,二是未来技术架构的演进方向

关于基础设施选型,我们首先从几个技术维度进行深入考虑,包括技术的适配性、国产化程度、成熟度、社区活跃度以及商业化支持等。经过对 TDengine、OpenTSDB、InfluxDB、Kdb+、TimescaleDB 等多种方案的对比,综合分析发现,TDengine 在满足这些维度需求上具有明显优势,虽然它相对较新,但在各方面的表现十分适合我们的业务需求。

相较于其他解决方案,OpenTSDB 在实际使用中已经暴露出诸多问题,InfluxDB 在开源版本上缺乏集群能力,Kdb+ 并未开源,且商业化过于封闭,TimescaleDB 作为 PostgreSQL 的扩展,其开源版本功能相对单一。因此,综合考虑开源性、商业支持及长远发展,我们最终选择了 TDengine 作为基础设施。

有了底层架构的选型后,我们对技术架构进行了相应的调整。首先,我们将任务调度模式升级为流式计算模式。流式计算在互联网应用中已十分普遍,但在工业互联网中仍较少应用。通过引入流式计算,我们能够将原有的任务调度方式转变为实时流式处理,这有效解决了任务调度中的延迟问题。同时,我们还将数据采集与计算分离,构建了“采算分离”架构:即通过物联网平台实现数据采集,再使用流式处理对采集到的测点数据进行实时加工与计算,进一步提升了数据处理的实时性与准确性。

基于新架构,我们接下来探讨如何具体落地并应用。例如,针对空压机的能耗监测和运行状态管理场景,空压机系统内可能包含多个空压机组,同时配备电能表或流量计作为测点设备。我们需要对这些测点的数据进行一级和二级的指标处理。在 TDengine 中,我们充分利用了超级表和子表的功能,将不同类型的测点归类为超级表,每台设备的实例对应子表。每个子表中的行记录对应设备的数据点,列则代表具体的测点。这一模型为我们提供了高效的测点数据存储方式。

同样地,对于指标计算,我们采用了类似的模型。常见的指标计算中会涉及不同的时间维度,如时、分、秒、日、月、年等。大部分应用场景要求在界面上展示某一分钟的指标曲线或某个时间段的指标趋势。因此,我们基于时间维度构建超级表,不同的时间类型作为分类维度,每个子指标作为子表,记录具体的指标值。这样一来,我们就完成了数据采集和指标计算的存储模型定义。

有了存储模型后,我们还需要解决一些数据处理中的常见问题。首先就是数据延迟问题。并非所有设备都能准时上报数据,有时会出现延迟。为了兼容这些延迟数据,我们在TDengine的流式计算中引入了 Watermark(水位线)机制,通过冗余时间叠加来处理延迟数据,确保计算的准确性。

其次,在高频率上报的场景中,一分钟内可能会收到大量数据点,但我们并不需要每个数据点都进行计算。这时我们采用数据分桶原理,将数据汇总后集中计算,提升了效率。

最后,针对复杂的指标计算,如空压机系统中的单耗指标,它由气量和电量的比值计算得出。这种场景下,我们通过分流每个因子的数据,分别计算后再汇总,解决了复杂指标中多因子并行计算的问题。

此外,数据会延迟,那自然也会有超前的境况出现,部分设备由于时间校准不准确或设备老化,可能会导致数据超前。对于这些情况,我们通过兼容性处理手段,在一定范围内等待数据,然后再进行延迟处理。对于严重超前的数据,我们则通过程序异常判断和设备时间校准来解决,确保数据的准确性。

新旧平台切换、架构迁移及效果

解决了前面提到的计算过程中异常的问题后,我们还需要考虑如何设计我们的底层模型,以及在平台改造完成后,如何进行线上切换。毕竟,我们的产品已经在线上运行了好几年,要进行如此大的底层更换,对我们来说也是一个巨大的挑战。

为了应对这个挑战,我们设计了一种动态切换的机制。我们将所有客户和数据源通过灰度发布或者叫做开关策略进行切换。当某个企业需要走新流程时,我们通过一个开关让它的流量路由到新的平台上。这样我们能够在尽量减少对客户影响的前提下,平稳完成平台的切换。

然而,除了平台切换,我们还面临着一个更大的挑战,那就是历史数据的迁移。我们这里面涉及到大量的历史数据,主要有以下四个方面的难点:

  1. 不能影响老系统的线上查询,且迁移成本需要可控。因为迁移时需要频繁读取旧的指标数据,这会影响线上指标查询的响应时间。

  2. 历史指标需要按企业维度迁移。指标历史结果数据模型不支持一次性读取所有企业的指标实例,需转化获取指标实例的 metric 值。

  3. 历史指标结果数据种类多且复杂,指标配置规则也十分多样,导致每个数据迁移任务都需要个性化处理。

  4. 迁移的历史数据量巨大。我们要迁移的数据量高达千亿级别,仅指标数据就有约 2000 亿条,测点数据更多。迁移的时间范围长,且指标实例量巨大,需要在短时间内迁移千亿级数据。

为了解决这些问题,我们采用了几种方式。首先,我们开发了自定义的数据迁移工具。其次,我们对 OpenTSDB 的历史数据进行了备份,再从备库中提取数据写入 TDengine。在实际操作中,可能我们写入的方法不是很合理,一开始还遇到了写入速度慢的问题。后来通过与 TDengine 的技术专家沟通,我们利用了 TDengine 的高性能写入能力,一次可以写入 50 万条数据,耗时仅为 100 毫秒,这极大地提升了数据迁移的效率。

完成数据迁移后,整个平台的迁移方案就相对完整了。去年,我们顺利完成了大约七八千个客户以及所有相关数据的切换工作。

通过这次平台升级,我们看到了显著的效果。首先,及时性得到了大幅提升。对比以往,我们的计算频率最少提高了 4 倍,最高的时候,例如从年指标计算频率两天一次提高到每分钟一次,时效性提高了 100 倍。计算时长方面,最少也提高了两倍,最高提升了 8 倍。

其次,计算准确度有了很大提升。通过流式处理和层级加工的方式,我们的指标数据能够前后一致地匹配,解决了无序数据带来的准确性问题。同时,延迟数据的处理也更加智能化,可以自动计算延迟测点的数据,并递归修正受影响的所有指标。对于日、月、年指标计算频率不一致的问题,我们也做了统一处理,现在所有计算频率统一为 15 分钟,并使用统一的时间窗口进行计算,确保数据的准确性。最终,客户投诉率几乎降为 0。

经验分享

最后,想跟大家分享一些我们在这个过程中总结出的经验和建议:

  1. 如果项目中需要删除数据,而TDengine 社区版不支持直接删除数据。如果是单独子表,那我们可以整个进行删除操作,如果是子表内数据,那可以通过标识数据来实现删除。

  2. 如果出现未来时间数据不能写入或写入报错的问题,解决办法是在建库时关注两个参数:一个是数据保留天数(keep),另一个是数据存储时间跨度(days)。根据这两个参数,TDengine 允许写入数据的时间范围是:从 now-keepnow+days。因此,如果要写入的数据超出这个范围,就会出现超出范围的错误。在创建数据库时,建议根据具体需求合理设置这两个参数,确保数据可以在预期的时间范围内写入。

  3. 在项目中,如果遇到无法通过时间戳主键更新当前记录的问题,通常是因为在建库时, update 参数的默认值为 0,表示不支持更新操作。为了解决这个问题,需要根据项目需求调整该参数,例如将 update 参数设置为 1,以支持整行更新。在当前项目中,将 update 参数设为1即可实现按时间戳主键更新记录的需求。

结合前面的注意事项,在日常项目中引用或评估使用 TDengine 时,我们需要从多个维度考虑相关参数。接下来,我会为大家详细讲解这些维度和所需考虑的具体因素,并附上一个汇总表格供大家参考。

1.项目基础信息的输入

首先,我们需要输入与项目相关的基本信息。这些信息包括未来需要监控或管理的设备数量、设备参数以及测点的数量。如果项目中涉及指标计算或存储相关的需求,这些也需要作为输入项加以考虑。

2.磁盘评估

在进行项目评估时,磁盘容量是我们需要优先考虑的因素之一。根据设备数量、数据采集频率和存储时长等因素,磁盘容量需求将直接影响项目的实施效果。因此,我们需要对磁盘进行合理的配置,以确保数据的存储和查询性能。

3.内存评估

内存方面,我们需要关注几个关键因素:

  • 节点数量和虚拟分组(vgroups)数量:根据 TDengine 的架构原理,节点数量和 vgroups 的配置对系统的性能和稳定性起到至关重要的作用。

  • 副本(Replica):这是数据库的备份机制,对于任何企业来说,数据的高可用性和存储安全性至关重要。因此,副本数量的设置应与具体项目需求紧密结合。

4.缓存配置

缓存设置也是影响系统性能的重要因素。在数据查询或存储时,我们需要为系统预留足够的缓存空间,以提高数据查询速度和数据读取效率。具体配置项包括 buffer、pages、pagesize、cachesize 等参数。这些参数的设定应结合实际项目需求和数据量进行评估。

5.CPU 评估

最后,CPU 的性能评估主要涉及数据查询和计算的负载。根据数据量的大小、查询频率以及计算需求,合理配置 CPU 资源能够确保系统高效运行。针对不同项目的实际情况,CPU 的需求也会有所差异,因此需要进行更详细的思考和规划。

以上就是我们平台改造过程中的一些重要节点和解决方案,结合这些经验和注意事项,希望能为大家在类似项目中提供一些参考。

结语

回顾我们使用 TDengine 的这段历程,不禁感慨万分。从最初的选择 OpenTSDB,到我们面临种种挑战,决定进行新一轮的数据库选型,这一路走来充满了思考与抉择。2018 年到 2022 年,OpenTSDB 在我们私有化场景中的表现曾一度支撑着我们的系统,但随着业务的不断扩展,问题也接踵而至——高昂的部署成本、复杂的运维难题,让我们不得不寻求新的解决方案。

正是在这个关键时刻,TDengine 走入了我们的视野。初次接触 TDengine 时,我们带着试探的心态,先在私有化场景中做了尝试。出乎意料的是,它不仅帮助我们降低了部署和运维成本,还让我们对未来充满了信心。于是,2023 年 6 月,我们正式启动了平台的全面切换,将 TDengine 应用到核心生产环境。

当然,任何技术变革的路上从不都是一帆风顺。我们也曾在 TDengine 2.6 版本时遇到过一些小问题,但通过与 TDengine 的技术专家密切合作,我们共同修复了这些 bug。随着系统逐步升级到 3.0 版本,我们在不断优化的过程中,也看到了 TDengine 带给我们的稳定性和效率提升。终于,在 2023 年 11 月,我们的整个平台稳定运行,所有的努力和尝试都获得了回报。

从 18 年初次启程到如今,我们不仅见证了 TDengine 的发展,也见证了自己系统的蜕变。这一路的技术革新不仅仅是架构的演进,更是我们对未来的信心所在。正是因为有了这些经历和突破,我们相信,未来无论遇到什么样的挑战,我们都有足够的底气去迎接。而 TDengine,已成为我们坚定的同行者。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/54705.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么选择合适的数据恢复软件?适用于 Windows 的数据恢复软件对比

针对 Windows 的领先数据恢复软件的全面回顾: 丢失重要数据对任何 Windows 用户来说都是一场噩梦。从意外删除到系统崩溃,数据丢失是一个非常普遍的问题。值得庆幸的是,有强大的数据恢复工具可以帮助找回丢失的文件。这篇评论深入探讨了适用于…

编译链接的过程发生了什么?

一:程序的翻译环境和执行环境 在 ANSI C 的任何一种实现中,存在两个不同的环境。 第 1 种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。 第 2 种是执行环境,它用于实际执行代码 也就是说:↓ 1&#xff1…

R语言绘制折线图

折线图是实用的数据可视化工具,通过连接数据点的线段展示数据随时间或变量的变化趋势。在经济、科学、销售及天气预报等领域广泛应用,为决策和分析提供依据。它能清晰呈现经济数据动态、助力科学研究、反映企业销售情况、预告天气变化,以简洁…

std::list

std::list是C标准库中的一个序列容器,它提供了双向链表的功能。std::list允许在序列的任何位置高效地插入和删除元素,而不会引起其他元素的移动,这使得std::list在需要频繁插入和删除操作的场景中非常有用。 std::list的特性: 双…

阿里140滑块-滑块验证码逆向分析思路学习

一、声明! 原创文章,请勿转载! 本文内容仅限于安全研究,不公开具体源码。维护网络安全,人人有责。 文章中所有内容仅供学习交流使用,不用于其他任何目的,均已做脱敏处…

使用Go语言的gorm框架查询数据库并分页导出到Excel实例(包含源代码,可以直接运行)

文章目录 基本配置配置文件管理命令行工具: Cobra快速入门基本用法生成mock数据SQL准备gorm自动生成结构体代码生成mock数据查询数据导出Excel使用 excelize实现思路完整代码参考入口文件效果演示分页导出多个Excel文件合并为一个完整的Excel文件完整代码基本配置 配置文件管理…

Javascript 普通非async函数调用async函数

假设我们有一个异步函数 async function asyncFunction() {console.log("开始执行异步函数");await new Promise(resolve > setTimeout(resolve, 1000)); // 模拟异步操作console.log("异步函数执行完毕"); } 我们在调用这个异步函数时,比…

【差分数组】个人练习-Leetcode-3229. Minimum Operations to Make Array Equal to Target

题目链接:https://leetcode.cn/problems/minimum-operations-to-make-array-equal-to-target/description/ 题目大意:给出两个数组nums[]和target[],可以对nums[]数组进行这样两种操作 给某个区间内的子列全加1给某个区间内的子列全减1 求…

C语言从头学66—学习头文件 <stdio.h>(二)

关于可变参数,我们曾经在《C语言从头学27》中接触过,下面学习能够接收可变参数作为 参数的几个函数。 一、printf函数的能够接收可变参数的变体函数: 1、函数vprintf() 功能:按照给定格式,将可变参数中的内容输…

Java 用属性名称字符串获取属性对象

一、场景分析 java 中没有 python 一样的方法,通过属性名称直接获取属性值。 getattr(obj, name[, default]) : 访问对象的属性。 getattr(student, name) java 中有 Map, 可以实现类似功能,但是如果我们现在有一个对象,要通过Map的方式获…

九大排序之交换排序

1.前言 所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。 重点: 冒泡排序和快速排序 2.冒泡排…

React Fiber 详解

why Fiber React Fiber的引入主要基于以下几个方面的考虑: 性能提升: 传统React的更新过程是同步的,一旦开始更新就会阻塞浏览器的主线程,直到整个组件树更新完成。这在处理大型组件树或高频用户交互时,可能会导致界…

数组合并与排序练习题

题目 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。 注意:最终,合并后数…

OpenCV库模块解析

1.OpenCV库每个模块解析 2.OpenCV的常用函数 它为计算机视觉应用程序提供了一个通用的基础设施,并加速了在商业产品中使用机器感知。作为BSD许可的产品,OpenCV使企业可以很容易地利用和修改代码。该库拥有超过2500个优化算法,其中包括经典和最…

量子概率云:微观世界中的不确定性与概率分布

量子概率云:微观世界中的不确定性与概率分布 摘要: 量子力学的核心之一是概率描述的引入,即粒子的位置和动量不能同时确定,而是在一个概率云中分布。本文探讨了量子概率云的理论基础、数学描述及其在电子云和粒子波函数中的应用。…

【基础介绍】【OCR】

注:若有冒犯,请问候留言,会尽快删除。 文章目录 注:若有冒犯,请问候留言,会尽快删除。背景介绍OCR基本概念介绍基础实现算法深度学习方法1. CNN(卷积神经网络)2. RNN(循环…

C语言学习之 没有重复项数字的全排列

题目描述 给出一组数字,返回该组数字的所有排列 例如: [1,2,3]的所有排列如下 [1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2], [3,2,1]. (以数字在数组中的位置靠前为优先级,按字典序排列输出。) 数据范围:数…

【React】入门Day04 —— 项目搭建及登录与表单校验、token 管理、路由鉴权实现

项目搭建 创建项目 # 使用npx创建项目 npx create-react-app my-react-app # 进入项目目录 cd my-react-app # 创建项目目录结构 mkdir -p src/{apis,assets,components,pages,store,utils} touch src/{App.js,index.css,index.js} 使用npx create-react-app创建项目&#xff0…

网站优化门槛低了还是高了?

自从2015年刚接触网站时,从一无所知到现在无人指导,一直跌跌撞撞走过来,当年花了1500元找了广东一个网友用织梦CMS做了一个门户网站,记得那时一星期没下楼,把网站折腾的千疮百孔,而终逐步熟悉网站建设与搜索…

【在Linux世界中追寻伟大的One Piece】DNS与ICMP

目录 1 -> DNS(Domain Name System) 1.1 -> DNS背景 2 -> 域名简介 2.1 -> 域名解析过程 3 -> 使用dig工具分析DNS 4 -> ICMP协议 4.1 -> ICMP功能 4.2 -> ICMP报文格式 4.3 -> Ping命令 4.4 -> traceroute命令 1 -> DNS(Domain Na…