如何高效存储海量GPS数据

最近几年,移动设备已经非常普及,对GPS的使用也越来越常见,比如快车专车产品中的实时位置和历史轨迹图,运动App中的跑步,骑行轨迹等,很多研发人都遇到了如何设计系统架构来高效存储和查询GPS数据的问题。

对于一个互联网产品,要面对大流量,突发大压力,要保证低延时,高稳定性,还要考虑以后的实时扩展性,作为负责人的话,还需要考虑成本。这样,设计一个满足这些需求的系统就不怎么简单了,比如下面这些应用。

在这篇文章中,我们将通过设计一个骑行类App的GPS功能来说明多种使用场景及其区别。

产品功能

我们先明确这款骑行产品需要具备的基础功能:

  1. 用户骑行过程中,App记录GPS轨迹
  2. 用户在骑行过程中可以在手机App中看到自己当前的位置,历史骑行轨迹以及最大时速,平均时速,骑行时间等统计值
  3. 用户在骑行完成后,可以查看自己历史的骑行记录
  4. 给好友、家人或恋人实时共享当前轨迹
  5. 运营需要分析用户轨迹某个维度的特征

存储系统

首先,我们来看一下此类产品的特点:

  1. 用户数大,比较有名的产品可能会有百万,甚至更多的用户。
  2. 有明确的高峰低谷,比如早晨,傍晚是高峰期,凌晨是低峰期。
  3. 存储的数据量比较大,数据量和场景,用户量极度相关。
  4. 产品可能会有爆发发展期,系统需要有非常快速的扩展能力。
  5. 跟时间相关,需要按时间查询范围,或者需要在不知道起始时间和结束时间情况下查询轨迹点。
  6. 成本低。
  7. 稳定性高,尤其是写。

总结下就是:

  1. 高并发写入,尤其是写:具有每秒处理千万请求的能力,且性能不能随着数据增大而下降。
  2. 按量付费
  3. 单表大容量存储,最好不限表大小:PB级别。
  4. 实时水平扩展能力。
  5. 支持范围查询。
  6. 低成本
  7. 高稳定性:SLA保障。

表格存储(Tablestore)是由阿里云自主研发的基于共享存储的NoSQL数据库,是一款专为海量数据高性能存取而设计的存储系统,10G以下免费。

表格存储可以完全满足上述所有要求,另外,还提供多版本,TTL,递增ID,增量通道等功能。
确定了存储系统后,我们再来看方案。

方案

表结构设计

表格存储最多支持四个主键,每个主键都支持三种类型,字符串,二进制和长整型,属性列是schema free的,可以自由修改。

在当前方案中,表格存储的表格可以这么设计:

主键顺序 名称 类型 备注
1 partition_key string md5(user_id)前四位 为了负载均衡
2 user_id string/int 用户id 可以是字符串也可以是长整型数字
3 task_id string/int 此次轨迹图的id 可以使字符串也可以是长整型数字
4 timestamp int 时间戳 使用长整型,64位,足够保存毫秒级别的时间戳

如何存

设计好了表结构后,我们可以看一下轨迹数据如何存:
比如原始数据是:

2017/5/20 10:10:10的时候小王在杭州西湖断桥上骑自行车,速度5m/s,当时风速2m/s,温度20度,已经骑行了8公里。

在表格存储中存储的是(10列);

part_key user_id task_id timestamp longitude latitude speed wind_speed temperature distance
01f3 000001 001 1495246210 120.1516525097 30.2583277934 5 2 20 8000

主键

  1. part_key:第一个主键,分区建,主要是为了负载均衡,保证数据可以均匀分布在所有机器上,提高并发度和性能。如果业务主键user_id可以保证均匀分布,那么可以不需要这个主键。
  2. user_id:第二个主键,用户ID,可以是字符串也可以是数字,唯一标识一个用户。
  3. task_id:第三个主键,任务ID,也就是轨迹ID,表示某一次骑行任务的轨迹图,可以是字符串也可以是数字。
  4. timestamp:第四个主键,时间戳,表示某一个时刻,单位可以是秒,如果是每隔10秒记录一个GPS地址,那么相邻行的timestamp就相差10。时间戳1495246210等价于2017/5/20 10:10:10。
  5. 至此,上述四个主键可以唯一确定某一个用户的某一次骑行在某一个时间点的数据

属性列

  1. longitude:经度值。
  2. latitude:纬度值。这个(120.1516525097,30.2583277934)经纬度值表示的就是杭州西湖的断桥上。
  3. speed:骑行速度,可以是当前的瞬时值,也可以是过去10秒的平均值,也可以都记录。
  4. wind_speed:当前风速,这个值无法通过手机采集,需要特定的自行车车载模块。
  5. temperature:当前温度,可以直接取当前城市的温度值,也可以使用特定的温度传感器。
  6. distance:骑行距离,由于骑行的速度不会太快,可以用米为单位。
  7. 上面只是举了几个简单的例子,由于表格存储的属性列是schema-free的,任何时候都可以增删属性列,每一行可以有不同的属性列。甚至可以异步处理后,再回写挖掘出来的一些特征值。

下面我们来看一下各个场景:

GPS轨迹存储

关键点:

  • 使用表格的形式保存用户骑行过程中的meta数据
  • 表格存储单表数据量无上限,支持万亿级在容量,性能上没任何问题。

手机端:

  • 用户启动后,手机每隔10秒钟,发送一条数据给应用服务器,这条消息包括当前GPS数据和meta值(经度,纬度,速度,距离等)

服务器端

  • 应用服务器收到客户端发送的消息后,先对其中的GPS数据做纠正,然后将消息保存到表格存储中的GPS轨迹表中,主键保存用户id,任务id,时间戳,属性列保存经度,纬度,耗费时间,距离等。某一个时刻的数据保存在一行中。
  • 【补充】用户数据发送给用户的应用服务器后,应用服务器可以先做数据订正,订正好后再写到表格存储,但是有时候需要考虑到写流程是关键路径,清洗订正是非关键路径,需要写入和订正流程是异步流程,这时候可以直接使用表格存储Stream功能。数据直接写表格存储,然后用户应用服务器通过表格存储stream功能实时读取到新增数据,订正、清洗等完成后将结果写回表格存储,因为表格存储会在stream中保存12小时,所以,就算订正清洗功能短时间不可用,也不影响用户的使用。

GPS轨迹查询

通过表格存储GetRange接口可以查询到完整历史轨迹图。

手机端:

  • 当要查询自己这次骑行的历史轨迹和当前位置时,只需要通过一个范围查询(GetRange)就可以查到此次骑行的位置轨迹图。也就是查询这次任务从最早时间到当前时间内的GPS数据,对应于范围查询,首次查询时起始键可以是(md5(user_id).sub(0,4), user_id, task_id, MIN),结束键是(md5(user_id).sub(0,4), user_id, task_id, NOW),首次查询完后可以将NOW值保存下来,下次查询的时候起始键就可以是上一次查询的结束键,一直到此次骑行结束

服务器端

  • 接收到手机端的查询请求后,将其转换成表格存储的范围查询(GetRange),就可以查询到此次骑行的历史轨迹图。
  • 对于之前的历史轨迹图,也可以使用范围查询获取到历史轨迹。

其他人的GPS轨迹查询

关键点:

  • 读扩散:自己的GPS轨迹数据只保存在自己的user id下,其他用户过来读取。
  • 新表:share_gps_table,记录分享的user id,task id等信息。
  • 加密:对于分享过程中涉及的ID等值加密,防止恶意用户冒充。

手机端:

  • A用户启动后,可以分享当前骑行给自己的朋友B,也就是只需要把A的user_id和此次的task_id分享给朋友B。
  • 朋友B的客户端获取到用户A的user_id和task_id后,就可以使用范围查询获取用户A在此次骑行中的实时位置和轨迹图了。

服务器端:

  • 如果是分享者A通过二维码,链接等分享给用户B,这时候用户B的手机端可以获取到用户A的user id和此次task id(可以使用加密,防止被人篡改id),用户B可以去服务器端获取这次的用户A的骑行实时轨迹图。通过这种方式的分享记录可以持久化到表shard_gps_table中,也可以不持久化。
  • 在App内部用户A分享给用户B,用户A将分享记录发送给服务器后,服务器记录在shard_gps_table表中,然后给用户B发送一个通知,包含一个特殊的ID值(可以是用户A的user id和task id加密后的一个值,这个值不能允许反向解析出user id和task id)。
  • 用户B收到通知后,通过这个特殊的ID值到服务器端来查看表shard_gps_table中是否有对应的分享记录,如果有,则将对应的用户A的user id和task id发送给用户B,用户B再通过这些来读取用户A的轨迹图。

组团GPS轨迹查询

有时候,用户会组团去骑行,这时候,团员都希望可以在一张地图里面看到大家所有人的实时位置和历史轨迹图,团长也希望能通过这些值作为参考,安排大家休息地点和时间。对于这种场景,可以按下面方式实现:

关键点:

  • 所有团员都使用同一个任务ID
  • 读扩散(写的时候写到自己的user id下面,读的时候读其他成员的同任务id的数据)
  • 使用新表:group_user_table,记录每个组的当前用户和历史用户(使用表格存储多版本功能可以保存用户的多次加入和离开时间)

手机端:

  • 团长发起队伍,创建一个task id,其他成员加入,获取task id
  • 每个成员骑行过程中,将自己的gps轨迹数据记录在自己的数据中(前两个主键为:user_id, task_id)
  • 如果有成员先退出,后加入,仍然使用同task id,前后两段gps轨迹仍然有关联。

服务器端:

  • 使用新表(group_user_table)记录每个task id下对应的成员id。这里可以使用多版本记录成员的多次退出加入事件。
  • 查看整个队伍gps轨迹时,先通过task id查看所有成员ID,然后使用表格存储的BatchGetRow或者GetRange获取所有成员的轨迹数据。

团员异常路线报警

组团骑行或者组织的大型比赛中,有可能某些成员掉队或者骑错路线,这时候就需要让组织者知道,使用表格存储的stream功能就可以很容易对于异常骑行者做出报警。

关键点:

  • 使用表格存储的增量通道(Stream)功能。
  • 读扩散:App中有可能会搞全国运动,这样同时参加用户可能数十万或者百万,这时候读扩散的优势就比较明显了。

服务器端:

  • 每个组员的GPS轨迹数据发给表格存储后,表格存储会持久化数据后,然后新数据和更新数据会实时进入stream通道,用户可以实时或者周期性的使用SDK提供的接口读取到这些新进来的GPS数据,然后在自己的应用服务器中计算这些GPS数据和安全区域做比较,如果出了安全区域或者掉队太远,发送一条报警短信给组织者或者组织机构。这里可以使用阿里云存储团队的消息服务(MNS)
  • 如果不想使用Stream功能,也可以直接通过GetRange接口从表中读取,由于不知道哪些用户有更新,需要读取所有用户的最近一段时间的数据,当用户量很大的时候,这个复杂度和开销都会很大,远远没有stream功能易用和性能好。

手机端:

  • 组织者收到团员掉队或者走出安全区域的报警后,可以立即查看这名成员的历史轨迹和当前位置,然后安排人员联系异常团员,防止危险事件发生。

粉丝围观大V骑行

有社区后就有可能会有大V,大V可以在App中搞骑行直播,旁边可以展示GPS轨迹,几十万,甚至几百万粉丝围观,打赏等

关键点:

  • 读扩散:这时候就只能使用读扩散了。由于前面的功能都使用了读扩散,那这里处理就非常简单。

手机端:

服务器端:

  • 和前面处理逻辑差不多,这里就省略了。

运营分析

全量分析:

  • SQL:使用Max Computer 2.0 (原ODPS)的SQL功能,可以直接读取表格存储中的数据,无需导出,节省了导出时间,更快地计算出结果。
  • 自有job:使用dataX可以全量高并发的导出到Max Computer中去做分析处理,处理完后继续可以用dataX写会表格存储。
  • 适用于批处理方式。

增量分析:

  • 使用表格存储的stream功能可以获取最近十二小时的用户新增,更新,删除事件涉及的数据,即可以获取到数据的实时变化情况后做分析处理。
  • 适用于实时处理方式。

直写方案

上述方案已经可以完全满足高并发,低延迟的需求了,那么这个技术架构是否是还可以继续优化呢?当然是可以。上述方案中,手机App其实可以直接将数据存储到表格存储,不需要经过应用服务器中转,减少对应用服务器的压力。

上述5个步骤分别是:

  1. 用户启动后,手机向应用服务器请求写表格存储的写权限。
  2. 应用服务器审批后,如果认为可以给予这个用户写权限,那么可以继续向阿里云的STS服务申请表格存储的临时写权限和授权时间。
  3. STS服务接收到请求后,生成一个临时的令牌,包括临时AccessKeyId,临时AccessKeySecret和临时token,将其返回给应用服务器。
  4. 应用服务器接收到STS的结果后,将其返回给手机端的APP。
  5. 手机端的App接收到临时令牌后,可以向表格存储开始持续写数据。等持续写了一定时间后,临时令牌会失效(失效时间用户可自定义),如果到时候还需要写入,可以继续申请新的令牌。

上述直写方案相对于原有方案,有如下一些优势:

  • 可以减少应用服务器压力。
  • 手机端直接写TableStore,不用经过应用服务器,路径更短,性能更佳。
  • 将最关键的GPS写流程和应用服务器解耦合,旁路化,关键路径独立出来,就算应用服务器出现故障,不可服务了,但仍然不影响用户的GPS写入流程。

总结

前面讲了如何用表格存储(Tablestore)存储骑行类APP的GPS数据,以及stream功能在各个重要场景中的使用。虽然讲的是骑行类APP,但是其他场景也同样适用,比如跑步类、专车类、车联网等等。这里由于篇幅问题,每个部分都还比较简单,如果大家有兴趣,针对上述的每个点后续都可以继续展开再详细讲讲。

也欢迎大家加入表格存储技术交流钉钉群讨论:

时间: 2024-08-21 16:25:19

如何高效存储海量GPS数据的相关文章

基于Hadoop的海量医疗数据存储平台的研究

基于Hadoop的海量医疗数据存储平台的研究 王恒 随着医疗信息化又好又快的发展,医疗数据迅速的涌现出来.然而,现存的医疗数据 存储平台不能够满足日益增长的海量数据的需求.因此,研究并开发一个有效的存储平台来管理和存储这些海量医疗数据显得尤为的重要.云计算为目前所面临的存储分析医疗数据的困境,提供了一种低成本.容错性强.高可扩展性和可用性的解决方案.基于分布式计算技术,本文提出了一种新的管理和存储海量医疗数据的方法.它提供了一种基于Hadoop,使用Linux集群技术的海量数据存储的解决方案.大

基于云上分布式NoSQL的海量气象数据存储和查询方案

前言 气象数据是一类典型的大数据,具有数据量大.时效性高.数据种类丰富等特点.气象数据中大量的数据是时空数据,记录了时间和空间范围内各个点的各个物理量的观测量或者模拟量,每天产生的数据量常在几十TB到上百TB的规模,且在爆发性增长.如何存储和高效的查询这些气象数据越来越成为一个难题. 传统的方案常常采用关系型数据库加文件系统的方式实现这类气象数据的存储和实时查询,这种方案在可扩展性.可维护性和性能上都有一些缺陷,随着数据规模的增大缺点越来越明显.最近几年,学界和业界开始不约而同的转向利用分布式N

海量冷数据存储关键技术

近年来,移动互联网.物联网.云计算的快速发展催生并积累了大量的用户.业务数据.据市场调研机构IDC预计,未来全球数据总量年增长率将维持在50%左右,到2020年,全球数据总量将达到40ZB.据统计,这些海量数据中只有10%~15%的数据是被经常访问的,而绝大部分都会在产生之后逐渐变冷.这些"冷数据"的访问率虽然很低,但用户还是希望保留这些数据,对于企业而言,还有很多数据需要进行备份和存档. 且不管数据的冷热及其冗余备份,如果将这40ZB的数据都使用目前已量产的最大容量蓝光盘来存储,按照

如何高效处理物联网中数据与消息

面临爆炸式增长,车联网业务平台问题重重 服务于大量的客户.合作伙伴和生态链的其他企业,用户诉求来源复杂: 需求变化快,不可控因素多: 各种营销手段带来突发的业务访问: 系统越来越复杂,模块越来越多: 市场竞争剧烈,创新不断涌现: 移动互联网规模比传统互联网大10倍,物联网的规模又要再扩大10倍,新时代才刚刚开始. 行车辅助.汽车安全.智能交通.出行服务.生活娱乐等将成为车联网的主要发展方向.面临爆炸式增长,车联网的系统架构需要充分考虑,使性能能够水平.线性扩展,功能满足市场快速变化的需求. 典型

C#实时处理海量GPS定位信息的难题

问题描述 系统概述我们用C#3.5做了一个Windows服务用来接收从GPS服务器发送来的海量定位信息(采用事件触发,我们订阅了GPS服务器的一个事件,GPS服务器不停地推送定位信息给我们),收到信息后做如下处理:1.解析GPS定位信息:2.存储GPS定位信息:3.分发GPS定位信息给订阅了该GPS终端的客户端(发送Socket包到一个通信服务器专门处理分发事宜.接收GPS定位信息的服务和订阅GPS定位信息的客户端都连接到该通信服务器)难题1.由于GPS终端量很大(大概2万个),每秒上报的GPS

定义大数据:不仅仅是海量结构性数据

文章讲的是定义大数据:不仅仅是海量结构性数据,大数据如果仅仅是海量的结构性数据,那么解决的办法就比较的单一,用户通过购买更多的存储设备,提高存储设备的效率等解决此类问题.然而,当人们发现数据库中的数据可以分为三种类型:结构性数据.非结构性数据以及半结构性数据等复杂情况时,问题似乎就没有那么简单了. 大数据汹涌来袭 当类型复杂的数据汹涌袭来,那么对于用户IT系统的冲击又会是另外一种处理方式.很多业内专家和第三方调查机构通过一些市场调查数据发现,大数据时代即将到来.有调查发现,这些复杂数据中有85%

C++程序设计:原理与实践(进阶篇)15.1 存储和处理数据

摘要 Programming: Principles and Practice Using C++, Second Edition 容器和迭代器 只做一件事,并把它做好.多个程序协同工作. --Doug McIlory 本章和下一章将分别介绍C++标准库(STL)中的容器和算法部分.STL是一个用于处理C++程序中数据的可扩展框架.我们首先通过一个简单的例子来说明STL的设计理念和基本概念,然后详细讨论迭代器.链表和STL中的容器.STL通过序列(sequence)和迭代器(iterator)的

云存储怎样解决数据中心存储问题

现在对于大型的数据中心来讲还有一种应用方式就是针对个人用户,以及在企业内部用户级数据的管理. 我们知道电信的数据机房里面,我们的存储设备我们的服务器是为专用的设备进行使用的,很少有针对个人用户来进行服务的一些系统. 随着我们个人级用户数量的不断增加,PC数量的不断增加,随着个人PC上或者工作机上资料的不断增加,如何对个人电脑中数据进行备份以及数据保护,就是一个很重要的问题. 而现在经过一个统计,大约65%的用户是完全没有办法或者对自己电脑中数据进行备份和容灾,只有20%通过简单的备份方式比如刻录

红帽开源云:Linux、虚拟化、存储与大数据

三月底,红帽发布了截止2012年2月29日的2012财年第四财季及全年财报.财报显示,红帽2012财年总营收为11.3亿美元.至此,红帽成为IT业首家年收入超过10亿美元的开源解决方案厂商.红帽是如何做到三年十亿?2012年过去了一半,红帽又有哪些新动向?未来又有何计划呢? 核心Linux业务与虚拟化 今年五月,红帽企业Linux面世十周年. 2002年5月,红帽推出首款企业Linux操作系统.十年间,Linux操作系统已经在企业级领域获得认可和普及. 红帽企业Linux还提供了内嵌的KVM虚拟