500个工商业电站压垮数据库?海量光伏时序数据存储的架构取舍

去年 7 月,我们接手了一个苏南地区的分布式代运维项目,涉及到 400 多个工商业屋顶电站,总装机容量接近 600MW。当时甲方自研的平台跑了不到一周,后端 InfluxDB 就开始频繁报 503 Service Unavailable。查了日志发现,不仅是高并发写入的问题,更多是因为每家逆变器厂商的 API 返回格式、字段精度、甚至时间戳时区都不一样,导致入库逻辑乱成了一锅粥。

很多做能源数字化的团队,第一反应是把数据接进来、存起来。但光伏电站的数据有其特殊性:它不是简单的 CRUD,而是典型的高频时序数据。一个 50MW 的站,如果按 5 分钟间隔拉取,看似压力不大;但如果要支撑调频、调峰或者做更精细的功率预测,采集频率通常会拉到 3 秒到 10 秒。这时候,如果你的架构还停留在「拉一个 API 存一条记录」的原始阶段,翻车是早晚的事。

我们今天不聊那些高大上的 PPT 架构,就实打实地拆解一下,从边缘侧的厂商 API 到云端 InfluxDB,这条链路上的坑到底是怎么填平的。

第一关:API 采集层的「流量地狱」与字段归一

大多数人对接华为、阳光、古瑞瓦特这些厂商云 API 时,最容易撞上的就是限流(Rate Limiting)。比如某头部厂商的 API,默认只允许每分钟 10 次调用。如果你有 500 个电站,每个电站单独去轮询,瞬间就会被封 IP。

我们在处理这个项目时,放弃了「电站级轮询」,改成了「组织级/账号级批拉」。通过一个 Token 批量拉取下属所有电站的实时列表。这里有个细节:不同厂商的 API 返回值里,电量的单位可能是 kWh,也可能是 MWh,功率可能是 W 也可能是 kW。甚至有的厂商在凌晨 0 点到 4 点会停止数据更新,返回空值或最后一次历史值。

为了解决存储前的混乱,我们必须建立一层「归一化映射表」。以下是我们内部常用的一套归一化字段参考:

标准字段名 业务含义 推荐数据类型 备注
active_power 有功功率 Float (kW) 强制统一为 kW,保留 3 位小数
daily_yield 当日发电量 Float (kWh) 需处理部分厂商累积电量清零逻辑
v_pv1 PV1 路电压 Float (V) 多路 MPPT 需拆分存储
status 运行状态 Integer 归一化为:0-待机, 1-运行, 2-故障

第二关:大数据网关的缓冲逻辑------不要让数据库直面洪水

在数据进入 InfluxDB 之前,必须有一个「中间层」来做缓冲和削峰填谷。我们当时用了 Redis 作为一级缓存,配合一个基于 Go 写的消费端。为什么要这么做?

  1. 补传机制(Backfilling) :光伏电站的通信链路极不稳定,4G 信号断了是常态。厂商 API 经常会补传前两个小时的数据。如果你直接往时序数据库写,InfluxDB 的 TSM 引擎在处理「过去时间戳」的写入时,IO 压力比「当前时间」大得多。我们需要在消费端识别这些历史数据,进行批量的 Upsert 操作。
  2. 数据降采样(Downsampling):对于运维监控,3 秒一次的数据太密了,看板根本不需要这么高的频率。我们在网关层做了一个简单的滑动平均过滤,把 3 秒的高频数据聚合为 1 分钟的基准点存入生产库,而原始高频数据则存入低频访问的冷存储。
sql 复制代码
-- 典型的 InfluxDB 写入行协议格式示例
-- measurement,tags fields timestamp
device_telemetry,inverter_sn=SN123456,station_id=ST_001 active_power=45.2,daily_yield=120.5,temp=42.3 1689235200000000000

第三关:InfluxDB 的架构设计------拒绝「基数爆炸」

这是很多工程师最容易栽跟头的地方。InfluxDB 的查询性能取决于 Series Cardinality(序列基数)。如果你把逆变器的序列号(SN)、型号、甚至每天生成的告警 ID 都作为 Tag,基数会迅速膨胀到几百万,最后导致内存溢出。

我们的方案是:

  • Tags 只放索引 :只放 station_id(电站 ID)和 device_id(设备 ID)。
  • Fields 放数值:功率、电压、电流、温度。这些不建立索引,查询时通过 Tag 过滤后进行 Scan。
  • Retention Policy (RP) :我们设置了两个 RP。实时库保留 30 天数据,采用高性能 SSD;历史库保留 5 年数据,存放在容量大的机械硬盘阵列上,并定期触发 Continuous Queries (CQ) 进行数据下采样。

在那个 600MW 的项目中,我们通过这套架构,将原本每秒 8000 次的随机写入优化成了每 5 秒一次的批量写入,数据库 CPU 占用率从 85% 降到了 12% 左右。

我们的思考与取舍

做光伏数据采集,千万不要迷信「通常实时」。在公有云 API 的限制下,所谓的实时其实都是「伪实时」。真正的挑战在于如何处理那 30+ 厂商千奇百怪的错误码,以及如何在 API 变更时不需要重构你的数据库表结构。

我们后来把这套针对多厂商 API 对接、字段归一、以及高并发写入的逻辑,封装成了一个专门的中间件,也就是我们内部一直在迭代的 ZenovaConnect。它的核心价值就是把这些脏活累活干了:不管是华为的北向接口,还是阳光云的 API,接进来之后,推给你的都是统一格式的 JSON 或时序数据包。这样你上层的 EMS 或分布式监控平台,只需要关注业务逻辑,不用再跟那些写得像天书一样的 API 文档死磕。

如果你现在也面临多品牌逆变器接入、数据存不进或者查不出的窘境,建议先回过头看看你的 Tag 设计是否合理。毕竟在能源数字化这条路上,数据接进来只是第一步,能存住、能算快,才是硬本事。

你目前在用的时序数据库是哪一家?在处理多厂商数据归一时,最让你头疼的字段是哪一个?欢迎在评论区聊聊。

了解 ZenovaConnect 完整方案

相关推荐
mubei-1232 小时前
SpringDAO的用法
java·开发语言·数据库
Dr.kangder3 小时前
嵌入式处理器仿真技术——Hypervisor 原理与实践
服务器·嵌入式硬件·架构·嵌入式
星蓝_starblue5 小时前
零服务器、零数据库!开源growth-board,利用GitHub自动管理刷题/学习/求职全流程
服务器·数据库·程序人生·系统架构·node.js·github·改行学it
2601_964840275 小时前
技术方案解析:4G 云边协同架构下,智能门禁系统的轻量化升级路径
架构
三8447 小时前
sqli-labs1-10通关笔记
数据库
漫谈数据智理7 小时前
从参考架构到可运行体系如何理解 IDSA 的最新进展
架构·高质量数据集
2601_963749107 小时前
越华环保集团污水监测云边协同架构:数字化污水治理Modbus-MQTT链路实现方案
人工智能·架构
XR1234567888 小时前
校园网整体架构选型:从核心到接入哪家方案更优?
架构
智购科技自动售卖机厂家8 小时前
从STM32到RK3588——自动售货机嵌入式主控方案的架构演进~YH
stm32·嵌入式硬件·物联网·架构·lua·零售·symfony