一种基于分布式系统的海量交通数据快速处理方法
技术领域
本发明涉及分布式内存计算平台Spark以及分布式文件系统HDFS领域,特别涉及一种基于分布式系统的海量交通数据快速处理方法。
背景技术
Spark是一个内存计算框架,提供和Hadoop(分布式系统基础框架)类似的MapReduce操作,但是中间结果不是存在文件系统上,而是在内存中,相比于Hadoop,在运算速度上有很大提升。
HDFS的全称为Hadoop Distributed Filesystem,是Hadoop的旗舰级文件系统。其思想来源于Google文件系统(Google File System,GFS),并适合一次写入、多次读取的访问模式,满足城市多源数据应用场景。它是一个适合存储大文件的分布式文件系统,可以作为Hadoop和Spark的数据源。
在内存中使用缓存技术,将常用数据块在内存中持久化,加快数据的处理速度。借助于Spark中的RDD(Resilient Distributed Datasets,弹性分布式数据集)将数据在内存中做标记并持久化,使得数据能被快速定位及访问。在内存中的预留空间使用完时,使用一种替换算法将不常用的数据块从内存中删除,目前比较适合的替换方法是最近最少使用(LRU)替换算法。
而随着目前城市交通发展迅速,交通数据量日益庞大,数据处理费时、效率低。如何在分布式系统的基础上实现快速处理海量交通数据正成为研究的方向。
发明内容
本发明针对上述交通数据量大,处理比较费时的技术问题,提出一种基于分布式系统的海量交通数据快速处理方法,该方法查询速度快,且效率高。
一种基于分布式系统的海量交通数据快速处理方法,包括以下步骤:
步骤a:在时间和空间上将海量交通数据分块,分块后的所述交通数据具有时间属性标识和空间属性标识;
步骤b:在内存中以细粒度存储一定数量的常用的所述交通数据,在文件系统中以粗粒度存储除所述内存存储的交通数据之外的交通数据;
步骤c:当处理程序请求处理数据时,判断所请求的交通数据是否在内存中;
步骤d:如果所请求的交通数据存储在内存中,则直接处理相应数据;以及
步骤e:如果所请求的交通数据存储在所述文件系统中,则先根据文件信息从所述文件系统中将所述交通数据读入内存,再对所述交通数据进行处理。
优选地,所述在时间上将交通数据分块是将每天的交通数据按顺序分为五个时间段:凌晨、早高峰、平峰即早晚高峰之间、晚高峰以及深夜,并用数字1~5作为其时间属性标识。
优选地,所述在空间上将交通数据分块是根据所述交通数据产生地点的经纬度信息找到其对应的交通小区,并将小区编号作为其空间属性标识。
优选地,所述交通小区是根据城市居民区以及交通道路将城市划分而成的小区,所述交通小区具有包括小区编号、交通小区质心、交通小区边界点集以及交通小区描述的域。
优选地,所述找到交通数据对应的交通小区包括如下步骤:
步骤a1:获取所述交通数据产生地点P的经度和纬度信息;
步骤a2:计算点P和所有交通小区质心之间的距离,并按照距离从近到远排序;步骤a3:按照所述顺序根据计算获得的所述距离判断所述点P是否在对应的交通小区内;
步骤a4:如果在对应的交通小区内,则返回对应的小区编号;否则继续找,如果最后也没有找到,则返回-1;
步骤a5:找到所述交通数据对应的交通小区后,在所述交通数据上增加一个字段,记录其对应的交通小区编号,作为空间属性标识。
优选地,步骤b中,在内存中以细粒度存储交通数据,是同时按照时间和小区号进行划分,将时间和小区号(<时间,小区号>)两者结合起来作为所述交通数据的键值。
优选地,步骤b中,在文件系统中以粗粒度存储交通数据,是在各个时间段的基础上,将所有交通小区分为若干个集合,并在文件开始位置记录各个小区在文件中的位置信息。
优选地,步骤c中,对于要处理的交通数据,根据其时间和空间属性查找其是否存在内存中。
优选地,步骤e中根据文件信息从所述文件系统中读取所述交通数据进一步包括以下步骤:
步骤e1:根据时间和空间属性获得所述交通数据所在的文件的文件名以定位该文件;
步骤e2:根据所述文件开头的数据位置索引信息,找到交通数据在文件中的具体位置,以快速读取。
优选地,所述内存中只保留一部分空间用于缓存所述常用交通数据,当新的交通数据需要读入内存时,若内存中预留空间不足,则根据最近最少使用原则从内存中剔除一部分数据,并将所需数据读入内存中。
根据本发明的机遇分布式系统的交通数据处理方法,对于海量交通数据,可以快速、高效地查询,大大提高了数据处理效率。
附图说明
图1是根据本发明方法的数据处理流程图。
图2是HDFS与内存映射关系图。
图3是内存数据细粒度存储示意图。
图4为北京市的交通小区划分示意图。
具体实施方式
以下结合附图对本发明进行详细说明。以下实施例并不是对本发明的限制。在不背离发明构思的精神和范围下,本领域技术人员能够想到的变化和优点都被包括在本发明中。
图1是根据本发明方法的数据处理流程图,包含数据的预处理过程(步骤S1~S2)和数据请求处理过程(步骤S3~S6)。
下面先对数据的预处理过程进行详细说明。预处理包括将原始数据按照时间和空间划分,增加时间和空间标识字段,并按照规则存储在文件系统上。
首先在时间和空间上将海量交通数据分块,分块后的所述交通数据具有时间属性标识和空间属性标识(步骤S1)。
城市交通系统每天都会产生大量的数据,对数据进行的大部分操作并不需要每次都对所有文件进行,而是根据某种属性选择一部分数据进行操作。即使要处理大量的数据,由于内存的限制,也需要对数据进行分块处理,所以需要提高的就是获取相应数据块的速度。由于交通数据在时间和空间的分布上有明显的规律(客流聚集、早晚高峰等),所以选择时间和空间这两个属性来作为海量交通数据分块的指标。
1)关于在时间上分块
交通数据中时间字段是以字符串格式存储的,格式为yyyy-MM-dd HH:mm:ss(如2015-08-3014:42:32)。根据客流规律,将每天按时间分为五个时间段:凌晨、早高峰、平峰(早晚高峰之间)、晚高峰以及深夜,分别用数字1到5作为时间属性标识。分时段方法如下:对于时段[startTime,endTime),只需要将每条数据的时间字段time和startTime、endTime进行比较即可。
2)关于在空间上分块
在空间上分块指根据交通数据产生地点的经纬度信息,找到其对应的交通小区。如图4所示为北京市的交通小区划分示意图。交通小区是一种对城市的划分方法,根据城市居民区以及交通道路将城市划分为一个个小区。它具有包括小区编号、交通小区质心、交通小区边界点集以及交通小区描述的多个域(如下表所示),另外还包括周长、面积等信息。
域 |
说明 |
id |
交通小区编号,从1开始 |
center |
交通小区质心 |
pointsList |
交通小区边界点集 |
desc |
交通小区描述,如“工人体育场” |
circumference |
交通小区周长,单位:m |
area |
交通小区面积,单位:m<sup>2</sup> |
划分交通数据块时以交通小区作为最小的划分单元。根据该交通数据产生地点的经纬度信息找到其所属交通小区的方法如下:
步骤a1:获取该交通数据产生地点P的经度和纬度信息,如(lng,lat);
步骤a2:计算点P和所有交通小区质心之间的距离,并按照距离从近到远排序;
步骤a3:按照该顺序根据计算获得的距离判断该地点P是否在对应的交通小区内;
步骤a4:如果在对应的交通小区内,则返回对应的小区编号;否则继续找,如果最后也没有找到,则返回-1;以及
步骤a5:找到该交通数据对应的交通小区后,在交通数据上增加一个字段,记录其对应的交通小区编号,作为空间属性标识。
如上所述,交通数据分块后,使得处理程序能够快速获取所需部分的数据。
接下来,在内存中以细粒度存储一定数量的常用的交通数据,在文件系统中以粗粒度存储除其它交通数据(步骤S2)。
若把交通数据只按照时间或者仅仅按照空间属性来划分数据块,那么从内存中提取另一种属性就需要读取多个这样的数据块后读取其中的部分数据,这会使得数据的访问效率变低。这就需要将数据的粒度变得更小,使用时间和空间两种属性同时划分数据。对于M个时间段以及N个小区,就会产生M×N个数据块。这种情况下数据的组合会更加灵活和快速。
另一方面,HDFS是面向大文件设计的,当存在大量的小文件时,会极大地降低HDFS的访问效率。本发明针对这个问题提出了分区而治的方法:在内存中以细粒度存储交交通数据;在文件系统上以粗粒度存储交通数据文件;同时在文件中提供细粒度的索引,加快数据从文件到内存的转化。具体如下:
1)在内存中,使用Spark提供的RDD来存储数据,使用时间和空间标识组合作为数据块的键值(标识)。在时间和空间标识中间加特殊符号(如'#')作为分隔,例如,“20150802#02#35”表示它所对应的是2015年8月2号早高峰时段,在35号交通小区内的数据。如图3所示是内存数据细粒度存储示意图。本方法在内存中将数据以细粒度划分,就是为了使得基于各种属性的数据集合的获取更加方便和灵活。
2)在文件系统中,使用类似于内存数据块的键值作为文件名。例如,将500个交通小区分为五组(五个交通小区组),分别用1至5代表,第i(1<=i<=5)组包含的小区范围是[(i-1)*100+1,i*100]。如第1组表示的小区编号范围是[1,100]。将每个时段分为5组小区数据分别存入5个文件中。文件名定义为date#t#groupId,其中date是日期,t为时段,groupId表示交通小区组编号。如“20150802#02#1”表示它所对应的是2015年8月2号早高峰时段,在1号交通小区组内的所有交通小区的数据。为了使得文件中某一小区的数据能够被快速转换到内存,还要在每个文件的开头建立各个小区交通数据在文件中的位置索引。
位置索引格式为:zoneId,startLine,endLine。其中zoneId是指小区编号,作为小区的标识;startLine指的是特定小区编号的数据在此文件中的开始行号;endLine指的是此小区的数据在文件中的结束行号。通过这三个字段即可获得任意一个交通小区数据在文件中的位置。
交通小区组:一个交通小区组包含多个交通小区,按照上面的划分,[1,100],[101,200],...等分别是一个交通小区组,每个组有对应的数字编号(groupId)作为标识。
图2是HDFS(文件系统)与内存映射关系图。数据在HDFS上是以粗粒度存储的,在内存中以细粒度存储,所以在文件系统上一个文件可以对应多个内存数据块。图中b1,b2,...分别代表某一时段的不同交通小区的数据。也就是说,文件系统中例如b1,b2和b3共同组成一个文件,而在内存中则将它们分开,b1,b2,b3分成三个内存数据块分开存储。
数据预处理完成后,即可以进行数据请求处理。下面详细介绍数据请求处理过程(步骤S3~S6)。
处理程序请求处理交通数据,该交通数据为日期为date、时段为t、小区编号为zoneId的数据(步骤S3)。
判断所请求的交通数据是否在内存中(步骤S4)。该步骤中,先确定所需数据的时间和空间属性标识,然后根据这两个属性判断内存中是否已经包含所需数据。即:首先确定数据的键值key="date#t#zoneId",然后查找内存中是否存在此键值。
如果所请求的交通数据存储在内存中,则直接从内存中提取并处理相应数据(步骤S6)。
如果所请求的交通数据不在内存中,则需要从文件系统中找到交通数据并读入内存(步骤S5)。然后再对所述交通数据进行处理。具体包括如下步骤:
e1:找到该交通数据的小区编号zoneId对应的交通小区组号groupId,然后根据date,t以及groupId确定数据文件名(文件路径名)filepath;
e2:根据获得的前述filepath,访问HDFS上对应的文件,读取文件开头的小区数据索引信息,快速找到数据在文件中的行号范围,并读取小区编号为zoneId的数据块;
e3:将数据读入内存后,持久化并设置"date#t#zoneId"作为键值。
通过上述方法,即可快速而高效地从分布式文件系统中读取交通数据至内存中。
本发明方法中,内存中只保留一部分空间(大小根据实际环境而定)用于缓存经常需要处理的交通数据。当新的数据要读入内存时,若内存中预留空间剩余不足,则根据最近最少使用(LRU)原则从内存中剔除一部分数据,并将所需数据读入内存中,最后再对内存中的数据做相应的处理。
LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。通过这种内存替换算法,可以使用有限的内存空间来尽可能好的提高数据的访问效率。
显然,本技术领域中的普通技术人员应当认识到,以上的实施例仅是用来说明本发明,而并非用作为对本发明的限定,只要在本发明的实质精神范围内,对以上所述实施例的变化、变型都将落在本发明的权利要求书范围内。