基于MongoDB数据库的多时态地形数据存储管理方法利用多时相遥感数据和融合技术,对受灾区域进行监测、预警和分析,对于制定具体的防灾方案和采取有效的防治措施,都有着重大意义[1]。如何有效地管理受灾区域的多时相、精细化的海量地形地貌历史数据,以及航空遥感和卫星遥感技术实时获取的最新数据,支持高效的存储和调度,以满足应急救灾的科学决策和应用需要,现已成为应急救灾数据库多时相数据管理的难点。多时相数据的存取也满足长尾理论,即大部分的数据库存取集中在少部分的现势性数据上[2]。显然,应该使活跃的现势性地形数据能便于有效存取。然而,传统的时态数据模型和数据组织结构,只是在概念和逻辑层面实现多时态数据组织的完整性,包括序列快照模型、基图修正模型、空间-时间组合体模型和空间-时间立方体模型等[3,4],并没有考虑不同时态数据的存取权重,物理实现统一采用磁盘存储,导致磁盘I/O成为数据库调度性能的瓶颈,极大地增加了磁盘I/O负荷和数据调度时间。如果将存取频率高的现势性地形数据存储在内存上,将历时数据存储在磁盘上,现势性地形数据的调取就可以消除内外存的磁盘I/O。这样不仅可以降低用户并发环境下服务器端磁盘的吞吐压力,也可以保证客户端的调度和绘制效率。为此,本文设计了多时态地形数据的组织模型,并充分挖掘分布式数据库MongoDB的性能优势,提出了基于MongoDB数据库的多时态地形数据存储管理优化方法。1多时态地形数据组织概念模型传统的静态GIS只涉及地理信息的空间维度和属性维度。对于语义更丰富、对现实世界描述更准确的时间维度,如何将其与空间和属性维度有机结合,保证“时空效率”,是多时态海量数据模型建立的难点。传统的时态GIS数据模型,包括序列快照模型、基图修正模型、空间-时间组合体模型和空间-时间立方体模型等[3,4],都只在时空数据管理的共性问题上提出了解决方案。在具体的时间、空间和属性的有机结合的应用中,还需要结合应用特点,从共性与特性出发,构建符合应用需要的时态数据模型。地形数据通常按照图层来组织。将不同时态的地形数据组织成不同的图层,并根据数据获取的时间依次排序,即新数据在上,旧数据在下,叠置显示。在应急救灾应用中,图层的最下层为覆盖全国或全球的低精细程度的地形数据,向上根据时间的早晚,依次叠置不同时态的受灾区域精细化的地形数据。考虑到应急救灾多时态数据库为基础数据库,不同时态地形图层之间独立存储,故可通过经纬度坐标隐式关联。对于表达地理时间最重要的变化,则通过上层的分析模块,根据几何位置、形状和范围,以及纹理的灰度和颜色等因素进行分析判断。故序列快照模型可满足多时态地形数据基本的管理需要。图1基于快照的多时态地形数据Fig.1Multi-TemporalTerraindataBasedonSnapshot由于天气和云雾等外在因素的影响,导致人为操作和地形传感器数据的采集存在测量误差,不同时态的数据范围会存在差异。当出现新数据的覆盖范围小于历史数据时,对于新数据未覆盖的区域,则采用该区域最新的历史数据进行代替,该应用特性满足基图修正模型。鉴于此,多时态地形数据模型采用快照模型和基图修正模型的折衷模型。即不同时态的地形数据采用快照来表示,某一时态的地形数据的缺失部分采用基图修正模型表示。图2基于修正模型的多时态叠置Fig.2Multi-TemporalOverlaybasedonCorrectionModel由于地形数据具有覆盖范围广和数据量大的特点,若仍以图幅为管理单元,难以满足实时可视化数据高效调度和绘制的需要[5]。因此,构建地形金字塔模型,即将异源异构数据整合到统一坐标系,按照规则的空间范围进行格网划分,并采用四叉树模型,为地形不同细节层次的格网间建立映射关系[6]。通过细化数据存储和调度的最小单元,建立层次结构,保证海量地形数据的调度。并按照视距和视点范围,由远到近、由局部到整体,高效调度并流畅显示。2多时态地形数据组织管理方法2.1基于元数据的时态信息管理时间、空间和属性是地理实体和地理现象本身所具有的三个基本特征,是反映地理实体的状态和演变过程的重要组成部分。由于地形数据本身并不包含时间信息,所以常将其作为地形数据的语义进行扩展,并通过结构化描述来统筹管理。按照xml文件管理的时态信息,地形根节点包括DemDB和DomDB两个数据子节点,每个子节点为每一个受灾区域建立一个工程节点,每个工程节点映射一个数据库节点,每个数据库节点映射一个或多个时态节点,时态节点存储地形数据的时间信息和地形范围信息。图3多时态元信息数据结构Fig.3DataStructureofMulti-TemporalMetadata客户端连接多时态地形数据库时,首先获取该时态元文件,解析得到工程、数据库和时态信息,并用树状控件显示。点击某受灾区域的工程节点,定位到该受灾区域,可显示最新的地形数据。如果需要回溯查看历史状态,点击树状控件中的历史节点或者界面中的时间进度条,可查看该受灾区域的历史状态。2.2基于时间戳的时态地形数据存储管理地形数据通过地形金字塔划分为规则格网,每一个地形格网块通过惟一标识码进行索引。地形格网块惟一标识码由三方面信息(L,(x,y))组成,其中L表示LOD的层级;x表示格网行号;y表示格网列号[7]。考虑到地形数据格网划分的规则相同,同一受灾区域不同时态地形格网的名称相同,故需要采用格网ID和时间戳的混合键值进行索引。通过视域范围内的格网ID和时间信息,能够快速调度目标区域和目标时态的地形数据。3基于MongoDB存储管理的优化方法传统的存储系统采用集中的存储服务器存放所有的数据。现有的存储服务器已成为提供系统性能的瓶颈,也是可靠性和安全性的焦点,不能满足大规模存储应用的需要。分布式存储系统采用可扩展的系统结构,利用多台存储服务器分担存储负荷,利用位置服务器定位存储信息,不但提高了系统的可靠性、可用性和存取效率,还易于扩展。考虑到多时态地形数据的数据量大,且随着时间的延长,数据不断增加的特点,故单数据中心的存储模式难以支持海量数据的高效存储和调度效率。而将海量的多时态地形数据存储在高性能、易水平扩展的非关系型数据库MongoDB中,并结合多时态地形数据的应用特点,提出了存储优化方法。通过分散存储和并行调度,可提高海量多时态地形数据的调度效率,支持流畅浏览和分析应用的需要。3.1支持海量数据的分布式存储MongoDB提供自动分片(Auto-Sharding)的分布式存储功能[8]。即通过路由服务器mongos,自动建立一个水平扩展的数据库集群系统,将数据库表分散存储在sharding的各个节点上。通过将数据拆分,将其分散存储在不同数据服务器的节点,让更多的机器来处理不断增加的负载和数据。并通过并行读写,提高I/O的吞吐能力。数据分片对用户透明,客户端在连接MongoDB数据库时,并不知道数据已经被拆分,也不知道拆分的数据存储在哪些数据服务器的节点中。用户发送查询请求,通过路由服务器mongos,查找到存在于各个分片节点的数据,通过并行读取和打包聚合,最终返回给客户端。分布式数据库MongoDB的sharding节点便于水平扩展。当集群存储接近饱和时,通过简单的“addshard”命令,便可添加新的分片节点,并支持数据的自动迁移和平衡。为了提高集群的安全性,MongoDB提供ReplicaSet数据备份模式,为每个sharding节点建立复制集,同步备份;当某个节点宕机时,主节点切换到备份节点上,不影响整个集群系统的使用,具有极强的自动容错(auto-failover)和自动恢复(auto-recovery)功能。此外,通过ReplicaSet来实现读、写分离,即由备份节点来分担读的压力,主节点只承担写操作。虽然备份节点数据的一致性存在一定的延迟,但极大地减小了主节点的读写压力。MongoDB分布式存储时,需要从集合里面选一个键,用该键的值作为数据拆分的依据。这个键成为片键。片键的选择,决定了插入操作在片之间的分布[9]。如果选择ID作为片键,每个片服务器存储一定连续ID范围的数据。如果选择时间戳作为片键,每个片服务器包含在一定时间范围内的所有数据。假设其中一片包含时间戳在“2013.10.15”以前的文档,则另一片包含时间戳在“2013.10.15”以后的文档。如果新文档的时间戳在“2013.10.15”之前,则会添加到第一片中,否则会添加到第二片中。随着数据量的增加或删除,MongoDB会重新平衡数据范围,使每片的流量比较均衡,数据量也在合理范围内。考虑到时间戳是升序片键,会导致写压力持续在单一分片节点上,无法分担热点压力。因此,时间戳不能作为独立的片键。地形格网ID的基数大,避免了小基数片键限制分布式集群的分片个数的缺陷。而采用格网ID进行分片,可实现多时态地形数据的分散存储和并行调度。3.2支持现势性数据快速查询的时空混合索引不同时态地形数据的覆盖范围存在差异。对于缺失区域,往往采用缺失时间点之前的最新历史数据,以降低缺失区域与周边区域之间颜色和纹理的跳跃感,提高地形的视觉效果。但该应用特点导致需提前判断某时态地形块是否存在。若当某地形块不存在时,需要按时间顺序搜索下一时态的地形块,直到搜索成功。这一查询方式产生了大量的无用操作,增加了数据调度的负荷。尤其是对存取频率高的现势性地形数据,在多用户并发访问的环境下,该查询方式的性能瓶颈格外突出。在分布式数据库MongoDB中,对于复合索引,如果查询条件包含复合索引中的前N个索引列,子集的查询同样可以使用该复合索引。在MongoDB中,建立格网ID和时间戳的混合索引{TileID:1,TimeStamp:-1},时间戳采用逆序排列。那么在通过格网ID查询时,虽然存在不同时态的同名格网数据,但是因为按照时间戳逆序排列,所以返回的是最新时态的地形格网,可满足现势性数据的存取需要。因此,基于MongoDB的该特性,在地形入库时,建立格网ID和时间戳的混合索引,时间戳逆序排列。在调度现势性数据时,根据格网ID,即可从数据库中检索和调度到最新的地形数据。3.3内外存协同的现势性数据优化方法内存中数据的读写速度要比磁盘中的高出几个数量级。将数据保存在内存中访问,相比将数据保存在磁盘中访问,能极大地提高应用的性能。但是内存的容量有限,不能容纳整个数据库。考虑到用户浏览往往关注现势性数据,若能将高频访问的现势性数据保存在内存中,将历史数据保存在磁盘中,能极大地提高用户的访问效率。考虑到MongoDB使用内存映射文件进行数据管理,故可把所有空闲内存当缓存使用。当分片服务器具有大内存时,如何利用MongoDB内存映射的性能特点,在内存中管理现势性地形数据,是实现高频访问现势性地形数据的高效调度的关键。在MongoDB中,以时间戳为键值划分数据,可以保证新数据保存在内存中。但是,如3.1节所讨论的,时间戳是升序片键,会导致写压力持续在单一分片节点上,无法分担热点压力,故不能作为独立的片键。大基数的地形格网ID,虽然保证了分散存储的平衡性,但是无法区分时态信息,导致现势性数据和历史数据都均衡存储在内存和磁盘中。鉴于此,将分片的键值增加时间属性,即键值为格网ID和时间的组合片键,数据不仅按照空间位置分片,也按照时间顺序分片。这样既保证数据均衡分散在集群中,又能把新数据保持在内存中。为此,本文采用{TimeStamp:1,TileID:1}组合键来做分片。在导入2013年10月份的数据时,若采用两台片服务器,则数据自动分割成两块。如:((-∞,-∞),(2013-10,10-536-427))[(2013-10,10-536-427),(∞,∞))所有的写操作都会被均匀地分布到两个块上。例如,所有瓦片ID小于10-536-427的数据会被写入块1中,所有瓦片ID大于10-536-427的数据会被写入块2中。若内存容量足够大,MongoDB会将10月份的数据保存在内存中,将2013年10月以前的历史数据保存在磁盘中,分布存储。等到11月数据更新,MongoDB又开始创建2013-11的分布式