千万级GPS数据接入案例分享

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: GPS

业务背景:

项目需要接入全省的GPS数据(数据量从一开始的1000w+ 到 现在的 4000w+),原始数据存于Datahub中。

GPS数据的使用场景:

1.地图撒点(最新GPS点位)

2.统计车辆当日车辆和在线数

3.历史轨迹(按时间查询点位列表)

4.实时跟踪(后端主动推送实时点位信息)

5.报废车辆报警 (根据报废车辆信息生成告警)

6.围栏管控(根据GPS信息与围栏规则进行计算)

…………


业务分析:

GPS撒点:只取最新的GPS数据,查询频率较高,条件也较为复杂,因此原始数据尽量要少,能够直接满足我们查询需求。 针对业务场景,新建一张GPS_CURRENT表,表中只存每辆车的最新GPS点位,根据车辆ID新增/更新,同时根据车辆ID关联出区域,类型等信息,以满足我们撒点的查询需求。


历史轨迹: 由于每日的数据量在千万级,使用传统MYSQL数据库,存在极大的存储和查询压力,因此首先要考虑的是,我们的存储极限在哪里,与产品协商后,仅保留7天数据,而7天的数据也有2亿+的数据量,单表还是比较吃力的,因此考虑到作分区表,较为理想的情况是每个分区数据在千万级,5G以内; 轨迹的查询条件比较清晰,根据车牌ID + 时间范围作为查询条件, 因此分区条件必然在这两个字段中产生,由于我们需要定时按时间清理分区,使用时间作为分区字段,我们可以很方便的使用drop分区的方式达到清理历史数据的效果,而车辆ID作为条件则不能,因此选用时间作为分区字段。


因此我们需要两张表:

gps_current: 根据车辆ID进行插入或更新,用于撒点,在线统计等

gps_log:以时间为分区字段,用于轨迹查询


方案:

version.1

// datahub 协同消费代码RecordEntryrecord=consumer.read(maxRetry);

image.png

datahub协同

消费

数据过滤

insertOnDupilicate

gps-current

insert

gps-log

线程池处理其他

GPS计算

该方案是需求最平铺直叙的表达,很快就遇到了问题 —— 消费速度无法跟上生产速度。

version.2

在version.1的基础上,增加队列机制,使gps_log插入变为batchInsert, gps_current的insertOnDuplicate 变为 batchInsertOnDuplicate。

image.png

datahub协同

消费

数据过滤

线程池处理其他

存放到Queue

GPS计算

线程池异步批量

获取数据

batchinsertOnDupilicate

batchlnsert

gps-current

gps-log


在某一次版本后, 我们修改过滤条件, 由原先的只处理危货车 且 速度不为0的数据 变更为 处理危货/包车/客车 数据,且去掉速度的过滤条件后, 终于,在某天这套方案的消费能力也开始捉襟见肘。

version.3

重新梳理业务后,我们把业务划分为两类: 需要较高的实时性的 和 能够接收一定延时的

高实时性

低实时性

GPS撒点

轨迹

在线数

围栏计算

实时跟踪

报废车辆告警

因此我们先将gps_current相关的消费服务独立消费并拆分为单独的服务部署,在拆分独立服务后,gps_current相关的消费能力于原先等到了数十倍的提升。

image.png

datahub协同

datahub协同

datahub协同

消费

消灵

消寒

数据过滤

数据过滤

数据过滤

钱程池socket推

按车牌IDhash到

线程池处理其他

按车牌IDhash到

GPS计算

送实时数据

不同Queue

不同Queue

线程池异步按根

线程池异步按根

据shardld批量获

据shardld批量获

取数据

取数据

batchlnsert

batchinsertOnDupilicate

gps-log

gps-current

单独服务

compute服务


原先我们gps消费是放在compute服务, 这个服务中有大量的datahub消费服务和计算服务,且存在一定线程池的滥用,通过arms监控可看到单个服务存在500+线程,大量线程处理等待状态,导致该服务内的线程效率较差,重构后解决了一部分问题。 因此最终我们拆分为3个订阅,由于sockeServer是集成在compute服务(原先是单独的服务,通过RPC调用,由于推送都是由compute服务发起的,且日均百万次调用,考虑IO成本因此将两服务合并)。


version.4

其实在version.3版本,服务的消费性能已经能满足我们在相当长的时间内的性能需求了,但是存在一个不得不解决的问题 -> GPS时间上是乱序的, 即存在同一辆车,时间更早的GPS点反而更晚写入datahub, 而我们是直接更新gps_curret表的,导致存在最新点位时间向下更新的情况,因此需要加时间的判断条件。


第一直觉上,通过mysql判断肯定是不可取的,车辆最新的点位信息扔到redis,通过redis判断就能满足要求; 而实际实施过程发现,直接使用redis是消费速度是无法满足要求的,即使使用pipeline作批处理,与上一版本也存在较大的性能差。最后的方案是使用java内部的Map来做判断,该方案与version.3消费性能略有下降,但仍是当前的生产速度5-8倍,能够满足性能上的要求。



总结:

1.使用批量处理

2.更快的IO速度  数据库 -> redis -> java内存

3.取舍和拆分



实际上我们对于gps的处理,是不止上面4种方案的演进的;还有一些细节问题,在这里简单介绍下:

1.多节点datahub协同消费,但实际只有一个节点处于忙碌状态,其他节点都处于空闲状态, 原因是datahub协同消费时,是根据shard进行负载均衡的,即同一shard,只能分配到一个consumer上;当服务中consumer(多线程模拟多consumer) 数  >  shard数时,由于节点发布有先后顺序,后续启动的节点几乎是只能“干瞪眼”了。这里需要说明两点 (1)当consumer数 < shard数 时,一个consumer会被分配多个shard,所以为了保证多节点能够正确的协同消费,尽量使单服务的consumer数 < shard数(2)以上结论只基于当前datahub版本


2.在多线程batchInsertOnDuplicate时,发生了数据库死锁问题(具体原因就不分析了,篇幅较长,有兴趣的可以去找相关材料阅读), 我们的处理方式是,某一线程保证每个线程只拿到; 因此,对队列作了一层包装,内部有多个队列组成,根据车牌ID hash到不同队列, 消费队列时,要带上shard参数(即每个shard对应的是一个实际的队列),确保线程shard不会重复且与队列数量对应即可。


3.在version.4中,多线程下使用hashMap会存在线程安全问题,而currentHashMap性能上又低于hashMap, 我们采用的方案是针对每个线程使用一个HashMap (同时用多队列保证某一俩车只会被同一线程消费)

相关文章
|
数据采集 存储 监控
大数据的数据来源 - 数据采集的方式(数据接入的方式)
大数据处理关键技术一般包括:大数据采集、大数据预处理、大数据存储及管理、大数据分析及挖掘、大数据展现和应用(大数据检索、大数据可视化、大数据应用、大数据安全等)。下面主要介绍下大数据采集
4685 0
|
25天前
|
数据库连接 数据库 DataX
数据接入方案
数仓平台可直连或通过从库、堡垒机、FTP/SFTP等方式接入业务数据库,需提供可读用户权限及相应连接方式。若无法直连,可通过提供数据文件或脚本处理实现数据导入。
56 7
数据接入方案
|
2月前
|
传感器 存储 监控
TDengine 签约北微传感,实现海量传感器数据的秒级响应
在当今物联网(IoT)快速发展的背景下,传感器技术已成为各个行业数字化转型的关键组成部分。随着设备数量的激增和数据生成速度的加快,如何高效地管理和分析这些数据,成为企业实现智能化运营的重要挑战。
51 0
|
前端开发 定位技术 Android开发
Android平台GB28181设备接入端如何实时更新经纬度实现国标平台侧电子地图位置标注
我们在做GB28181设备接入端的时候,其中有个功能,不难但非常重要:那就是GB28181实时位置的订阅(mobileposition subscribe)和上报(notify)。
181 0
|
存储 JavaScript 前端开发
TDengine极简实战:从采集到入库,从前端到后端,体验物联网设备数据流转
TDengine极简实战:从采集到入库,从前端到后端,体验物联网设备数据流转
1340 1
|
存储 安全 网络协议
IoT亿级设备接入层建设实践
互联网的产品基本都需要解决终端的接入问题,每个接入层会因为终端数量、终端能力、网络环境等不同的因素有各自的设计特性。物联网场景下由于IoT设备的特点,不同的&quot;物&quot;特性催生了不同的IoT接入层。本文详细介绍了阿里云IoT在接入层的一些关键策略和设计。
1362 0
|
SQL 数据可视化 数据挖掘
如何在5分钟之内完成一个物联网统计指标?
本文介绍如何使用物联网平台的指标管理功能实现快速完成数据统计指标的开发。
如何在5分钟之内完成一个物联网统计指标?
|
数据采集 安全 大数据
大数据数据采集的数据来源的第三方服务数据之第三方埋点数据
在大数据应用中,数据采集是非常重要的一步。除了从自有渠道、应用程序和设备中收集数据外,现在越来越多的企业开始使用第三方埋点服务提供商来获取更丰富的数据。本文将重点介绍第三方埋点数据在数据采集中的作用。
376 0
|
人工智能 监控 自动驾驶
物联网对 5G 的指标要求 | 带你读《5G时代的承载网》之九
未来移动互联网主要面向以人为主体的通信,注重提供更好的用户体验,进一步改变人类社会信息交互方式,为用户提供增强现实、虚拟现实、超高清视频、云端办公、休闲 娱乐等更加身临其境的极致业务体验。
物联网对 5G 的指标要求  | 带你读《5G时代的承载网》之九
|
消息中间件 前端开发 Java
实时即未来,车联网项目之车辆驾驶行为分析【五】
单次行驶里程区间分布、单次行程消耗soc区间分布、最大里程分布、充电行程占比、平均行驶里程分布、周行驶里程分布、最大行驶里程分段统计、常用行驶里程、全国-每日平均行驶里程(近4周)、全国-单车日均行驶里程分布(近一年)、各车系单次最大行驶里程分布、不同里程范围内车辆占比情况。
361 0
实时即未来,车联网项目之车辆驾驶行为分析【五】

热门文章

最新文章