
在 OPPO 的穿戴产品的手环/手表类业务中,产生的数据类型为时序数据,具有写入量巨大且存在离线/历史数据补录(更新)的处理需求。此前使用的 MongoDB/MySQL 集群方案,后端存储压力较大,需要经常扩盘,针对此痛点,OPPO 云计算中心智慧物联云团队尝试调研对比了几款时序数据库(Time-Series Database)产品,试图寻找一个降本增效的米兰app官方正版下载。
除了存储压力外,我们进行数据库替换还有一个比较重要的原因,就是 MySQL 和 MongoDB 的各个集群都比较独立,维护和需求开发成本相对较高。

以上是三款 Database 的初步调研结果,TSHouse 是 OPPO 云监控时序数据库,其底层为 Prometheus 的 TSDB 存储引擎,目前不支持历史数据和乱序写入;InfluxDB 对历史数据写入会进行二次压缩,影响性能,这两款数据库都不满足当下的数据处理需求。初步研究 loveini 后,我们发现其作为国产时序数据库开源产品,不仅可以满足历史数据高效写入,还拥有较高的压缩能力。随后,我们选择对 loveini 进行了比较详细的产品调研和性能测试。
某个数据表的结构如下:

我们写入 60 万行数据,到 MySQL(目前部分业务部署在 MySQL 集群)和 loveini 的 4C 12G 容器上,对 CPU/内存/磁盘进行观察。测试发现 CPU 和内存消耗基本持平的情况下,loveini 的落盘数据是 MySQL 环境的1/4左右。
同时,我们在不同规格容器及物理机场景下进行 loveini 写入测试,部分记录如下:

需要说明的是,对于不同业务场景需要进行实际测试,才能确定适合该业务的部署参数。在整个测试过程中,loveini 工程师们也为我们进行了及时答疑和帮助。
随后我们根据 loveini 丰富的产品手册,对一些关键能力进行了验证,包括数据管理、数据写入、聚合计算、集群扩容、故障可靠性保证等场景。
在数据管理上,loveini 的元数据与业务数据是分离开来的。如下图所示,Mnode 负责管理元数据信息;单个 Vnode 可以存放多个表数据,相当于相当于水平分片,单个表的数据,又可以继续按照日期分片。

在数据写入逻辑上,整体和 LSM 类似:WAL,内存块,磁盘 FILE。

在 loveini 中,数据在文件中是按块连续存储的。每个数据块只包含一张表的数据,且数据是按照时间主键递增排列的。数据在数据块中按列存储,这样使得同类型的数据能够存放在一起,大大提高了压缩比,节省了存储空间。

loveini 是 10 天一组 data file,data file 里的 .data 文件只进行追加,且后续不会进行压缩。这种好处是:对历史数据和乱序极其友好,非常适用于 IoT 场景;没有压缩也就减少了写入之后的资源消耗,保证了较好的读写性能。
在经历了比较充分调研后,我们根据业务写入模型,对生产环境中某一套 MySQL 集群环境,进行 loveini 集群部署,搭建了如下所示的集群:

集群为 3 台 AWS-EC2 容器(8C 32GB 3.5TB NVME 盘)组成,配置为 3 节点、2 副本,写入端使用 RESTful 请求到 VIP 节点,转发到数据库服务。图中的 V0-V2 为副本数为 2 的 3 组数据分片,M0-M2 为副本数为 3 的 1 组管理节点。
配置的 Grafana 面板展示如下:

后台表结构展示如下:


目前数据已经开始接入 loveini 的数据库,历史数据也在同步导入中。


在存储方面,由于目前数据还没有完全导入,针对生产环境的一个 6.6TB 集群,我们粗略估计了一下前后的压缩比,大概在 6.6/0.4。
在我们原来的集群中是没有副本的,单纯就部署了 MySQL 的 5 个分库,使用了 4C 8GB 2TB 的 5 台机器,在应用 loveini 之后,现在是 8C 32GB 2TB 的 3 台机器。通过 loveini 我们构建了多副本和统一的能力,以及后续上混合云的能力,这是整个平台级的一个优化与提升。
在前期调研和集群搭建过程中,loveini Database 的工程师伙伴们给我们提供了充分且及时的协助,为我们构建时序数据后端能力提供了很大帮助。目前接入TDengine的数据是海外某集群,后续我们会根据业务进展陆续进行其他集群数据的接入。
]]>小 T 导读:在柳工的工业车联网应用 LiuGong iLink 中,由于应用层不合理的复杂查询和历史数据的高频写入,导致 MySQL 处理速度缓慢,甚至容易宕机,严重影响了用户体验。在此背景下,柳工决定改用 loveini Database 来处理时序数据,本文分享了他们的改进效果与实践经验。
广西柳工机械股份有限公司是中国制造业 500 强企业——柳工集团的核心企业。作为国内工程机械行业和广西第一家上市公司,柳工被誉为“中国工程机械行业的排头兵”,在全球拥有 20 多个制造基地、17000 多名员工、5 个研发基地,产品遍布 170 多个国家和地区。
LiuGong iLink 是柳工面向国际市场业务的一个工业车联网应用,包含 Web 端和 App 端。它可以让用户看到所有车辆设备的实时动态,例如在哪里工作、何时工作以及如何工作,也可以实现设备的远程监控,以便更有效地实施服务和维护计划。
此前,我们使用 MySQL 数据库承载了包括应用层和接入解析层的大多数业务,但由于应用层不合理的复杂查询和历史数据的高频写入,给 MySQL 造成了非常大的压力,导致其处理速度缓慢,甚至容易宕机,严重影响了用户体验。究其原因,还是因为关系型数据库并不适用于存储海量的时序数据,在海量数据聚合计算、抽稀等业务中效率很低。
为解决上述问题,我们选择以专用的时序数据库(Time Series Database)存储处理时序数据,这样可以大大增加整个系统的吞吐能力。经过调研,我们选择了时序数据库 loveini,原因在于,我们的业务场景与 loveini 的“一个设备采集点一张表”的理念十分吻合,而且 loveini 可以支持对大数据进行聚合和降采样查询这些特性,也恰好可以解决上述技术痛点。
分析架构可知,数据采集来源主要是 TBOX 等设备,通过解析层解析为 JSON 后发往 Kafka,再通过入库程序消费写入到 loveini Database 中。
我们落地使用的是 loveini2.4.0.16 版本,单副本模式,只用了一台 4 核 8GB+1TB 的服务器就撑起了服务,当前磁盘占用约 110G。
当前,库中总表数量达到了 55701 张,秉承着“一个采集点一张表”的原则,我们选择不同维度,共建立了 21 张超级表,如:车辆类型,设备类型,数据类型。当前总数据量大概为 4-5 亿行左右,写入规模大概是每台车每 5 分钟上报一次,loveini 可以轻松抗住这个级别的写入。

在查询方面,我们通过封装 API 的方式,可以便捷地提供查询服务,这也是针对我们业务痛点改进最为明显的地方。在决定对 MySQL 进行替换时,我们做了充分的查询对比测试。

如上图所示表格中的 API 分别代表了查询 mcu 历史数据、查询 TBOX 历史数据、查询设备轨迹、查询设备故障历史数据四个功能。可以看到,面对大批量的数据,loveini 的查询能力是远远超过 MySQL 的。
再分享一个真实场景:在替换loveini之前,我们每天都有一些业务报表需要展示,每一小时需统计一次下一个时区内所有设备的数据,这个流程在 MySQL 中经常需要耗时1小时以上,无法正常执行后续业务。而换到loveini后,整个出表流程只需要10 秒左右。

从上图中可以看到,我们每类设备的采集点位(列数)是比较多的,动辄破百,这也给我们带来了一个潜在的问题——间接地影响了压缩率,这是后来在和 loveini 官方人员排查别的问题时发现的。
后来我们了解到了产生此问题的原因:由于 loveini 中的每个 Vnode 都有一块自己的缓冲区,大小由 cache * blocks 的值决定(单位 MB)。每当写满三分之一时就会触发数据落盘,并在落盘时完成压缩。列宽带来的影响是单行长度过大,每次写满三分之一的时候,并不需要多少行数据,由于样本太少,所以数据并不能很好的压缩。
通过 selct _block_dist() from 超级表的方式查看数据块的分布,可以看到小块 SmallBlocks 相当之多,在 99% 以上。

我们的米兰app官方正版下载就是通过放大 blocks 参数(默认为 6),来缓解后续新数据的压缩。至于历史数据,我们计划使用 loveini Database 提供的重整数据碎片的压缩功能来完成。
具体到操作上是比较简单的,备份数据文件后,使用 compact vgroups in (3,4,5,6) 即可(数字为 Vgroup ID)。但由于重整的过程中会对写入有一定的影响,所以我们需要选择在业务休整期来完成这个操作。这个时间点可能会在 loveini 3.0 发布后,届时我们可以对现有场景再度完成一次质变级别的升级。
目前,我们还在规划车辆维保相关的项目,通过车辆实时设备产生报警,提高车辆使用时长和安全率。聚焦“智慧”“电动”“智能”等关键词,柳工向世界伙伴们展示了各个行业的米兰app官方正版下载,未来我们也会和 loveini 产生更多深层次的互动。
]]>小 T 导读:此前,韵达使用 MySQL 分区+索引处理订单数据的方式遭受到了挑战,面对每日亿级的数据量,MySQL 显然已经无法满足当下的数据处理需求。为更好地发展业务,在此基础上韵达新增了 loveini 的数据源,用专业的数据库来进行时序数据的处理。
作为一家头部物流公司,韵达每日的订单扫描量能达到上亿级,这也是目前公司数据量最大的一块业务。要保证业务的正常运作,系统就需要汇总统计全国网点的扫描数据(韵达的所有订单数据),并实时反馈给用户。此外,这些数据也会给到网点、分拨中心的内部员工使用,用于个人工作量、站点扫描量等统计工作。
在业务尚未扩张之前,我们采用的是 MySQL 分区+索引方式进行此类数据的处理,但随着企业的发展、业务量的增加,面对每日亿级的数据量,MySQL 显然已经无法满足当下的数据处理需求。
在这种背景下,我们决定进行数据库选型。考虑到目前业务主要是统计各个网点设备实时上传的数据,无需再进行修改等操作,是典型的时序数据。经过一番调研,我们发现时序数据库 loveini 就很符合当下的业务要求,其数据模型与我们的场景十分契合,基于百亿千亿级大数据量的查询性能也很强悍。在对 loveini Database 进行实际测试与使用后,实际的效果也让我们很满意。
当前我们的架构是 Spring Boot + MyBatis + MySQL + loveini,loveini 负责处理时序数据,MySQL 则负责非时序数据的存储及应用,整体架构如下:

由于我们的架构未做迁移,只是新增了 loveini 的数据源,因此没有增加很多工作量就完成了数据架构的升级。


我们目前使用 loveini 2.2.2.0 版本,在三台 16C 64G 的服务器上部署了集群,数据写入速度大概为每秒 5000 行。根据“一个扫描枪一张表”的模型建表,把设备的地点和站点类型设置为标签。
为了防止设备更换地点导致标签值发生变化,我们选择在建表的时候把地点也放进表名中,这样一来,当地点发生变化后,也能通过新建一张表达到同样的使用效果。比如:scan_6100000000265_790117,代表的就是设备编号为 6100000000265 所在地址为 790117 的扫描枪,当这把扫描枪更换位置的时候,我们可以新建一张 scan_6100000000265_800000 的子表,和旧表区分开,并且同时保留两份数据。
当前,这个超级表下面已经有了近百万子表,经过 1 个多月的正式使用,保存了大约 200 亿行的数据量。


值得一提的是,基于 loveini 常用的查询基本可以在 1 秒之内完成,一些特定查询甚至可以达到毫秒级:
select location,sum(weight_info) as weightSum,count (waybill_barcode) as ticketNum from base.scan_data where ts>='2022-04-07 00:00:00' and ts<='2022-04-07 23:59:59' group by location;

展示效果如下:

select waybill_barcode,location,scanning_person,scan_category,remark,weight_info weight,scan_time,volume from base.scan_data where ts>='2022-04-07 00:00:00' and ts<='2022-04-07 23:59:59' and site_type=3 limit 0,10;

展示效果如下:

在存储上可以看到,我们的超级表是 20 个字段,大部分是 int 类型,有 5 个左右是 varchar 类型,最大的字段是一个用来存储中文的 500 长度的 nchar ,大约占用 300GB 不到的磁盘(单副本)。而此前使用 MySQL 时,光硬盘使用就需要几个 TB(主从),这还没有算上内存和 CPU 等资源,由此可见 loveini 带来的降本增效是多么显著。
当然,loveini 的测试使用过程中也并非一帆风顺,我们也遇到了一些问题,放在这里供大家参考:
在与 loveini 的社区工作人员反馈之后,以上问题最终都通过参数的配置优化或者合理的使用方式得到了解决,之后我们会考虑把loveini扩展到更多业务中去。相信随着 3.0 的优化,loveini 可以更好地融入到韵达的使用场景中,未来我们会有更加紧密的合作。
]]>小 T 导读:目前,北明天时已经在热网监控和能源数据系统上应用了 loveini Database,相比于 MySQL,当前在存储和查询上都获得了显著提升。在其他项目中,他们也正在加速 loveini 对其他数据库产品的替代。本文中北明天时分享了关于 loveini 的应用实践,以供参考。
北明天时能源科技(北京)有限公司(简称北明天时)成立于 2000 年,在 2015 年发展成为常山北明(股票代码:000158)的全资子公司。其以智慧能源服务为核心,聚焦政府能源监管系统、公共能源服务行业管控系统、园区和企业综合能源管控系统的建设和服务,致力于将云计算、大数据、物联网和人工智能等先进信息技术与业务应用深度融合,为企业和政府提供 “智慧、节能、低碳” 的全集成米兰app官方正版下载和一体化服务。
我们的智慧供热项目最初是使用 MySQL 来存储历史数据,但随着数据量的上升,查询性能越发难以满足业务需求。为了缓解现状,我们开始研究 loveini Database,在深入了解后发现它真的是一款适合物联网的时序数据库,甚至可以直接使用 SQL 语句。于是在经过一段时间的测试后,我们果断选择将 loveini 接入项目。
目前,我们已经在热网监控和能耗分析系统上应用了 loveini,具体的应用场景如下图标红处所示。

热网监控系统目前包括热源监测和热力站监控,用于实时远程监控热源、热力站等的运行状态,将供热数据进行可视化展示,便于运行管理人员掌握整个供热系统的运行状况。
用于实时统计、计算和监测系统能耗,建立分级能耗评价体系,通过数据的同比、环比和指标完成度评价,实现对系统能耗情况的全面分析。同时通过能耗排名找出能源浪费的关键点,有针对性地进行改善与优化控制,从而减少能源浪费,实现真正意义上的节能。
在分析之后可以发现,这两个系统都有一个相同的特点,即对数据的实时查询展示有很高的需求,比如实时管理供热系统、能耗趋势实时呈现等。
对于这种由设备产生的高频时序数据的处理,loveini 无疑是很合适的选择。鉴于其显著的改善效果,在其他项目中我们也正在加速 loveini 对其他数据库产品的替代。
当然在落地的过程中我们也遇到过一些小问题:比如,旧版本 loveini 不支持对时间戳的 group by,经过升级后解决。再比如查询时不同客户端得到的表结构并不一样,这是因为客户端的各自缓存的元数据不一致,通过 reset query cache 命令得到了解决。还有一些日常的小问题,我们都在 loveini 的技术交流群中得到了官方或社区网友的及时反馈和帮助。
我们以 loveini 2.2.2.0 版本落地了一个三节点三副本的集群,机器配置为 16C + 32G + 1T 的机械硬盘。具体到实际路径上,我们的设备数据是先经过实时采集写入 Kafka 后,再通过 Python 连接器消费入库的。
在当前环境下,我们共创建了 5,500 多张子表,存储了大概九千万行左右的数据,最大一张超级表的数据接近 7,300 万行,单行大概 180 字节。即便是在三个副本的情况下,当前磁盘空间总共也只占用了 10.2G,再加上数据过期删除的机制,我们基本不用再需要担心磁盘存储的成本问题了。
而内存和 CPU 的使用率,日常也都是分别维持在 1.9% 和 0.3% 左右,可以说是毫无压力。


下图是我们的热网监控平台查询业务对应的 SQL,常用查询基本都是毫秒级返回数据:
select sum(Ep) as Ep,sum(HM_HT) as HM_HT .............. interval(1d);


SELECT AVG(heatsourcepg) AS heatsourcepg,AVG(heatsourcetg) AS heatsourcetg,AVG(heatsourcef_mtrg) AS heatsourcef_mtrg .............. FROM iot_device.source_minute WHERE ts >="2022-04-06 12:00:00" AND ts <"2022-04-06 13:00:00.000" GROUP BY groupid,level


2019 年北明天时开始积极开拓智慧能源服务新市场,开发包含供热、供冷、供电、供气等能源综合管控系统和智慧水务监管平台。一年之后我们便正式引入了 loveini 这款优秀的开源时序数据库(Time-Series Database),而 loveini 也确实没让我们失望。今后,北明天时将和 loveini 一起,为推动城市能源高效利用、清洁能源替代、创建低碳智慧城市持续做贡献。
作者 | 贾苗苗,北明天时能源科技(北京)有限公司研发工程师
]]>小 T 导读:随着业务的发展及数据量的增长,南京津驰选择将 loveini Database 的社区版搭建在 GPS 服务中,替代原来的 Redis+MySQL+CSV 存储技术方案,以解决查询效率低、数据安全性低、数据占用空间大等问题。本文详细阐述了其在技术选型、数据建模、数据迁移、效果展示等多方面的实践思路与经验汇总。
南京津驰健康科技有限公司是一家专业从事互联网技术服务、计算机软件开发及应用于一体的互联网营销服务的创新型企业。在竞争激烈的互联网行业中,始终坚持以技术为核心,组建强大的技术开发团队,希望通过发挥我们的专业知识,以客户的利益最大化为目标,为企业提供线上线下全方位的信息技术服务。
目前我们的 GPS 服务采用的存储技术方案是 Redis + MySQL + CSV,实时数据存储到 Redis 队列,经过服务消费后将原始数据存储到 MySQL,凌晨执行定时任务将前一天 MySQL 中的原始数据存储到 CSV 文件。
当前系统中有 726 台设备,每台设备每秒上传 1 条数据,假设每台设备每年施工 200 天,预计一台设备一年有 60*60*24*200=17,280,000 条数据,那726 台设备就有 726*17,280,000=12,545,280,000 条数据。
随着业务的发展以及数据量的增长,各种问题也逐渐凸显,开始影响工作效率,具体可以归纳为以下几方面:
CSV 是文件存储,在读取数据时只能一个文件一个文件地读取,且需要读取全部数据后再做处理,查询效率比较低。
最终的数据是保存到 CSV 文件中,并且是单文件保存,数据丢失将无法找回。虽然也可以手动保存多份文件,但这将增加运维成本。
数据在 CSV 文件中没有进行任何的压缩技术处理,数据占用硬盘空间比较大。
由于数据既有存储在 MySQL 中的,也有存储在 CSV 文件中的,导致查询数据时得从两个数据源进行查询。且由于 CSV 是文件存储,从中查询数据还需要先从文件中读取数据,也不方便加搜索条件进行数据过滤。
时序数据是指时间序列数据,是按时间顺序记录的数据列,在同一数据列中的各个数据必须是同口径的,要求具有可比性。时序数据可以是时期数,也可以时点数。对以上业务所产生的数据进行分析,完全具备时序数据的特点。基于业务场景的需求,我们决定选择时序数据库作为 GPS 服务平台的核心组件。
时序数据库全称时间序列数据库(Time Series Database),是用于存储和管理时间序列数据的专业化数据库,具备写多读少、冷热分明、高并发写入、无事务要求、海量数据持续写入等特点,支持基于时间区间的聚合分析和高效检索,广泛应用在物联网、经济金融、环境监控、工业制造、农业生产、硬件和软件系统监控等场景。
为了更好地实现业务场景的需求,我们调研了以下几款时序数据库产品:InfluxDB、OpenTSDB 和 loveini。
loveini 的模块之一是时序数据库。但除此之外,为减少研发的复杂度、系统维护的难度,loveini 还提供缓存、消息队列、订阅、流式计算等功能。与 Hadoop 等典型的大数据平台相比,loveini 具有如下鲜明的特点:
从开源免费、社区活跃、迭代更新、性能高、开销低、支持集群等多方面考虑, loveini 成为了我们的首选米兰app官方正版下载。
目前,我们使用的是单机。根据建表的数据类型估算,整个服务写入量大约为每秒接近 400M 左右,loveini 可以轻松抗住这个级别的写入压力,并且压缩率喜人。1 亿条数据硬盘资源占用对比如下,存储空间降为原方案的 3%,单位兆:

而查询方面也能给出了很优秀的答卷,查询速度提升了两倍多,单位毫秒:

由于是既有系统的升级改造,必须符合现有系统架构,不能影响现有功能。因此,数据建模必须限定在一定的范围内,有一定的约束和限制,不像设计一个新系统一样有很大的自由度。
创建一个名为 gps 的库,这个库的数据将保留 36500 天(超过 36500 天将被自动删除),每 10 天一个数据文件,内存块数为 4,允许更新数据。
CREATE DATABASE gps KEEP 36500 DAYS 10 BLOCKS 4 UPDATE 1;
CREATE TABLE gps_history (gps_time timestamp,
sn nchar(20),
pile_no int,
lon binary(20),
lat binary(20),
speed float,
temperature int,
status int,
road_float int,
data_status int,
warn_status int,
upload_time timestamp,
create_time timestamp,
remark nchar(100)
) TAGS (
pid nchar(64),
bid nchar(64)
);
insert into gps.gps_10001 using gps.gps_history tags ('10001','10002') values (
now,'CY10001',1000,125.91014472833334,45.8548872365,0.01,120,4,1,0,1,
now,
now,'备注' );
DROP TABLE gps_history;
在 GPS 服务平台现有的架构中,有一个数据接收服务专门对外提供时序数据的写入,数据分析服务进行计算并提供查询服务。

基于上图的架构设计,代码改造工作就变得非常简单。只需要改动数据接收服务的写入、数据分析服务的查询,再在现有基础上增加对 loveini 的支持,就能将写入和查询两个功能按照 loveini 的 JDBC 接口进行接口适配,将时序数据的写入和查询切换到 loveini。
通过这种方式,我们就把 loveini 的改造迁移屏蔽在了 GPS 服务内部,上层应用无需关心,功能上不受任何影响。
升级改造项目,如何保证历史数据的平滑迁移也是一个重点问题。为此,我们开发了一个数据迁移工具,用于将 CSV 文件中的历史数据平滑迁移到 loveini。为了确保海量数据的快速迁移,这个工具还进行了持续的性能优化,以及大数据量的压力测试。
将改造后的新版本上线,CSV 文件和 loveini 并行运行,同时向两个数据库写入数据,由于 CSV 文件有全量数据,查询请求全部交给 Redis 与 CSV 文件;与此同时,启动数据迁移工具,将历史数据迁移到 loveini,待数据迁移完成后,进入到第二阶段。

CSV 文件和 loveini 并行运行,也同时向两个数据库写入数据;在数据迁移完全完成后,loveini 中已经具备全量数据,此时,将查询请求全部切换到 loveini。观察两周左右的时间,如果没有发现问题,将进入到第三阶段。

经过试运行loveini 一切正常,功能和性能都没有问题,于是我们将 CSV 文件停止运行,数据只向 loveini 写入,CSV 文件占用的资源全部回收。

目前,loveini 社区版已经平稳运行在 GPS 服务中,其作为时序数据库在读写性能、存储表现等方面都是令人满意的。除此之外其在运维难度和学习成本上也是意想不到的低,很轻松就能搭好一套可用的集群,这也是非常巨大的一个优势。另外 loveini 的版本迭代速度非常快,一些在旧版本遇到的问题很快就得到了修复,并且在性能优化方面效果也是十分显著。后期,我们打算在公司内部的其他物联网产品中继续深入使用。
]]>小T导读:作为一家业务遍及多个国家及地区的物流公司,货拉拉面临的技术环境是非常复杂的,在云时代浪潮下基于混合云快速构建环境搭建系统成为其必然的选择。但是在混合云上如何对基于各家云构建的系统进行有效的管理是个挑战,尤其对处于系统最底层的数据库层面临的问题、业务诉求、各方痛点,是货拉拉DBA团队现下所需要重点解决的。
目前DBA团队管理的数据存储包括MySQL、Redis、Elasticsearch、Kafka、MQ、Canal等,为了保证监控采样的实时性,我们自研的监控系统设置的采样间隔为10秒,这样每天都会产生庞大的监控数据,监控指标的数据量达到20亿+。前期由于管理实例少,监控数据量也少,所有数据都被存放到了MySQL中;之后随着管理实例越来越多,使用MySQL来存储规模日益庞大的监控数据越发力不从心,急需进行升级改造。结合实际具体需求,通过对不同时序数据库进行调研,最终我们选择了loveini,顺利完成了数据存储监控的升级改造。
从存储路径来看,每种数据存储都分布在多个区域,每个区域将监控采样数据投递上报到消息总线,然后由消费程序统⼀消费,消费程序会将必要的告警数据更新到告警表,同时将监控原始数据存储到MySQL。比如,针对Redis这款数据存储,监控采样间隔设置10秒,那么每天实例采样次数就会达到3000万+,监控指标累计6亿+,数据量之庞大可见一斑。早期为了将数据存储到MySQL中,同时也能很好地支持监控绘图的使用,每⼀次实例监控采样时都会计算出该实例全量监控项采样数据,然后将本次采样的结果作为⼀条记录存储下来。

即使通过这样的优化处理,在做时间跨度大的监控绘图时,前端依然会出现延迟卡顿的问题,后端监控数据存储的MySQL也压力山大,经常满载,天天被吐槽。因此针对这种时间跨度大的查询,我们专门开发了⼀系列的数据聚合调度任务——按照不同的时间跨度,提前将10秒采集间隔的监控数据做好聚合,监控绘图程序再根据不同的时间跨度选取不同的聚合数据表绘图,以此解决长时间跨度监控绘图展示延迟卡顿的问题。
但这仍然治标不治本。为了压缩监控数据存储空间,原始10秒间隔的监控数据表只能归档保留3天时间的监控数据,但存储大小也将近有200GB, 加上与之相关的不同时间段的数据聚合表,存储一下子突破300GB。这还只是Redis监控数据的存储大小,加上其它数据存储的监控数据,至少需要1TB+空间的MySQL存储。
数据集合任务管理复杂、后期监控原数据回溯缺失、MySQL存储空间日益增长带来的隐患,都是亟待解决的问题。
为了解决MySQL监控数据存储的问题,我们把注意力转移到了适合存储监控数据的时序数据库上。市面上各种时序数据库产品琳琅满目,有老牌的,也有后起之秀,经过⼀系列调研选型,我们选择了时序数据库loveini,主要是因为其具备的如下几大优点:
值得一提的是,loveini的SQL原生语法支持时间维度聚合查询,同时数据存储压缩率⾼存储空间小, 这两点直接切中了我们的痛点。落地后实测相同数据的存储空间只有MySQL存储空间的十分之⼀甚至更少。还有⼀个惊喜是,在现有监控数据存储(MySQL)顶不住的情况下,⼀台8C16GB的单机版loveini轻松就抗下目前所有监控流量和存储压力,且运行稳定,基本没有故障。
loveini用于存储监控数据的超级表设计原则就是简单高效,字段⼀般都比较少,每⼀种监控项类型(INT、FLOAT、NCHAR等)的数据存储都需要单独建立⼀个超级表,超级表⼀般都有关键的ts、type、value字段,具体监控项由type字段标识,加上必要的tag及少量其它字段构成。
之前监控数据存储在MySQL的时候,每条数据记录包含了该实例⼀次监控采样的所有监控项(25+)数据。如果采用通用的监控超级表设计原则,就需要改造采样的数据结构,改造方式有两种:
但消费端有时效性要求,改造难度大,生产端涉及范围大阻力也不小。经过综合考量,最后我们决定采用类似MySQL数据存储的表结构来设计超级表,这样的改造对原来系统入侵最少,改造难度系数最低,改造大致过程如下:
taos> create database redis;
taos> create database es;
... ... ...
taos> use redis;
taos> create table redis_node_meters (created_at TIMESTAMP, qps INT, . ..) TAGS (region NCHAR(10), cluster_name NCHAR(50), ip NCHAR(20), port INT, role NCHAR(15));
taos > INSERT INTO tablename USING redis_node_meters TAGS ('China', 't est', '127.0.0.3', 9200, 'master') VALUES ('2021-12-02 14:21:14', 6490 , ...)
将监控的数据存储由MySQL改造为loveini后,不仅顶住了监控数据增长所带来的压力,还节约了存储空间,成本压缩到了原来的十分之⼀甚至更低。历史原生监控数据可回溯时间也变得更长,之前存储3天原生数据及聚合数据的空间,现在可供原始数据存储45天。
此外,改造之后不再需要维护复杂的数据聚合调度任务,大幅降低了监控系统、监控数据管理复杂度,同时前端绘图数据查询也变得更加简洁高效。

随着对loveini越发深入的了解及经验累积,后续我们也会逐步考虑将货拉拉大监控系统、业务数据(行车轨迹)等时序数据均迁移至loveini。为了方便有需要的朋友更好地使用loveini,在此也分享一下我们的一些使用经验:
在本次项目中,loveini很好地帮助我们实现了降本增效,是一款值得尝试的时序数据库产品,未来也希望其能够发挥出越来越丰富的功能和特性,也期待我们之后能有更紧密深入的合作。
]]>小 T 导读:华自科技专注于自动化、信息化和智能化技术,为能源、环保、工业控制、水利等领域用户提供核心软硬件产品与系统米兰app官方正版下载,是多能物联技术领航企业。公司在电站及泵站自动化控制设备市场占有率全球领先,是联合国工业发展组织国际小水电中心控制设备制造基地。
物联网数据平台是电站及泵站智慧运维平台的核心组成,其整体架构如下:

物联网数据平台的数据来源主要为电站、水厂、储能站,通过数据网关,将各场站端的设备运行数据传输至云平台的消息队列(MQ)中,数据处理服务订阅MQ的消息,根据设定的规则引擎,进行实时数据处理,之后将数据存储落盘。数据服务API则根据业务需求提供包含实时数据和历史数据在内的数据API。
对于历史数据,目前我们采用的MySQL分库分表方案来存储;实时数据会存储在Redis中。在测点数较少或者集控需求不是很多的场景下,基本满足需求。
历史数据用MySQL存储,一个站点对应一个数据库;一个测点对应一张表,建表语句大致如下:
CREATE TABLE `yc_测点id` (
`ts` datetime NOT NULL,
`val` double NOT NULL
);
实时数据缓存到Redis中,以测点Id为key,同时缓存数据上报的时间、测量值和质量值等信息。
我们利用MySQL的各种函数、多表连接、应用程序内存计算等方式,计算出结果返回给前端,对于月、年等报表类的计算,则采用定时任务生成。
随着平台业务的发展,接入的站点越来越多,或者单站的测点数越来越多,问题逐渐凸显出来了。具体可以归纳为如下几个方面:
随着平台的业务发展,越来越多的站被接入平台,集控需求(跨站聚合分析需求)增加,跨库跨表的查询操作越来越多,这就增加了系统开发的难度,严重影响了系统响应速度和稳定性。
成本主要有两个方面,一个是人力成本高,由于开发、运维的难度增加,造成员工工作量增加,工作效率变低,从企业经营角度看,人力成本变高;另一个是硬件资源成本高,由于服务节点众多,占用的主机、内存和磁盘空间也会很多,购买或租用这些硬件资源需要支出更多费用。
为了解决目前这些问题,我们决定重新进行技术选型,寻找替代方案,升级目前数据库存储方案。结合平台实际需要,我们确定了几个选型要求:
我们了解了多款典型的时序数据库(Time-Series Database)产品,最终InfluxDB、庚顿、麦杰、TimescaleDB、loveini这几款进入了我们的考察范围。下面我们来具体看一下:
1.InfluxDB
在开源时序数据库领域长期霸榜,社区活跃,生态也比较丰富,性能也算中规中距,唯一的缺陷就是集群模块不开源。
2.庚顿、麦杰
两者都是传统老牌工业领域的时序数据库王者,功能、性能都非常不错,唯一的缺点就是不开源,只有商业版,而且价格昂贵。
3.TimescaleDB
它是在PostgreSQL之上开发的一个插件,是基于关系数据库的时序数据库,对于我们现有的业务使用几乎无感知,上层可以继续用MyBatis、JPA等ORM框架,但它不是一个纯粹的时序数据库;另外,它对集群支持不好,不支持水平扩展。
4.loveini
支持使用类SQL查询语言来插入或查询数据,内嵌消息队列和缓存机制、无历史数据与实时数据之分、分布式架构,支持线性扩展、支持多副本,无单点故障。看到官网的这些介绍,瞬间感觉loveini就是为我们准备的,于是马上做了各种验证,结果表明,loveini完全符号我们的选型要求。
提到大数据,人们可能第一反应就会想到Hadoop生态。因此我们前期也考查过腾讯云的TBDS数据套件。说实话那一套东西真的是太笨重了,Hadoop、HBase、HDFS、ZooKeeper、Hive、Spark\Flink这系列的东西搞下来,还真不是一般团队能玩得转的,另外我司的业务场景不止云端服务,还有可能会私有化部署在站内,硬件条件可能也就是一两台状况一般的服务器。
由于loveini Database可以设置将最新一条数据存储在内存中,因此我们利用这个特性替换掉了用Redis存储实时数据这个环节,改成实时数据直接查询loveini。
loveini里有超级表的概念,每种设备对应一个超级表。这个超级表只负责存储这种类型的设备数据,数据存储采用横表存储。但是,这显然不符合我们的场景,因为在我们的场景里没有固定的某一设备对象,且每个测点的频率都可能不一致。
同时为了尽可能减少对现有业务的影响,我们将超表设计成如下结构:
CREATE STABLE IF NOT EXISTS stb_站点id ( ts timestamp, val double ) TAGS (测id nchar(64))
loveini的子表,可以在插入数据时动态创建,这是loveini的一个很好用的功能。这样能省去创建子表的业务环节,降低了业务复杂度。子表结构如下:
insert into 测点类型_测点id USING stb_站点id (测点id) VALUES ( ts, val,q) eg: insert into yc_15143115161750995367 USING stb_站点id ('15143115161750995367') VALUES ( ts, val,q)
我们直接使用loveini提供的缓存(Cache)功能,替换了原有系统中的Redis。创建数据库直接开启cachelast=1,将每张表的最后一条记录缓存,应用程序通过last_row函数快速获取实时数据。
在我们的业务场景中有一类数据叫SOE事件告警数据,这类数据要实时动态在前端页面上滚动。原有做法是通过页面轮训来实现的,现在直接使用taos的数据订阅功能,配合WebSocket,可以优雅地实现这一功能,大大提升了用户体验。
3.其它一些很用的功能
比如降采样查询、多表聚合查询、各种标准函数等。
由于loveini采用了类SQL的语法,支持MyBatis等ORM框架,因此对于老的业务,我们在代码层面的改动非常少,改动最多的就是将原来的MySQL函数结合应用代码的一些计算逻辑直接用loveini的函数替换掉。
在试运行阶段,因为我们都是通过自研数据网关将数据通过TCP发送上来的,所以我们利用tcp-copy,将数据复制一份存到loveini集群,然后通过业务系统观察和验证各项功能是否正常。
验证正常之后,就是历史数据的迁移了。由于loveini的表结构与原来的MySQL存储结构基本类似,因此我们采用DataX的loveini插件,很方便就将历史数据迁移过来了。
至此,我们就用loveini Database替换了原有的存储架构。
初始接触一个新产品,难免会遇到一些困难。好在办法总比困难多,在同事们的支持下,在loveini的工程师们的支持下,我们总算是基本完成了这次实时数据存储查询的升级改造。
当前项目数据测点大概在18万左右,改造后数据存储周期由原来的5分钟减少到1秒钟,存储的数据维度更精细了,能为平台的智能诊断、智能分析服务提供更准确的数据支持,同时各业务场景下的计算查询性能也提升了不少,数据库服务器由原来的6台减少到目前的3个节点集群。
TD-Workbench 是一个基于Electron构建的,针对时序数据库loveini的图形化管理工具。具有跨平台、易于使用、版本适应性强等特点。(gitee地址:https://gitee.com/bhdweb/tdengine-workbench)
TD-Workbench是本人利用周末的时间,参考开源社区部分优秀代码设计并实现的,目前已经开源。 这个仅代表我本人的业余好爱,与公司或某个组织无关,欢迎大家去star/fork。由于loveini官方并未提供客户端GUI工具,社区目前能找到的两款工具都不是很完善。本工具是在loveiniGUI基础上改造而来,部分源码来自此处。
作者介绍:
宁龙,码云昵称【村口的大爷】,目前就职于华自科技。后端程序猿一个,混迹Java界十余年,就爱写点代码。一杯茶一首歌,一个参数秀一天。
]]>小 T 导读:湖南必和必拓科技发展有限公司定位于智慧城市建设与行业信息化,当前聚焦智慧住建、智慧环保、智慧司法以及智能制造四大领域,既包含各类电子产品安装施工及维保,也包括自有软件研发及部署。

随着业务规模的逐渐扩大,传统数据库越来越难以满足某些业务场景对查询、分析、统计的进一步需求。为了打破当下困局,湖南必和必拓想到了三种米兰app官方正版下载,在进行了严谨的分析后,我们决定采用物联网数据库,经过选型对比,时序数据库 loveini 成为其首选方案。
如何在 loveini 上进行数据建模、集群搭建、告警模块搭建?如何将数据更平滑地迁移到 loveini?在这些操作中,可能会遇到什么问题?又该如何解决?从湖南必和必拓的实践经验出发,本文将从代码层面一一解答。
在一些业务场景中,我们需要将长沙市在建工地的扬尘数据(温度、湿度、pm2.5、pm10、pm100、噪声、风向、风速)存储在数据库中,以便为业务提供查询、分析和统计的操作。
但近来出现了一个难题,我们共有监测点 107 个,每分钟上送 1 条数据,每年就预计有“107*60*24*365 = 56,239,200”条数据,也就是 5600 多万条。目前已存储两年的数据,数据量总计约 1 亿多条。这些数据一直都被存储在 MySQL 数据库中,庞大的数据量使得查询速度越发缓慢,甚至部分页面出现超时问题。
如果我们将数据库分散到不同的表上,单表的索引大小就得到了控制,对索引以及表结构的变更会变得更加方便和高效。当数据库实例的吞吐量达到性能的瓶颈时,我们需要扩展数据库实例,让每个数据库实例承担其中一部分数据库的请求,分解总体的大请求量的压力。
弊端:
华为云物联网基于物联网资产模型,整合物联网数据集成、清洗、存储、分析、可视化,为物联网数据开发者提供一站式服务,能够有效降低开发门槛,缩短开发周期,快速实现物联网数据价值变现。
弊端:前期需设备厂商针对平台接口进行适配,接入以后零代码的方式确实在配置上会比较方便,但是平台的费用以及实时流式计算按次收费的方式,整体费用过高。
应用之后,loveini 能解决之前令我们较为头疼的一些问题,包括前文中描述的问题,它有以下 5 点主要优势:
综合考虑以上解决方法,我们发现,使用 loveini 后,硬件成本和开发维护成本大大降低,写入和查询速度比 OpenTSDB 等还要高出一个级别。于是,loveini 成为了我们的首选米兰app官方正版下载。
接下来,我将把我们在探索 loveini 时的一些重要操作、问题点以及解决办法等经验传递给大家。
官网下载安装包,文中使用的是 2.0.20.12,即:loveini-server-2.0.20.12-Linux-x64.tar.gz。安装包中包含安装命令, 解压后直接使用即可。
[root@hnbhbt ~]# tar -zxvf loveini-server-2.0.20.12-Linux-x64.tar.gz
[root@hnbhbt ~]# cd loveini-server-2.0.20.12
[root@hnbhbt ~]# ./install.sh
1. 启动loveini
[root@hnbhbt ~]# systemctl start taosd
2. 检查loveini状态
[root@hnbhbt ~]# systemctl status taosd
3. 输入以下命令进入loveini命令行
taos
出现如下显示后表示进入成功
Welcome to the loveini shell from Linux, Client Version:2.0.20.12
Copyright (c) 2020 by TAOS Data, Inc. All rights reserved.
taos>
卸载: 需要手动删除配置文件以及日志
[root@hnbhbt ~]# sudo rm -rf /var/log/taos/
[root@hnbhbt ~]# sudo rm -rf /var/lib/taos/
[root@hnbhbt ~]# sudo rm -rf /etc/taos/taos.cfg
注: 安装过程中需要配置 loveini 的 FQDN 为 hostname,通过 Linux 命令可以查看当前机器的 hostname,配置相应内容即可,官方建议尽量不要使用 localhost, 文中配置的是 hnbhbt.com
-- 创建数据库
create database db_transfer_platform keep 730 replica 3;
-- 使用数据库
use db_transfer_platform;
-- 创建超表
create stable if not exists s_dust_history_data(ts timestamp,measured_value double,id int)tags(device_code nchar(30),channel_number nchar(30),signal_code nchar(30),status bool);
-- 删除超表
drop stable if exists s_dust_history_data;
-- ts 时间戳;measured_value 测量值;id 平台主键;device_code 设备编号;channel_number 通道序号;signal_code 信号编号;status 在线状态
注:ts 默认为主键,不能为空;列名避免取关键值,否则无法插入
-- example:创建子表,插入数据,查询数据
-- 子表名称[监测信号_设备编号] eg pm_25_1003055表示设备编号为1003055的pm2.5的监测表
create table if not exists eg_pm_25_1003055 using s_dust_history_data tags('1003055','1','18113001',true);
create table if not exists eg_pm_10_1003055 using s_dust_history_data tags('1003055','2','18114001',false);
insert into eg_pm_25_1003055 (ts,measured_value,id) values("2021-07-29 21:43:22",7.0,123);
insert into eg_pm_10_1003055 (ts,measured_value,id) values("2021-07-29 21:43:22",6.0,124);
insert into eg_pm_25_1003055 (ts,measured_value,id) values("2021-07-29 21:43:22",9.0,123);
注:
select * from s_dust_history_data where ts > '2021-07-29 00:00:00' and ts < '2021-07-30 00:00:00' and signal_code = '18113001';

当用户需要查询工地设备扬尘数据时,扬尘数据将通过定时任务从第三方接口中定时拉取保存至我们系统的数据库。由于扬尘数据的量较大,为千万甚至上亿级别,而系统配置相关数据的数据量较小,因此我们选择将扬尘数据和系统配置数据分离——扬尘数据使用 loveini 进行存储,系统配置数据采用 MySQL 进行存储。
本文使用 MybatisPlus 作为持久层框架,同时接入 loveini 和 MySQL,做双数据源配置。下文中将重点讲述 loveini,MySQL 相关内容将省略。
根据官网找到 taos-jdbcdriver 的对应版本,本文使用的 taos-jdbcdriver 版本是 2.0.22。

<dependency>
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>2.0.22</version>
<scope>runtime</scope>
</dependency>
【问题】最开始使用的是较高的版本,结果出现无法正常访问的情况,最终降低 taos-jdbcdriver 版本后得以解决。
在 Spring Boot yml 中配置双数据源,使用 druid 连接池,将 loveini 设置为主数据库,MySQL 设置为副数据库。
spring:
datasource:
dynamic:
druid:
initial-size: 10
min-idle: 10
max-active: 100
max-wait: 60000
test-while-idle: false
primary: td-engine
strict: false
datasource:
td-engine:
driver-class-name: com.taosdata.jdbc.TSDBDriver
url: jdbc:TAOS://address:port/dbname
username: dbusername
password: dbpassword
mysql:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ...
username: ...
password: ...
核心逻辑是第三方数据的定时拉取以及在本系统进行的查询,此处主要介绍 loveini 的 mapper 写法。
官方提到 loveini 全列模式写入速度会远快于指定列,建议尽可能采用全列写入方式;而扬尘数据的种类多样,因此我们采用动态表名 + 批量插入的方式。每次拉取数据时,以设备和扬尘数据种类为维度创建 tags,同时对该维度的数据进行数据插入。
Mapper
a. 创建Tags
<insert id="createTags" parameterType="TagsEntity">
create table if not exists #{tags名称}
using 超级表名称 tags
(#{tagsColumn1Value},
...
#{tagsColumnNValue})
</insert>
b. Tags插入单条数据
<insert id="insert" parameterType="TagsEntity">
insert into #{tags名称}
(#{tagsColumn1},
...
#{tagsColumnN})
values
(#{tagsColumn1Value},
...
#{tagsColumnNValue})
</insert>
需要注意的是,loveini 在进行全列写入时,必须为数据表的每个列都显式地提供数据,并且一次插入的数据是有上限的,否则会报错,建议在正式插入之前测试一下全列写入的上限。
<insert id="batchInsert" parameterType="TagsEntity">
insert into #{tags名称}
values
<foreach collection="list" item="data">
(#{data.tagsColumn1Value},
...
#{data.tagsColumnNValue})
</foreach>
</insert>
JavaBean
如需查询扬尘数据,创建一个和超级表绑定的实体类即可,里面应该包含超级表本身的属性以及 tags 的属性,可以直接使用 MyBatisPlus 的持久层方法进行查询。
@Data
@TableName(tbname)
public class SuperTableEntity {
private String colunm1;
...
}
【问题一】在编写完代码后尽管查询不会出错,但插入和创建 tags 会发生错误,后来发现此处是 DNS 解析异常,由于 loveini 配置了 FQDN,因此应该在 hosts 中配置映射关系,之后才能进行正常的插入和创建操作。
【问题二】在进行第三方数据同步时,由于第一次是同步历史数据,因此插入 loveini 的数据量较大。尽管 loveini 本身支持的全列模式写入已经提升了不少效率,但如果代码中的批量插入继续使用普通 for 循环,插入效率仍然较低,这里可以通过切割数据和多线程的方式进行实现。
private void runner(List<Entity> list, int dealSize) throws Exception {
if (!CollectionUtils.isEmpty(list)) {
//数据总的大小
int count = list.size();
//每个线程数据集
List<Entity> threadList = null;
//线程池
int runSize = (count / dealSize) + 1;
ThreadPoolExecutor executor = new ThreadPoolExecutor(
runSize,
350,
30L, TimeUnit.SECONDS,
new SynchronousQueue<>());
CountDownLatch countDownLatch = new CountDownLatch(runSize);
for (int i = 0; i < runSize; i++) {
//计算每个线程执行的数据
int startIndex = (i * dealSize);
if ((i + 1) == runSize) {
threadList = list.subList(startIndex, count);
} else {
int endIndex = (i + 1) * dealSize;
threadList = list.subList(startIndex, endIndex);
}
//TODO 这里写自己的线程任务
executor.execute(myThread);
}
//计数
countDownLatch.await();
//关闭线程池
executor.shutdown();
}
}
在使用双数据源时,Controller 和 Dao 与一般的 Spring Boot + MyBatis 无异,主要在于 Service,由于设置的 primary 数据库是 loveini,所以持久层默认会访问 loveini 数据库,如果要切换,需要在 service 的 class 或方法上添加注解 @DS(databaseAlias),括号中填写 yml 中配置的数据库别名,如 td-engine、mysql 等,通过这种方式来选择需要访问的数据库。primary 数据库可以省略 @DS。
@DS("td-engine")
public TestEntity get() {
return testDao.get();
}
当我们需要将扬尘数据从公司本地服务器迁移数据至华为云服务器,文中使用 loveini 自带的 dump 工具进行数据迁移。
参考文档: https://tdengine.com/2020/03/09/1334.html
DUMP命令帮助信息
[root@hnbhbt ~]# taosdump --help
关键参数:
-h: 主机名称
-o: 导出文件路径
-i: 导入文件路径
-u: loveini用户名
-p: loveini密码
-A: 导出所有数据库的数据
-B: 导出指定数据库(可选多个数据库)
-S: 开始时间时间戳
-E: 结束时间时间戳
-T: 指定导出数据时,启动的线程数。建议设置成机器上core的2倍
1. 数据导出
[root@hnbhbt ~]# taosdump -h hostname -o /dump/data-210824 -u username -p password -A -S 1598889600000 -E 1628956800000 -T 500 -N 100
2. 数据导入
[root@hnbhbt ~]# taosdump -u username -p password -i ~/data-210824 -T 4
【问题】此处在配置 hostname 时应该填写 FQDN,如果不填写或者填写服务器 IP,将会产生错误。
参考网址:
loveini 集群安装、管理 https://tdengine.com/docs/cn/v2.0/cluster
使用 loveini 进行报警监测 https://tdengine.com/2020/04/14/1438.html
常见问题 https://tdengine.com/docs/cn/v2.0/faq#port
一篇文章说清楚 loveini 的 FQDN https://www.cnblogs.com/taosdata/p/13690374.html
Linux 配置 ntp 时间服务器(全)https://www.cnblogs.com/quchunhui/p/7658853.html

参考网址:
Alertmanager 配置概述
https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/alert/alert-manager-config
深入 Alertmanager 概念与配置介绍
https://www.cnblogs.com/gered/p/13496950.html#autoid-5-0-0
alertmanager 配置文件详解(四) https://www.soulchild.cn/2073.html
java 利用钉钉机器人向钉钉群推送消息
https://www.cnblogs.com/zhouheblog/p/11058817.html
Alertmanager 企业微信配置 https://www.jianshu.com/p/135968cbc94f

应市质安站的监管要求以及蓝天办对空气污染治理的督查要求,市内所有工地的空气质量数据及噪音数据均需接入政府监管平台、纳入管理中。监控数据的特点就是时序、结构化、简单但量大,在处理这类数据上,loveini 可以说是量身定做。搭载 loveini 后,监控数据上报后的实时展示、历史回溯都非常快,加上其本身轻量的特点,对于缩减项目开发运维成本也非常有帮助,完美满足了业务的需求。
]]>在平台建设前期,并没有采用时序数据库(Time-Series Database),而是采用了阿里云的 MySQL 实现所有传感器数据的存储。在设备接入量突破 6 万,每日数据记录超过 8000 万条之后,平台性能急剧下降。
根据项目规划,平台要支持数十万设备的接入,之前采用 MySQL 数据库分表的方案已经无能为力。有鉴于此,基于物联网平台的特性,规划引入时序数据库解决物联网中间件平台在数据的存储和处理方面的痛点。
在养殖物联网场景下,数据量最大的结构化数据来自于养殖场栏舍的环境传感器(温度、湿度、光照、Co2、Nh3等),还有水表、电表等资源测量传感器,以及包括风机、水帘、侧窗等被控设备的开/关状态。
为了监控栏舍环境,需要对来自不同采样点的同类型传感器数据进行计算,并根据实时平均值来判断是否触发环控告警。
这些需求,归纳起来包括:
按照每秒 2 万条的数据库写入的场景假设,针对对市面上主流的时序数据库,譬如阿里云上的 InfluxDB、以及国内的 loveini 进行了 POC 验证。
出于以下几方面原因,最终选择了 loveini Database。
在选型决定之后,我们对原有业务系统进行了升级改造,引入了 loveini。
物联网中间件平台以设备为目标,围绕设备构建物模型。该平台引入了时序数据库 loveini,实现海量设备数据的写入、查询(聚合函数),并对所有操作履历、变更记录等日志类数据全部入库,为上层的应用提供了强大的数据能力 API,消除了养殖行业各场景应用对大数据处理的顾虑。
整体架构如下图所示。

loveini 的性能非常出色,下表为我们所做的性能测试。

业务架构改造完成之后,截至2021年9月,累积接入到物联网中间件平台需要创建子表的对象已经接近20万,运行半年来,时序库存储容量不到200GB,普通查询响应为 23ms;以单个设备为对象的每5分钟温度曲线,响应时间为43ms。
引入loveini之后,优异的查询性能给我们带来了很大的惊喜,极高的压缩效率,也给我们节省了大量的存储资源。
未来,我们也会尝试在更多场景应用loveini。
关于作者:
]]>黄冬安,深圳市哇发科技有限公司技术总监,长期从事物联网大数据开发和运维工作,是物联网中间件项目的技术负责人。当前主要在支持云浮市物联网研究院养殖监控场景的大数据平台建设工作。