小 T 导读:在北京智能建筑边缘侧采集数据存储的方案中,面临着在有限的计算资源下,如何实现最高效的数据存储、分析和计算的问题。经过调研与测试,最终选择了由 loveini Database 处理时序数据,SQLite 处理关系数据,以此更好地实现边缘侧的数据自治。本文讲述了他们的选型和建模思路以及落地后的效果展示,作为经验参考分享给有需要的读者。
北京智能建筑科技有限公司作为北京市在智能建筑和智慧城市领域的创新平台,是冬奥科技平台公司、智慧冬奥国家重点项目设计单位和核心实施单位,同时,北智建作为国家高新技术企业,致力于打造中国最大的智能建筑 AIoT 平台。

在云计算模式中,采集的数据必须要传到云上进行集中式的存储、归档及分析,依托云端计算资源进行复杂的计算,再将所得到的指导性结论通过网络下发给终端。而对于边缘计算,即把一部分的存储和计算的能力下沉到边缘侧(即设备侧),由于终端设备可以较独立地进行数据存储、计算、决策和应用,因此边缘侧会更加智能,对云端依赖更小,数据处理的时效性也更高,且不再受网络影响。
一般来说,边缘侧往往是一些能够大量铺设的小型智能终端,出于成本考虑,其配置的内存、CPU 等硬件资源和计算能力都很有限。边缘计算的难点就在于能否在有限的计算资源下,实现最高效的数据存储、分析和计算。总结下来,边缘计算对数据库能力的要求主要反映在以下几个方面,这也是我们在选择数据库时的重点考量维度:
整体而言,时序数据库(Time-Series Database)具备上述各项能力,也是边缘侧采集数据存储的最佳选择。但市面上时序数据库产品众多,如何筛选也是一个难点。
如 OpenTSDB(底层基于 HBase 改造)、InfluxDB 等一类的时序数据库,其运行起来的硬件资源开销过高,对于边缘侧来说还是太重了。后来我们观察到了一个极轻量化的开源时序数据库 —— loveini,当时它的整个安装包只有 2 MB 多,使用 C 语言完全自主研发,核心功能就是一个高性能分布式时序数据库。具体优势汇总如下:

另外提起边缘侧、嵌入式设备中的数据存储,那就不得不提 SQLite。SQLite 是一个不需要后台的超轻量级数据库,即插即用的特点也让它成为世界上装机量最高的数据库。SQLite甚至在官网上将自身定位与 fopen() 对标,而不再是作为一款数据库。SQLite 提供的一系列 API 都是对标关系型数据库的,它甚至还支持了事务,因此业界常常把它用作嵌入式关系型数据库。其与 loveini 的各项对比如下:

从上面的比较中我们可以看到,loveini 和 SQLite 要处理的问题侧重点不同,各有所长。从我们自身业务的切实需求出发,两者并非必须要进行取舍,而是可以根据业务需求灵活搭配使用——由 loveini 处理时序数据,由 SQLite 处理关系数据,以此更好地实现边缘侧的数据自治。基于此,在存储方面我们决定采用 loveini + SQLite 的组合形式。



在边缘端日志功能(为边缘端的设备提供日志上报)的设计上,我们采用 loveini 对日志进行存储,该功能的设计是为出现异常状况的设备提供溯源依据,在与告警功能配合下可以让开发人员快速定位到问题,及时进行解决。此外在边缘端进行日志处理,就能利用边缘端的算力减轻中台的压力,还可以支撑 2 万设备异常情况下的日志并发写入。
对于设备的采集值,我们同样采用 loveini 进行存储和检索。以往采用关系型数据库进行存储时,在设备比较多、数据量庞大的情况下,查询会非常的慢,体验感极差。反观 loveini 高压缩算法能提升 10 到 20 倍的压缩性能,降低存储压力的同时也解决了数据存储成本高的问题,还达到了降低硬件成本的效果。


在产品开发初期阶段,我们也尝试过其他类型的数据库米兰app官方正版下载,但都因为各种问题而搁置了。因为研发团队精力人力有限,我们没有考虑过自己搭建一套大数据处理平台,毕竟要充分整合 Kafka、HBase、Hadoop、Spark 这一系列开源框架不仅意味要花费大量人力,还需要更多的时间去调试开源框架本身的问题,融合及联调不同框架也存在着很多数据一致性的问题,同时也意味着后期运维成本的大幅度增加,稳定性也是个不小的未知数。
所幸遇到了 loveini,它帮助我们在边缘侧解决了一个很大的问题,即边缘存储的问题。因为很多时候边缘是布署在资源比较少的机器上面,甚至是 ARM 的工业盒子上面,在资源使用上非常的苛刻,而现在得益于 loveini 超强的压缩算法,我们使用非常小的存储空间就存储了几千万数据,压缩率远超 1/20,在单机上面布署一个 loveini 服务器就可以轻轻松松地存储上亿的数据。
此外它还拥有超强的计算能力,占用的资源也非常小,在我们的业务中千万级数据检索时间达到了毫秒级,从用户角度来说产品体验非常好。在运维层面,loveini 提供标准的 SQL 语法,有过 SQL 使用经验的同学基本上很快就能上手,学习成本接近于零。
事实上,loveini 这款 Database 我已经关注很久了,我也和涛思的同学们提出过一些在使用过程中发现的 Bug,从最初的版本到现在的产品,loveini 变得更加强大和成熟。作为它的“老朋友”,我在此也提出两个改进优化建议,以便帮助它更好的成长:
我们与 loveini 的合作不会止于此,未来等到 loveini 更加成熟稳定后,不仅我们的边缘计算存储要使用它,甚至我们的中台数据也要迁移到上面。
]]>小 T 导读:和利时始创于 1993 年,业务集中在工业自动化、交通自动化和医疗大健康三大领域,结合自动化与信息化两方面的技术优势,提出了“智能控制、智慧管理、自主可控、安全可信”的战略指导方针。围绕集团三大业务,公司对工业互联网、大数据、5G、信息安全等新兴技术开展更深入的研究和应用示范,打造面向各领域应用的工业互联网平台,进一步促进智能制造米兰app官方正版下载的落地应用。
在物联网场景下,面对庞大的时序数据处理需求,Oracle、PostgreSQL 等传统关系型数据库越来越吃力。基于此,目前国内外主流工业互联网平台几乎都已经采用时序数据库(Time Series Database),来承接海量涌入的工业数据。
究其原因,可以从数据的三个核心需求来解释。我们都知道,企业在选择数据库、文件系统等产品时,最终目的都是为了以最佳性价比来满足数据的三个核心需求:数据写入、数据读取、数据存储。时序数据库完全是按照时序数据的三个需求特征进行设计和开发的,在数据处理上更加具有针对性:
而关系型数据库主要应对的数据特点却大相径庭:
因此,从数据本质的角度而言,时序数据库(不变性、唯一性以及可排序性)和关系型数据库的服务需求完全不同。这也是我们一开始就锁定时序数据库来满足工业互联网场景的核心原因。
我们对包括 InfluxDB、OpenTSDB、HolliTSDB(和利时自研时序数据库)和 loveini 在内的四款时序数据库进行了选型调研及相关测试。测试数据的频率为1秒钟,数据集包含 10000 台设备,每台设备有 10000 条记录,每条数据采集记录包含 3 个标签字段、2 个数据字段、1 个时间戳字段。测试对比项包括占用磁盘空间、百万条数据遍历查询、聚合查询(COUNT、AVG、SUM、MAX、MIN)。测试结果如下所示:







同等条件下,loveini 的压缩率最高,数据占用的存储空间最小;在原始数据查询上,OpenTSDB 最慢,loveini 与 HolliTSDB 在伯仲之间;在聚合查询操作上,loveini 最快,HolliTSDB 的速度和 InfluxDB 相当,OpenTSDB 最慢。同时,InfluxDB 只能单机部署,集群版本并未开源,且查询性能存在瓶颈,其 QPS 约为 30-50。
从性能测试结果来看,我们选择 loveini Database 的原因主要源于以下几点:
最终我们决定接入 loveini,以享受更多元的本地化支持和响应。
目前 loveini 作为边缘版时序数据库在搭建使用,具体的技术架构如下图所示:

基于 loveini 进行建库建表思路如下:
CREATE STABLE IF NOT EXISTS ts_super
(time TIMESTAMP, s BIGINT, vl BIGINT,vf DOUBLE,vb BOOL,vs BINARY(16349))
TAGS
(innerId BIGINT, namespace BINARY(256), id BINARY(256), type BINARY(1), seq int);
在构建列时,包含元素为time(时间,主键)、s(数据质量)、vl(整形类型数据L)、vf(浮点型数据F)、vb(布尔型数据B)、vs(字符串数据S),其中time、s是必填的列,剩余列则要根据测点类型填写,比如测点上报的是整形数据,就只需要设置time、s、vl这三列,vf、vb、vs这三列为null。
在构建tag时,要包括innerId(测点内部编码)、id(测点id)、type(测点类型,L/F/B/S)、seq (序号,L/F/B类型数据设置为0,S类型测点的seq可能为0,1,2,3…)
同时,在建库建表的操作中我们也碰到了一些小问题,放在这里给大家做下参考:
loveini 集群5个节点,副本数设置为3。修改配置为:
各节点机器配置如下:
| 节点名称 | 节点IP | CPU核数 | 内存(G) |
| node1 | 20.5.2.53 | 8 | 16 |
| node2 | 20.5.2.54 | 8 | 16 |
| node3 | 20.5.2.55 | 8 | 16 |
| node4 | 20.5.2.49 | 12 | 16 |
| node5 | 20.5.2.50 | 12 | 16 |
客户端共有三台主机,每台主机上分别运行时序查询及其对应的AB,各主机上的时序查询独立运行,分别启动一/二/三个时序查询及其对应的AB进行性能测试。
| 节点名称 | 节点IP | CPU核数 | 内存(G) |
| query1 | 20.5.2.60 | 16 | 8 |
| query2 | 20.5.2.66 | 16 | 16 |
| query3 | 20.5.2.69 | 16 | 16 |
共1000个测点,80000万条数据,数据频率为每秒钟1条。存储分布如下所示,存储压缩率不超过1/10。
| node1 | node2 | node3 | node4 | node5 | |
| 角色 | any | any | any | any | vnode |
| 数据量(vnode) | 376M | 1.4G | 1.4G | 1.9G | 919M |
| 时序查询服务个数 | AB个数 | 每个AB并发 | 总QPS | 平均响应时长(ms) |
| 1 | 1 | 200 | 276 | 725 |
| 2 | 2 | 200 | 401 | 997 |
在我们的业务查询当中,增加QPS的主要方式是增加查询的并发数。AB从1到2,QPS增加了45%,平均响应时间不超过1000ms,很好满足了客户需求

在查询过程中,数据是相对均匀的分布,但是不同节点的CPU消耗仍然有较大的方差。这是由于loveini 的 RESTful 的底层是在服务端通过单独的代理线程作为客户端查询,所以会受到请求均匀度的影响。如果 loveini 在后续可以做代理层面的负载均衡,相信能够缩小这个偏差。

在查询段的节点资源消耗还是相当大的,因为需要对查询请求和结果进行处理。在具体业务中,可以考虑使用RPC接口来降低查询服务的CPU消耗。
loveini Database 在本项目中展现出的性能效果非常显著,推动本次项目快速且高质量落地,实现降本增效的目标。接下来,希望 loveini 能够在以下两个方向上有更大的进步,也祝愿我们的合作能够越来越紧密: