APP下载

面向气象Web 应用的数据库访问性能优化及应用∗

2020-12-23杨立苑周雪莹邹海燕刘喆玥胡丽丽

计算机与数字工程 2020年11期
关键词:数据表气象动态

杨立苑 李 芬 周雪莹 邹海燕 刘喆玥 胡丽丽

(江西省气象信息中心 南昌 330096)

1 引言

近年来,随着互联网技术的的快速发展,国家积极推进“互联网+”行动[1],互联网技术已经成为包含气象行业在内各个行业提供服务的基石[2~4],其中Web 应用是提供互联网服务的重要手段。为了满足气象服务现代化的需要,各省气象部门基于Web 应用开发框架建立了满足各种气象服务需求的Web应用[5~7]。关系型数据库是构建Web应用系统必不可少的一部分,气象Web数据库访问性能的高低严重影响着气象Web应用的服务质量。

目前,Web 应用系统主要通过对象关系映射(Object Relational Mapping,ORM)技术访问数据库[8],开发人员使用的主流ORM 框架是基于静态语言开发的,例如Java 语言的Hibernate 框架[9]、C#语言的EF 框架[10]。在Web 应用开发中,ORM 技术能将面向对象建立的对象模型映射到关系型数据库表结构,这样开发人员就不必再通过SQL语句去操作数据库,只需要操作对象实例便可以实现数据库的增删改查。

造成这种挑战的原因主要来自两个方面。一是承载省级及以下气象业务的服务器等基础硬件设施陈旧,性能不高,二是数据表中站点数量多,随着系统运行时间的增长,数据表中数据记录会爆炸性的增长,最终影响该表数据访问性能。例如,如果站点数是3000 个,一年的小时数据记录数可以达到2600 多万条。所以,本文主要研究的是如何在该特殊环境下去优化气象Web 数据库中气象类数据表的ORM 访问性能,并且将其应用到实际开发应用中。

2 本文工作分析

Web 数据库访问性能的优化一般是从服务器硬件性能、数据库软件、数据库设计、ORM 框架性能、缓存等方面进行[11~14]。服务器硬件性能不满足业务需求以及增设缓存服务需要大量资金进行升级,这方面尤其在市县级很难一时得到解决。数据库软件和ORM 框架技术成熟,在本文特殊环境下优化带来的效果不佳。

本文优化途径是优化数据库表设计,压缩数据表中的记录数。本文主要从两个方面进行数据表记录数的压缩,一是对数据表进行分表操作,二是通过增加表属性个数的方式减少同一时间段的数据记录数。

但是经过优化设计的数据表并不能很好地得到静态语言ORM 框架的支持。这是因为优化后的数据表需要根据时次动态的操作表属性,使用原生的SQL语句可以通过字符串拼接的方式简单实现,但使用面向对象的方式需要能够动态地改变赋值属性。例如一段逻辑代码的语义是给实例A的t时属性赋值,那么在t+x 时该段逻辑代码需要给A 的t+x时属性赋值。在静态语言程序中对类实例中公共属性的操作可以通过变量赋值的方式进行操作,对类实例中私有属性的操作需要通过调用类中定义的公共方法进行操作。简单的变量赋值方式和调用公共方法方式都无法改变程序中操作类实例的属性对象,这需要采用复杂的反射技术才能实现。

为了能够更加快速简单地开发气象Web应用,考虑到相比于国家级,省级及以下气象业务人员信息技术能力不强的现状,本文基于动态语言Python的Django ORM 框架实现了对优化后数据表的访问方法,Python 语言可以非常容易的进行动态属性赋值。最后将该方法应用到实际Web应用开发中。

3 访问性能优化技术

3.1 数据库分表方法

为了能够动态地增加分表的数量,减少分表产生的数据迁移量,本文使用一致性Hash 算法进行分表操作。由于气象类数据中,时间属性是用于数据检索的重要指标,所以本文使用每条数据的时间戳作为Hash 函数的输入。数据库分表方法如图1所示。一致性Hash 算法将Hash 函数的值空间构成一个虚拟圆环,值空间的取值范围是[0,232-1]。本文将现有的表通过Hash 函数映射到虚拟圆环上。每条数据存储的表取决于每条数据时间戳Hash值的大小。当时间戳的Hash值大于某张表在Hash 环上的值,且该表的Hash 值离该条数据的Hash 值最近,那么该条数据存放在该表中。每次进行数据的插入、更新、查询也会根据时间戳判断数据位于哪张表中。

图1 数据库分表方法

当某张表中的数据记录数超过了设定的阈值,那么该张表将会进行分表。表中时间戳Hash 值大于新表Hash 值的数据将会迁移到新表中。其余表中的数据保持不变。为了不影响气象数据服务的质量,每次对所有表中记录数的检查以及分表的数据迁移操作都在凌晨一点执行。由于气象数据是时序,为了方便查询,提高查询效率,时间戳经过Hash函数计算出的Hash值也会保持和输入值一样的大小顺序,这样时间相近的数据会尽量存放在一张表中。为了保证查询数据的完整性,数据库会有一张单独的表来记录每张分表存储数据的最大和最小Hash值。

3.2 表结构设计方法

如果要在保障气象Web 数据库某张表数据信息量不变的前提下,减少该表数据的记录总数,那么可以将时次属性和气象数据属性的笛卡尔积作为数据库表的属性。例如,区域站小时降水表可以将每个时次降水量都作为表中一个属性,将同一个站点一天24条小时降水数据压缩至一条数据。

FastEthernet0/1 128.2 128 19FWD 0 4096 cc00.1ca0.0001 128.2

图2 数据库表优化设计方法

假设需要在数据库中建表的对象属性集合为S,对象的时间信息属性和站点信息属性集合为X,上一级时间单位包含当前时间单位的集合为T,设计的表中列属性集合为C。数据库表优化设计方法如图2 所示。集合X 中时间信息属性主要是指该条数据的资料时间、资料更新时间等。如果当前资料是小时数据,那么资料时间单位是小时,该资料的上一级时间单位是天,一天包含00 时t1、01 时t2在内共24个时间属性,这些时间属性组成了集合T。集合X 中的时间属性直接映射到集合C 中,时间单位上升一级。集合X 中的站点信息主要包括站点的站号、经度、纬度等属性,这些属性可以直接映射到集合C 中。集合X 是集合S 的子集,集合S除去集合X 中的元素,剩下的元素是一系列气象观测要素属性或者和气象类相关的要素属性,例如到报情况。所有的要素属性需要和集合T 中的所有属性进行笛卡尔积字符拼接,拼接的字符作为新的属性映射到集合C 中。综上所述,优化后表的属性集合C定义公式为C=X ∪((S-X)×T)。

在数据库表设计完成之后,需要对设计的数据库表进行范式检查。范式检查主要包括第一范式(1NF)、第二范式(2NF)、第三范式(3NF)这三类范式检查[15]。按照本文数据库表设计方法定义的数据库表每一列属性没有重复也没有存储多个值,设计的主键由资料时间和站号组成,该主键能够唯一区分每一条数据记录。但是数据表中站点属性,如经度、纬度、海拔高度可能出现在其他数据表中。所以本文设计的表符合数据库设计第一范式和第二范式,可能会不符合第三范式。第三范式的主要作用是保障不会出现大量的数据冗余,这里存储少量冗余经度、纬度数据所占用的多余空间是可以接受的。并且如果这些冗余信息存储在同一张表中,在进行该表数据访问时,就不必为获取这些信息再进行连表操作,这样有助于提升数据检索性能。

3.3 基于Python动态特性的ORM访问

Django 是使用Python 语言编写的开源Web 应用开发框架[16],Django 框架关注点集中在模型(Model)、模版(Template)、视图(Views)这三个部分。其中Model 部分指的是数据存取层,处理与数据存取相关的所有事务。Django 允许用户通过管理命令Manage migrate 进行数据库的迁移,该命令可以一次性帮助开发人员创建Models 中定义的数据表。

Web 应用系统通过ORM 技术将软件系统中的类映射至对应数据库表,对数据库表的操作主要是增(INSERT)、删(DELETE)、改(UPDATE)、查(SELECT)这四种操作。首先是对数据库分表的映射,本文采用开源项目django-sharding 进行分表映射,该项目允许用户在执行数据库操作时动态的选择要操作的分表。其次是对数据表的面相对象操作。Python 能够使ORM 进行动态操作的本质在于可以通过字典“键-值对”中的键字符串进行类属性值修改。为了能够对对象实例进行动态属性赋值,需要在对象的类中定义一个动态属性赋值函数,如下:

def init_from_dict(self,init_dic):

for k in init_dic:

self.__dict__[k]=init_dic[k]

其中init_dic 是字典数据结构,该字典每个元素的键是类的属性名,值是键对应属性的值。Python中定义的类本质也是一个字典,在这通过循环的方式对init_dic中包含的所有属性进行动态的修改,这样就不用去使用静态语言中复杂的反射技术。

在定义好映射类的基础上,开发Web应用时便可以在业务逻辑中进行相关数据库操作了。数据库的动态增操作首先要需要定义一个空字典,将所有需要更改的属性及该属性的值赋给字典,然后用自定义的方法init_from_dict进行类实例的初始化,最后通过Django ORM 的函数进行数据库表数据的批量增操作。数据库的动态查操作需要调用Django ORM 提供的Q 函数,使用Q 函数只需要定义条件逻辑连接器和查询条件即可进行数据库查询,条件逻辑连接器支持与(AND)、或(OR)、非(~)逻辑,查询条件也只需通过字典键值对的方式添加。数据库的动态删操作是基于查操作,进行查操作获取返回的查询结果对象后,只需调用delete 函数即可将该对象从数据库中删除。数据库的动态改操作类似于数据库的动态增操作,但首先需要先通过查操作获取需要更改的记录对象,然后通过该对象的init_from_dict 函数进行相关属性值的修改,最后通过save 函数即可完成该条数据的修改。Django ORM动态访问数据库操作示例如表1所示。

表1 Django ORM动态访问数据库操作示例

4 优化验证和业务应用

4.1 验证实验环境

本文使用三台虚拟机(VM)作为气象Web数据库访问性能优化效果验证的实验环境。这三台虚拟机部署在江西省气象云平台[17]当中,具体的配置环境如表2所示。三台虚拟机都使用CentOS 7.4作为操作系统,其中一台虚拟机部署数据库MySQL 5.4,一台虚拟机部署采用优化技术的Django Web测试应用,一台虚拟机部署未采用优化技术的Django Web 测试应用。Django Web 测试应用使用的Python 动态语言运行环境版本是Python 3.6。云平台分配给部署MySQL 虚拟机的CPU 是4 核@2.1GHz,内存大小是8GB;分配给部署Django Web测试应用虚拟机的CPU 是2 核@2.1GHz,内存大小是4GB。

表2 验证实验环境虚拟机配置

4.2 验证实验及分析

实验首先需要向MySQL 数据库注入气象数据,实验使用的数据是江西省2017 年全年所有区域站小时降水数据,江西省区域站个数是2456个。为优化后Django Web 测试应用建立的数据库表是按照本文提出的设计方法设计的,以日期和站号作为主键,24 个时次和小时降水量的笛卡尔积作为元素属性。为优化前Django Web 测试应用建立的数据库表是按照传统气象数据库设计方式建立,以时次和站号作为主键,小时降水量作为属性。然后用Django 技术开发两个简易的Web 测试应用,测试应用开发完毕后部署到相应的虚拟机中。最后,使用Web 测试应用进行数据库读写测试。

进行Web 测试应用的数据库读写测试需要分6 次进行。每次向数据库中注入气象数据,使得数据表中的数据集时间跨度达到1周、1个月、3个月、6 个月、9 个月、12 个月。每次注入完数据后,分别测试Django Web 应用的读写操作。读操作是连续进行100 次查操作,随机查询某个站点某天某时次的降水量,统计完成100 次查操作的时间。写操作是连续进行100次增操作,随机插入2016年某个站点某天某时次的降水量,统计完成100 次增操作的时间。

验证实验读写测试结果如图3、图4 所示。在数据集时间跨度比较小情况下,采用本文所提出优化技术开发的Django Web测试应用ORM 访问性能和传统设计方法开发的Web测试应用ORM 访问性能差不多,ORM 读测试的百次访问耗时都集中在9s 左右,ORM 写测试的百次访问耗时都集中在12s左右。但是,随着数据集时间跨度的增加未采用优化技术的应用ORM 访问性能快速衰减,12 个月数据集的ORM读测试的百次访问耗时达18s,12个月数据集的ORM 写测试的百次访问耗时达25s,而采用优化技术的应用ORM 访问性能总体保持平稳不变。

图3 数据库ORM读测试结果

图4 数据库ORM写测试结果

4.3 气象业务应用

本文将提出的气象Web 数据库数据小时表访问性能优化方法应用于江西省区域站数据直传运维保障系统。江西省区域站数据直传运维保障Web 系统采集入库了每个时次全省区域站数据在每个传输环节的传输情况,包括CIMISS CTS[18]、省级区域站中心站、区域站报文来源、区域站电量供应等环节。省、市、县三级区域站数据传输业务运维保障人员可以通过该系统查询区域站每个时次每个传输环节是否正常。该系统也提供了对区域站数据传输情况的统计、分析、诊断。该系统分为数据存储与访问层、业务逻辑层、数据展示层。

本文将气象Web 数据库访问优化技术应用于数据存储与访问层,设计实现了省级区域站数据直传情况数据库,基于Django ORM 进行数据库的动态访问,并且向业务逻辑层提供数据访问接口。最后运维人员可以通过Web 展示层进行区域站数据直传情况的查询和故障诊断,图5 是区域站数据直传历史情况查询页面示例。该运维保障系统的实现基本上满足了省、市、县三级运维保障人员对区域站数据直传保障的需求,经过优化之后,系统查询效率得到了一定的提升,提高了平常业务工作的效率,推动了该运维保障系统在江西省省、市、县三级气象部门的应用。

图5 区域站数据直传历史情况查询页面

5 结语

本文设计了一种面向气象Web 应用的数据库ORM 访问性能优化方法,并且针对优化后的数据库基于Python 语言提供了ORM 框架下的动态访问操作方法。实验结果表明该优化方法是有效的,本文也将该方法应用到江西省区域数据直传保障系统开发中。但是该方法面临着在数据库表属性过多的情况下会明显增加软件开发人员工作量的问题,下一步的主要工作是研究如何进行数据库表和对象模型类代码的自动化生成,提高Web应用开发人员工作效率。

猜你喜欢

数据表气象动态
国内动态
气象树
国内动态
国内动态
专栏:红色气象 别有洞天
湖北省新冠肺炎疫情数据表(2.26-3.25)
湖北省新冠肺炎疫情数据表
湖北省新冠肺炎疫情数据表
动态
大国气象