小 T 导读:作为地震监测的核心业务单位,中国地震台网中心承担着全国乃至全球地震监测任务。在地震发生后,台网中心的科学家会第一时间进行震源定位并为公众提供地震速报信息。地震波形数据就是各地震台站的直接观测数据。通过对地震波的到时分析地震学家们可以来分析地震发生时间、定位震源、计算震级等。本文介绍一种用时序数据库TDengine来存储归档地震波形数据的新思路。
业务场景
地震监测业务可简化成数据采集、数据传输和数据处理三部分。其中数据采集使用的设备一般为地震计(可视为特殊的物联网采集设备),其由多个国家布设在全球各地(如图1),并7×24小时不间断测量和记录当地的地面运动数据供各国使用。采集的数据通过有线或无线网络传输至台网中心,台网中心的数据处理软件采用人工交互处理或自动处理方式对数据进行处理,监测全国和全球的地震活动情况。
近几年,随着国家对防震减灾要求不断提高,我国先后实施了多个大型地震监测工程项目,优化和加密观测台网和观测仪器(如地震计),预计未来几年,用于数据采集的地震计数量将会呈数量级增长,并且随着物联网的发展,将会有更多数据接入用于地震监测。因此,原有在单台机器上运行的地震数据处理软件(如地震自动测定软件)的数据处理压力会越来越大。同时海量数据的汇入,对数据存储、管理、回溯等都提出了新的要求。
为了解决海量数据处理和存储的问题,中国地震台网中心地震科学开放实验室研发团队开发了SeisFLINK2地震自动监测系统(如图2)。SeisFLINK2系统是基于大数据技术构建系统框架,并集成地震专业处理模块的地震实时流处理平台。其使用Kafka作为分布式消息交换子系统,实现海量地震数据的接入和交换;使用Ignite作为分布式数据缓存子系统,方便各地震数据处理模块获取近线数据用于地震数据处理;使用Flink对海量地震数据流进行实时处理(主要用于震相检测);正逐步使用TDengine Database替代HBase实现地震数据的存储和检索(图2左下)。
用TDengine Database存储地震波形数据
我国的地震计一般1秒钟采集100次地面运动数据(100Hz),并定期(零点几秒至几秒)打包后向后方数据服务器传输数据,数据一般为国际通用的MiniSeed格式,一个数据包均包含头文件和数据文件,头文件包含数据元信息,如地震计所属台网、台站、通道、位置号、采样率、包数据起始时间和结束时间等。数据文件包括时间段内采样值。
按照业务需要,我们将MiniSeed数据分两部分存储。第一部分我们设计了一张超级表Seismometer,设有两个字段以及4个标签,ts为采样时间,value为采样值,四个tags分别为地震计对应的台网、台站、通道和位置号。我们为每个地震计创建了两张表(通过超级表创建),一张用于存储该地震计传输回来的数据,地震计的数据包经过解包后把采样点数据按照时间顺序存入该表中(如图5右侧所示)。另一张表记录每一个数据包的数据起始时间和结束时间。
第二部分对于长期保持不变的元数据信息如某个地震计的采样率,存储在固定文件中。这样做目的是虽然只需利用存储的采样值数据就可进行波形显示,但地震专业分析软件大多支持MiniSeed格式,因此考虑后续通过读取上述两部分数据,将元数据和采样数据还原成MiniSeed包,供地震专业分析软件使用。
在数据量方面,一个地震计一般1秒采样100次,在数据没有缺失的情况下,一天一张表约存储8,640,000条记录,共约5000张表。在这种数据量情况下,经简单测试,数据检索效率仍然很快。
在数据写入方面,采用C接口单线程批量的写入方式,一条波形一天的数据(17000个数据包)大概20秒就可以写完。按照接入1000多个台站计算,每秒就有1000多个包,大概消费时间在1.2秒,通过多线程消费入库,可比较轻松满足实时性要求。用Python接口会更方便,我也将从www.iris.edu拉取的地震数据并写入TDengine的Python程序开源,操作很简单,开源仓库地址:
https://github.com/schenton/seedlink2taos_py
在数据压缩率方面,由于原有MiniSeed包内数据已进行过压缩,故原有数据与TDengine数据占用磁盘空间比例约为1:1。TDengine压缩后的数据文件与未压缩的原始数据相比,压缩比大概在9.5%,还是相当优秀的。
集成Grafana做地震数据展示
为了将存入TDengine的地震数据利用起来,我们尝试利用grafana辅以简单的消息转发程序,成功将地震波形数据在grafana上进行显示。应用场景为在某个地震发生后,在grafana web页面上自动显示距震中最近6个台站(可理解为地震计)的波形数据。首先我们利用一个简单的python消息转发程序,在接收到新的地震事件后,计算得出距震中最近的6个台站,并将台站名写入MySQL的waveform_station表中。然后在grafana上配置6个变量用于动态表示6个台站,变量可定时从Mysql数据库中读取台站名(如图6)。这样我们就实现了在grafana中实时地显示最新地震的最近6个台站的波形变化,即不仅波形实时变化,各个面板中显示的台站也会随着地震事件而更新(如图8)。
最后,在grafana input sql中,用变量代表需要在TDengine中查询的表名,tbname1动态的表示为:seisflink.IU_RAO_00_BHZ(图7)。
采用TDengine的原因
我们接触TDengine时间不长,使用它的初衷是通用的大数据软件(如HBase等)的维护对人员的技术要求较高,不利于我们专业软件的推广和使用。同时,使用HBase存储MiniSeed数据后,按时间、按台站检索地震数据的效率并没有想象中的快。
相比之下,开源版TDengine的安装包只有不到5MB,对硬件资源也没有什么硬性要求,安装部署只需运行一个脚本,十分简单。对应用而言,TDengine没有区分历史和实时数据库,支持Ad Hoc查询,并且是SQL语法。这个就大大降低了开发的难度,不需要我们做分库分表的操作,并且可以做到大量地震波形数据的实时显示。TDengine的超级表设计也非常适合对各个台站数据的分片,每个台站的数据独立存放在各自的表中,但可以通过超级表统一过滤、查询,高效方便。
总结与展望
毫无疑问,TDengine是一款非常好的时序数据库(Time-Series Database)产品,轻量、高效、简单。经过前期的开发,它可以方便的将地震数据高速入库并快速地检索出来。但如果想要在地震业务中更好的得到应用,我们认为还需要在如何更方便的使用TDengine存储的地震数据上做文章:如何无缝的将地震专业分析软件与TDengine集成使用?
例如地震行业通用的python工具包obspy,它可通过webservice按时间,按台站方便的请求MiniSeed数据并实时进行滤波、仿真等数据处理。就像前面提到的,我们后续可能尝试在obspy的上层做一个数据接口,同样实现按台站、按时间从TDengine中获取采样点数据并打包成MiniSeed数据,供obspy、sac等地震专业软件使用。
同时TDengine的许多高级部分我们尚未完全挖掘应用,如流计算,某个时间段的最大值最小值等对我们量取地震波形数据峰值,计算震级等应该会有帮助,简化我们的开发,以后有机会继续深入研究和使用。
作者简介:陈通,中国地震台网中心地震科学技术开放实验室高级工程师,主要从事地震监测和地震应急,近年来专注于使用大数据技术来处理和分析地震数据。