本章节主要为您介绍基于表格存储的海量气象格点数据解决方案的模型及方案设计。

标准化格点数据模型

一个规整的五维网格数据为一个网格的数据集(GridDataSet),按照维度顺序五维分别为:
维度 说明
variable 变量,例如各种物理量
time 时间维度
z z轴,一般表示空间高度
x x轴,一般表示经度或纬度
y y轴,一般表示经度或纬度

GridDataSet = F(variable, time, z, x, y)

一个GridDataSet除了包含五维数据,以及各个维度的长度等外,还包含一些其他信息:
名称 说明
GridDataSetId 唯一标记这个GridDataSet的ID。
Attributes 自定义属性信息,例如该数据的产生时间、数据来源、预报类型等等。

您可以自定义属性,也可以给某些属性建立索引,建立索引后就可以通过各种组合条件来查询符合条件的数据集。

例如,假设某种气象预报每次预报未来72小时的每个整点的各个高度、各个经纬度的各种物理量,则这次预报就是一个标准的五维数据,是一个单独的GridDataSet,下一次相同的预报则是另一个数据集。这两个数据集需要有不同的GridDataSetId。这两个数据集比较类似,只是起报时间不同,但是因为起报时间不在五维模型中(五维内的时间为一次预报中的未来不同时刻),所以属于不同的数据集,起报时间可以作为数据集的自定义属性。本方案中,也支持对自定义属性设置条件进行检索。

数据存储方案

表格存储设计了两张表分别存储数据集的meta和data:
  • meta表示这个数据集的元数据,例如GridDataSetId、各维度长度、自定义属性等。
  • data表示这个数据集里实际的网格数据。data相比meta在数据大小上要大很多。
将数据集的meta和data分开存储,主要是出于以下考虑:
  • 用户会有根据多种条件查询数据集的要求,例如查询最近有哪些数据集已经完成入库,或者查询表中有哪些某种类型的数据集等。传统方案中主要是通过MySQL等关系型数据库来存储,在本方案中我们通过单独的meta表来存储,并通过表格存储的多元索引功能来实现多条件的组合查询和多种排序方式,相比传统方案更加易用。
  • 在查询格点数据之前,一般要知道格点数据中各维度的长度等信息,这些信息就是存储在meta表中的,即需要先查询meta表,再查询data表。因为meta数据一般都很小,因此查询效率相比查询data要高,多一次查询并不会明显增加延迟。

meta表设计

由于GridDataSetId可以唯一标记一个GridDataSet,所以meta表的主键只有一列,用于记录GridDataSetId。各种系统属性和自定义属性保存在meta表的属性列中。


meta表设计

查询meta表有两种方式:一种是通过GridDataSetId直接查询,另外一种是通过多元索引。可以根据多种属性条件组合进行查询,例如筛选某种类型的数据,按照入库时间从新到老返回等。

data表设计

data表的设计要解决五维数据在不同的切分模式下的查询效率问题,不能简单直接的对数据进行存储。

为了高效查询,需要尽量减少一次查询需要扫描的数据量。一个数据集的数据量可能在几GB的级别,但是一次查询往往只需要其中的几MB的数据,如果无法高效的定位要查询的数据,那么就要扫描全部的几GB的数据,从中筛选出符合某个范围的数据,显然效率是很低的。如何才能高效定位到需要的数据之中是提高查询效率的关键。

合理的表结构设计可以提高查询效率,在设计表data时,使用四个主键列:
主键 说明
GridDataSetId 数据集Id,唯一标记这个数据集。
Variable 变量名,即五维模型中的第一维。
Time 时间,即五维模型中的第二维。
Z 高度,即五维模型中的第三维。

data表设计

这四列主键列标记一行表格存储中的数据,这行数据需要保存后两维的数据,即一个格点平面。

这种设计下,五维中的前三维都可以通过主键列的值来定位,即对于前三维的每一种情况,都对应表格存储中的一行。由于前三维分别代表变量、时间和高度,一般不会很多,每个维度在几个到几十个的级别,可以通过一些并行查询的方法来加速查询速度。

后两维代表了一个水平的平面,一般是一个经纬度网格,这两维的大小是比前三维要大很多的,每维在几百到几千的级别,随着数值预报越来越精细化,这个网格的大小还会成倍增加。这样的一个稠密的网格数据,不能把每个格点都用一列来保存,这样列的数量会非常多,存储效率也会非常的低。另一方面,如果我们把一个平面的格点数据存储到一列中,在整读整取时效率比较高,但是如果只读取某个点,就会读取很多的无效数据,效率又会变得比较低。因此我们采取一种折中的方案,对平面的二维数据再次进行切分,切分成更小的平面数据块,这样就可以做到只读取部分数据块,而不总是读取整个平面,因此极大的提高了查询性能。


data表设计