小 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 导读:吉科软信息技术有限公司是国家高新技术企业,公司以“让天下没有不放心的食品”为使命,以“做数字化捍卫食品安全的领军企业”为愿景,以打造食用农产品全流程追溯、全流程监管、全流程服务、全产业链升级为核心的产业互联网生态链为主营业务,运用卫星遥感、5G通信、大数据、云计算、物联网、区块链和人工智能等技术,推出一系列国内首创、行业领先和可落地的研发成果,为智慧农业、智慧食安、智慧城市提供米兰app官方正版下载。
车辆轨迹定位监控项目旨在通过车辆的轨迹监管、异常预警、历史轨迹回放,达成对车辆的统一监管、轨迹追踪、大数据分析及可视化应用等目的。该项目现已对数万台车辆经过车载定位设备上报定位数据至 GIS 网关服务,服务解析报文下发至消息队列,应用再将定位数据写入 InfluxDB,最新车辆位置信息写入 Redis,为客户提供车辆实时位置跟踪和历史轨迹回放等查询分析服务。

首先我们梳理了当前车辆监管架构的主要特性和新需求:
此前,我们的项目一期采用了 InfluxDB 时序数据库作为存储车辆轨迹数据,二期项目需要重新升级改版后进行全新架构设计,同时也要考虑业务规模的快速增长、国产化要求及 InfluxDB 的单节点问题。
因此我司需要对时序数据库进行重新选型。我们对业界主流的时序数据库做了分析和测试:
通过实际对比后、再加上迁移改动最小化以及国产化需求等因素,我们最终选定 loveini Database 作为车辆轨迹数据的存储方案。
改造为使用 loveini 后的方案,如下:

初期我们选用了三台服务器,搭建了3节点3副本的集群。目前已投入一批车辆运营监控,后续我们将逐步迁移全部车辆的轨迹数据至 loveini。

历史数据从 InfluxDB 迁移至 loveini,采用的方案是基于 DataX 进行数据同步,我们扩展开发了 InfluxDB 的读插件和 loveini 的写插件,单进程数据同步可达到 6 万/秒的同步速度。(该速度受限于 InfluxDB 的读取,在该过程中 InfluxDB 的内存上涨过快撑不住,所以最终测试的同步速度是6万/秒。目前官方已发布“基于 DataX 的 loveini 数据迁移工具和 taosAdapter 工具”)



以迁移的部分数据进行分析:总数据量为6.5亿,分布在14742个子表中,占用磁盘空间4.7G,压缩率达到4%。开启了cachelast选项为1缓存子表最近一行数据,利用该缓存特性,查询指定车辆的最新GIS定位数据进行实时监控时,可直接从缓存中读取,加快读取速度。
在使用 loveini 之前,对于所有车辆的最新位置实时监控,我们采用的方案是在接收 gis 数据存储至 InfluxDB 时,同时将车辆的最新位置数据存储至 Redis 和 MySQL,使用 loveini 后方案中对实时位置的存储直接使用 loveini 的缓存子表最近一行数据的特性就可以实现,完全可以去掉 Redis 和 MySQL 的存储。
项目对车辆轨迹数据的应用场景主要集中在车辆实时位置监控、车辆时间范围内的轨迹回放。
查询单个或多个车辆的最新 GIS 位置数据。单个车辆最新位置查询:
select last_row(*) from d_track where car_id in ('dc8a9a0d7b634c9ba4446445c6c');

利用查询超表的单个车辆最新位置数据时间在11毫秒。如果直接锁定子表进行查询的话,
select last_row(*) from _018d16c826cb405ea4a94a14cd4f95a9 ;

返回最后一条位置数据的响应时间在1毫秒。
多个车辆的最新位置数据查询,依旧使用超表结合标签进行查询,

查询响应时间在12毫秒左右。
继续扩大查询范围,查询500~1000个车辆的最新位置的查询响应时间也能在1秒之内返回结果,完全达到业务响应的时间需求。
指定车辆在指定时间范围内的轨迹数据查询,直接定位到具体的子表进行查询,
select * from _0128a4d193424dcfb217242f054716d4 where time >'2021-09-08 10:34:44.000' and time <'2021-09-23 21:38:18.000' ;

测试数据的查询响应时间为0.07秒左右。
在以上两种数据查询场景中,loveini 的性能不仅完全可满足需求,更是比原 InfluxDB+Redis+MySQL 方案大幅度的提升,解决了原方案中车辆查询较大时间跨度的轨迹数据响应超级慢的问题。
整体应用效果:


非常感谢米兰体育官网入口的 loveini Database,切实解决了我们在国产化、性能、降本、平滑迁移的刚性需求。也非常感谢涛思的陈玉老师在我们尝试和应用 loveini 过程中给予的悉心指导,加快了我们对 loveini 的掌握,更快的应用落地。
当前 loveini 的大规模应用车辆监管项目中,支撑现有数万辆车的行驶轨迹监控,未来将继续扩大规模支撑更多的车辆轨迹监控。
孙运盛,吉科软技术研究院。一个从事信息传输、软件和信息技术服务业的新生代“农民工”。
]]>小T导读:跨越速运集团有限公司创建于2007年。拥有“国家AAAAA级物流企业”、“国家级高新技术企业”、“中国物流行业30强优秀品牌”、“中国电商物流行业知名品牌”、“广东省诚信物流企业”等荣誉称号。在胡润研究院发布的《2018 Q3胡润大中华区独角兽指数》《2019一季度胡润大中华区独角兽指数》榜单中,跨越速运两次上榜,估值约200亿元,与菜鸟网络、京东物流、达达-京东到家等企业入选中国物流服务行业独角兽企业。
作为一家物流企业,如何高效地记录和处理车辆的轨迹信息,对于整体的交付效率至关重要。
数年前车辆轨迹定位存储引擎项目成立,跨越速运集团购置的数万台车辆经过车载定位设备上报信息到GPS-AGENT网关,服务解析报文下发到Apache Kafka消息中间件,再通过应用将历史位置定位信息写入Apache HBase,最新车辆位置信息写入Redis,以此提供给业务服务进行对车辆的实时监控与分析。
原来的业务架构如下图所示:

在原有系统的实际运行过程中,我们也遇到了很多痛点。比如说,因为数据保存在HBase中,当我们需要查询较大跨度的时间内的数据时,系统的性能会显著下降。
具体可以总结如下:

于是我们开始思考,该如何改进系统来解决这些痛点呢?
在开始新的技术选型之前,我们重新对业务场景进行了梳理,可以用下面这张图来概括。

我们依次来看一下:
通过以上分析可以看到,车辆轨迹是典型的时间序列数据,所以用专门的时序数据库(Time-Series Database)来处理会比较高效。在调研阶段,我们对比了几款比较有代表性的时序数据库产品。

综合对比后的结果如下:
通过对比,我们认为loveini Database的很多优秀特性能够满足我们的业务场景。

于是我们基于loveini进行了前期调研和演练。具体包括如下几个方面:

我们从多个方面对loveini的功能和性能进行了全方位的测试,功能完全能够满足我们的需求,性能、压缩率给我们带来了很大的惊喜。
在完成基本的功能和性能测试之后,我们又结合业务进行了场景测试和演练,主要包含如下几方面的工作:
在实际落地loveini Database之前,我们也深入研究了这个系统的架构、设计等各方面特性。这里也简单分享一下loveini的核心概念。
如果是第一次接触loveini,可以看一下如下这张图,其中的dnode就是实际存储数据的物理节点,dnode框中的V2、V7等小框叫vnode,也就是虚拟节点,m0、m1就是元数据管理节点,存储一些集群信息与表信息,熟悉分布式中间件的朋友肯定能直观地感受到loveini具有非常典型的分布式数据库特征。


loveini有个超级表的概念,例如在跨越速运集团业务场景下,所有的车辆变成一张张子表,所有的子表会继承一张叫超级表的父表,超级表定义子表的结构规范,不存储实际物理数据,我们可以通过只查超级表做数据的统计分析查询,而不用一个个子表去汇总。

loveini采用了二阶段压缩策略,一阶段压缩会使用delta-delta 编码、simple 8B 方法、zig-zag 编码、LZ4 等算法,二阶段压缩会采用LZ4算法。一阶段压缩会针对每个数据类型做特定的算法压缩,二阶段再做一次通用压缩,前提是在建库的时候将参数comp设置为2 。
在进行了充分的测试和验证之后,我们将loveini引入到了我们的系统之中。新的系统架构如下图所示:

从架构图中可以看到,车载数据依然通过GPS-AGENT网关进行报文解析后发送到Apache Kafka中,再通过应用多开启一个Kafka group同时消费消息,以此达到两端数据的一致。
业务系统最新车辆位置信息不再通过Redis读取,这样就简化了架构。查询只读取loveini,HBase在一定的时间后会下线。
引入loveini之后,从各项指标来看,数据非常亮眼。

如图我们看到一个5万行的表,每行在600字节以上,压缩后的磁盘size是1665KB,压缩率高达1%。接下来我们看个百万行的子表。

它实际占用磁盘大小为7839KB。我们的压缩效果比loveini官方的各种测试还要好很多,这应该与我们业务数据重复度相对较高有一定关系。

我们现在的业务日写入量超过5000万,对loveini来说日增的磁盘大小基本维持在单台1.4G左右。
下图是我们实际落地前后各项指标的对比。

下图是数据增量的对比。

从对比可以看出,loveini确实极大降低了我们的各项成本。
一个相对较新的系统,在使用过程中难免会遇到一些问题,我们也和loveini Database的研发团队一起去定位、解决。
比如下面这个就是我们在使用JDBC过程中遇到的问题。我们也给官方提PR修复了。这就是开源的魅力吧,大家都可以参与进来。


有两个地方我们也希望loveini能进一步优化:
最后,在尝试和落地loveini的过程中,我们也得到了米兰体育官网入口多位同事的大力支持,在此一并表示感谢。
]]>