1. 选型背景
我公司致力于储能业务的开发,包括对庞大而复杂的储能装置进行设计、制造和管理。
在生产安全的重任下,我们需要实时监测电池的每一次充放电过程、电流、电压等值,以保障电池安全,而每一个变化的数据就是一个带有时间戳的时序数据。
大型储能装置十分复杂,伴随着业务的扩展,我们的设备和测点数量不断激增,数据采集的频率也在不断提高。
面对海量的时序数据,传统的处理方案显得力不从心,成本高昂且效率低下。因此,我们需要一款高性能的时序数据库,实现数据的高效处理和实时分析。
经过深入的调研之后,我们在 InfluxDB 和 IoTDB 之间选择了 IoTDB 作为储能业务线的时序数据库。
IoTDB 1.0 版本后支持了分布式部署,其数据分区存储的高可扩展性,以及多副本存储实现了无单点故障的高可用性,都深深吸引了我们。
而且,IoTDB 搭配了多种一致性协议,能够适配不同的场景,这种易于横向扩展的系统架构,完美匹配了我们业务的发展趋势。
2. 部署架构
考虑到将 IoTDB 部署在物理服务器上,通过公网进行业务应用交互可能会带来数据延迟和运维成本问题,并且需要从头规划计算、存储以及监控系统,整个过程耗时漫长,不利于项目推进。
最终,我们决定直接在业务应用的 K8S 环境上部署 IoTDB,实现云上集成应用。这样不仅可以提高运维的一致性,也充分利用了云环境的弹性。
部署 IoTDB 后的业务架构是这样的:在储能设备端,电池簇持续实时上报增量时序数据,并每隔 5 秒上报一次超过 10 万指标的全量时序数据。
这些数据通过站端转发服务器,使用 MQTT 协议传输至云端,经过 EMQX 的数据转换后,存储至阿里云环境中部署的 IoTDB 数据库,并进一步进行数据的查询、计算与分析。
IoTDB 新颖的分布式架构和高可用模式,为我们提供了强有力的数据存储保障,因此目前我们采用了 3C3D 的高性能分布式架构。
对于整体存储空间,IoTDB 支持使用公有云的 SSD 云盘随时扩容,DataNode 节点容量也可以通过 scale StatefulSet 工作负载进行扩容,为我们的业务架构提供了非常高的灵活性。
为满足实时监控处理需求,我们利用了 IoTDB 内置的 Prometheus Exporter,快速接入监控,实时了解集群状态,为性能优化指明方向。
在数据备份方面,我们采用了 Velero 对 IoTDB 相关负载进行备份,数据可以直接备份到 OSS 上,也可以通过 crontab 定时备份,并使用 velero hook annotation 在备份前进行强制 flush 刷盘,以保障备份过程中的数据完整性。
值得一提的是,在部署落地的过程中,IoTDB 的用户文档描述清晰,运维简便,上手成本低,大大方便了我们运维人员的部署工作。
并且,我们深深感受到 IoTDB 背后有一群热爱研发的程序员,他们的运维支持稳定可靠、响应积极快速,我们生产中遇到的问题能够在很短时间内获得很多实质性的帮助,因此我们对于 IoTDB 产品和团队是非常信任的。
我们的 IoTDB 集群配置如下:
root@iotdb-datanode-0:/iotdb/sbin # start-cli.sh -h iotdb-datanode
---------------------
Starting IoTDB Cli
---------------------
_____ _________ ______ ______
|_ _| | _ _ ||_ _ `.|_ _ \
| | .--.|_/ | | \_| | | `. \ | |_) |
| | / .'`\ \ | | | | | | | __'.
_| |_| \__. | _| |_ _| |_.' /_| |__) |
|_____|'.__.' |_____| |______.'|_______/ version 1.1.2 (Build: 54819a1-dev)
Successfully login at iotdb-datanode:6667
IoTDB> show variables;
+----------------------------------+-----------------------------------------------------------------+
| Variable| Value|
+----------------------------------+-----------------------------------------------------------------+
| ClusterName| defaultCluster|
| DataReplicationFactor| 2|
| SchemaReplicationFactor| 3|
| DataRegionConsensusProtocolClass| org.apache.iotdb.consensus.iot.IoTConsensus|
|SchemaRegionConsensusProtocolClass| org.apache.iotdb.consensus.ratis.RatisConsensus|
| ConfigNodeConsensusProtocolClass| org.apache.iotdb.consensus.ratis.RatisConsensus|
| TimePartitionInterval| 604800000|
| DefaultTTL(ms)| 9223372036854775807|
| ReadConsistencyLevel| strong|
| SchemaRegionPerDataNode| 3.0|
| DataRegionPerDataNode| 5.0|
| SeriesSlotNum| 1000|
| SeriesSlotExecutorClass|org.apache.iotdb.commons.partition.executor.hash.BKDRHashExecutor|
| DiskSpaceWarningThreshold| 0.05|
| TimestampPrecision| ms|
+----------------------------------+-----------------------------------------------------------------+
Total line number = 15
IoTDB> show cluster;
+------+----------+-------+---------------------------------------------------------------+------------+
|NodeID| NodeType| Status| InternalAddress|InternalPort|
+------+----------+-------+---------------------------------------------------------------+------------+
| 0|ConfigNode|Running|iotdb-confignode-0.iotdb-confignode.iotdb-cls.svc.cluster.local| 10710|
| 1| DataNode|Running| iotdb-datanode-0.iotdb-datanode.iotdb-cls.svc.cluster.local| 10730|
| 2| DataNode|Running| iotdb-datanode-1.iotdb-datanode.iotdb-cls.svc.cluster.local| 10730|
| 3| DataNode|Running| iotdb-datanode-2.iotdb-datanode.iotdb-cls.svc.cluster.local| 10730|
+------+----------+-------+---------------------------------------------------------------+------------+
使用的 IoTDB 数据备份脚本如下:
velero create backup iotdb-backup1106 --include-namespaces iot-dbtest --default-volumes-to-restic --snapshot-volumes
3.应用效果
以下举例两个 IoTDB 在我们的储能业务中的实际应用场景:
业务场景一
在某大型储能业务中,IoTDB 共监测 150 个设备,10000 测点,1 秒采集一次上报的时序数据。其集群写入性能稳定实现千万级吞吐,并发 10 个聚合查询场景,平均耗时都在 1 秒之内,各项监控指标表现优异,完全满足我们的业务需求。
在该场景,我们使用 IoT-Benchmark 进行压测的结果如下:
集群设置:
+------+----------+-------+------------------------------------------+------------+
|NodeID| NodeType| Status| InternalAddress|InternalPort|
+------+----------+-------+-----------------------------------------+------------+
| 0|ConfigNode|Running|iotdb-0.iotdb.iotdb-cls.svc.cluster.local| 10710|
| 3|ConfigNode|Running|iotdb-1.iotdb.iotdb-cls.svc.cluster.local| 10710|
| 5|ConfigNode|Running|iotdb-2.iotdb.iotdb-cls.svc.cluster.local| 10710|
| 1| DataNode|Running|iotdb-0.iotdb.iotdb-cls.svc.cluster.local| 10730|
| 2| DataNode|Running|iotdb-1.iotdb.iotdb-cls.svc.cluster.local| 10730|
| 4| DataNode|Running|iotdb-2.iotdb.iotdb-cls.svc.cluster.local| 10730|
+------+----------+-------+-----------------------------------------+------------+
性能表现:
业务场景二
在某大型储能业务中,IoTDB 共监测 150 个设备,1 分钟采集一次,连续上报 3 个月的时序数据,覆盖测点数近 150 亿个。IoTDB 的千万级写入性能完全满足场景需要。在核心聚合查询场景中,SQL 结果均在 1 秒内返回,而对于如此数量的模型数据,关系型数据库是不可能完成查询的。
聚合查询场景举例如下:
# 5 月 28 号的平均A相电流, 左闭右开区间包含 5 月 28 号零点的数据,不包含 5 月 29 号零点的数据。
IoTDB> select AVG(aa160) from root.test.teq_492.PCS group by ([2024-5-28T00:00:00,2024-5-29T00:00:00),1d);
+------------------------+-------------------------------------------+
| Time|AVG(root.test.snSN_1716889138492.PCS.aa160)|
+------------------------+-------------------------------------------+
|2024-05-28T00:00:00.000Z| 20.0|
+------------------------+-------------------------------------------+
# 5 月 28 号到 5 月 31 号间每天前三小时内UV相电压总计量和最大值
IoTDB> select count(aa161),max_value(aa161) from root.test.teq_492.PCS group by ([2024-5-28T00:00:00,2024-5-30T00:00:00),3h,1d)
+------------------------+---------------------------------------------+-------------------------------------------------+
| Time|count(root.test.snSN_1716889138492.PCS.aa161)|max_value(root.test.snSN_1716889138492.PCS.aa161)|
+------------------------+---------------------------------------------+-------------------------------------------------+
|2024-05-28T00:00:00.000Z| 2186| 7854|
|2024-05-29T00:00:00.000Z| 3120| 8566|
+------------------------+---------------------------------------------+-------------------------------------------------+
# 查询aa162的5 月 27 号到 29号每天的最高峰值:
IoTDB> select max_value (aa162) from root.test.teq_492.PCS group by ([2024-5-27T00:00:00,2024-5-29T00:00:00),1d)
+------------------------+--------------------------------------+
| Time|max_value(root.test.teq_492.PCS.aa162)|
+------------------------+--------------------------------------+
|2024-05-27T00:00:00.000Z| 20|
|2024-05-28T00:00:00.000Z| 20|
+------------------------+--------------------------------------+
# 每隔半天统计 5月 25 号到 31 号 0 点到 6 点的aa163的平均值:
IoTDB> select avg(aa163) from root.test.teq_492.PCS group by ([2024-5-25T00:00:00,2024-5-31T00:00:00),6h,12h)
+------------------------+-------------------------------------------+
| Time|avg(root.test.snSN_1716889138492.PCS.aa163)|
+------------------------+-------------------------------------------+
|2024-05-25T00:00:00.000Z| 7.55|
|2024-05-25T12:00:00.000Z| 8.33|
|2024-05-26T00:00:00.000Z| 5.55|
|2024-05-26T12:00:00.000Z| 6.88|
|2024-05-27T00:00:00.000Z| 3.33|
|2024-05-27T12:00:00.000Z| 6.12|
|2024-05-28T00:00:00.000Z| 6.14|
|2024-05-28T12:00:00.000Z| 5.11|
|2024-05-29T00:00:00.000Z| 8.43|
|2024-05-29T12:00:00.000Z| 4.98|
|2024-05-30T00:00:00.000Z| 7.79|
|2024-05-30T12:00:00.000Z| 6.55|
+------------------------+-------------------------------------------+
4. 未来展望
部署 IoTDB 后,我们不但可以很自豪地和客户说:“我们使用的是国产时序数据库。”而且这款国产时序数据库还能够真正高效地管理海量时序数据,有效提升数据的处理和实时分析能力,为公司储能业务的电池安全监控提供有力保障。
未来,我们希望抽象出一套 operator 来满足各种不同架构的 IoTDB 部署,同时实现 K8S 环境的一键部署。我们也希望与 IoTDB 团队继续保持紧密合作,适配更大规模的数据体量,通过对更多时序数据的有效管理,进一步赋能我们储能业务的发展。
更多内容推荐:
• 了解更多 IoTDB 应用案例