阿里云安全

阿里云InfluxDB®教你玩转A股数据

2019-11-05 00:00:00 mimukeji

阿里云InfluxDB®目前已经商业化,专注于处理高写入和查询负载的时序数据,用于存储大规模的时序数据并进行实时分析,包括来自DevOps监控、车联网、智慧交通、金融和IOT传感器数据采集。
本文首先介绍时序数据库的发展,然后具体介绍阿里云InfluxDB®的功能。由于金融中股票交易具有高频和时间属性,非常符合InfluxDB的应用场景,最后提供了一个在阿里云InfluxDB® 创建的TIG(Telegraf/InfluxDB/Grafana)实例信息,采集了部分沪深股票交易信息,供用户登陆操作实践,更深入地了解时序数据和阿里云InfluxDB®。

时序数据

时序数据发展

时序数据发展到当下,主要经历了三个阶段:基于关系型数据库的存储,基于通用大数据的存储系统,以及垂直型时序数据库系统。每个阶段均出现代表性产品,如RRDTool, OpenTSDB, InfluxDB等。

  • 基于关系型数据库存储:这类系统处理的数据模型比较单一,缺乏针对时间的特殊优化,单机容量受限,处理时序数据的效率相对不高;
  • 基于通用大数据存储:伴随着大数据和Hadoop的发展,借助HBase等存储系统,利用时序的特性规避部分通用存储的劣势,在数据模型设计方面做了很多的改进,但时序的发展与存储发展路线不统一,缺乏定制化,往往会受制于底层存储,如索引技术,查询过滤机制等。
  • 垂直型时序数据库:随着kubenetes, 微服务,IOT市场的崛起,针对时序数据的存储产品慢慢涌现,如InfluxDB专门针对时序的TSM存储引擎,Gorilla压缩,以及面向时序的窗口计算函数p99等。
    image

当前时序数据库呈现百家争鸣的状态,传统数据库朝着分布式方向发展,如TimeScaleDB;OpenTSDB紧跟大数据的存储计算分离架构;InfluxDB TICK集成数据采集、分析和告警等。上图是DB Engine给出的关于时序数据库的排名,InfluxDB位于最受喜爱的时序数据库行列,也是阿里云将其开源托管的重要原因。

时序数据模型

下面将针对于InfluxDB数据模型来介绍时序数据。
image

  • 时间线(time series): 测量值(measurement)与标签(tagset)的组合
  • 时间点(time series point): 一个具体的时间戳下,某条时间线中,某些field的值。

    时间线用于在写入和查询时对数据做快速匹配,关联时序数据索引,因此时间线的膨胀会引起时序索引结构膨胀,占用过多内存空间和匹配效率降低。在股票交易数据结构中,由于股票代码(code), 股票名称(name), 所属行业(industry)并不经常改变,因此在模型设计的过程中,可以将这些设为tagkey;成交价格(price),成交手(volume),成交金额(amount)这些要记录的值随时间会不断变动,我们将其放入field中,进行数值存储和函数计算。上图中:

时间线:

tick_data,industry=银行,name=平安银行,code=000001.SZ

时间点:

tick_data,industry=银行,name=平安银行,code=000001.SZ price=10.86,volume=2295,amount=2492370 2015-09-23T09:25:01Z
tick_data,industry=银行,name=平安银行,code=000001.SZ price=10.85,volume=128,amount=138847 2015-09-23T09:30:32Z

时序数据写入

关于阿里云InfluxDB®实例的购买和时序数据的写入具体可以参考阿里云官方文档
image
如上图所示的存储结构中,为了更好管理历史数据,InfluxDB推出了数据保留策略(Retention Policies),用来定义数据的保留时间。数据保留策略(RP) 用来定义数据在InfluxDB中存放的时间,或者定义保存某个期间的数据。在阿里云InfluxDB®管理控制台,我们可以自定义历史数据的保留时长。
下面为采集A股日成交(daily)和日行情(tick_data)的时间线情况:

> use stock
Using database stock
> show series limit 10
key
---
daily,area=上海,industry=IT设备,list_date=19901219,name=方正科技,symbol=600601,code=600601.SH
daily,area=上海,industry=IT设备,list_date=20170607,name=恒为科技,symbol=603496,code=603496.SH
daily,area=上海,industry=专用机械,list_date=20150320,name=创力集团,symbol=603012,code=603012.SH
daily,area=上海,industry=专用机械,list_date=20150527,name=华铭智能,symbol=300462,code=300462.SZ
daily,area=上海,industry=专用机械,list_date=20150630,name=沃施股份,symbol=300483,code=300483.SZ
daily,area=上海,industry=专用机械,list_date=20160607,name=上海沪工,symbol=603131,code=603131.SH
daily,area=上海,industry=专用机械,list_date=20160812,name=上海亚虹,symbol=603159,code=603159.SH
daily,area=上海,industry=专用机械,list_date=20161018,name=古鳌科技,symbol=300551,code=300551.SZ
daily,area=上海,industry=专用机械,list_date=20170113,name=至纯科技,symbol=603690,code=603690.SH
daily,area=上海,industry=专用机械,list_date=20170314,name=克来机电,symbol=603960,code=603960.SH
> use tick
Using database tick
> show series limit 10
key
---
tick_data,area=上海,industry=区域地产,list_date=19961210,name=荣丰控股,symbol=000668,code=000668.SZ
tick_data,area=上海,industry=区域地产,list_date=19970925,name=三湘印象,symbol=000863,code=000863.SZ
tick_data,area=云南,industry=中成药,list_date=19931215,name=云南白药,symbol=000538,code=000538.SZ
tick_data,area=云南,industry=全国地产,list_date=19961205,name=美好置业,symbol=000667,code=000667.SZ
tick_data,area=云南,industry=房产服务,list_date=19940202,name=我爱我家,symbol=000560,code=000560.SZ
tick_data,area=云南,industry=机械基件,list_date=19990415,name=云内动力,symbol=000903,code=000903.SZ
tick_data,area=云南,industry=铜,list_date=19980602,name=云南铜业,symbol=000878,code=000878.SZ
tick_data,area=云南,industry=铝,list_date=19980408,name=云铝股份,symbol=000807,code=000807.SZ
tick_data,area=内蒙,industry=化工原料,list_date=19970131,name=远兴能源,symbol=000683,code=000683.SZ
tick_data,area=内蒙,industry=煤炭开采,list_date=19970606,name=平庄能源,symbol=000780,code=000780.SZ

函数分析

InfluxDB提供了丰富的计算函数帮助我们进一步挖掘数据的价值。InfluxQL函数分为四大类:聚合(aggregate)、选择(select)、转换(transform)和预测(predict)。

聚合

阿里云InfluxDB®支持的聚合函数有:COUNT()DISTINCT()INTEGRAL()MEAN()MEDIAN()MODE()SPREAD()STDDEV()SUM()
查询某支股票2019-10-21日共成交了多少手:

> select sum(volume) from tick_data where code='000001.SZ' and time >= '2019-10-21T00:00:00Z' and time <= '2019-10-21T23:59:59Z'
name: tick_data
time                 sum
----                 ---
2019-10-21T00:00:00Z 945952

查询某支股票2019-10-21日每小时的成交额(元):

> select sum(amount) from tick_data where code='000001.SZ' and time >= '2019-10-21T00:00:00Z' and time <= '2019-10-21T23:59:59Z' group by time(1h)
name: tick_data
time                 sum
----                 ---
2019-10-21T00:00:00Z
2019-10-21T01:00:00Z
2019-10-21T02:00:00Z
2019-10-21T03:00:00Z
2019-10-21T04:00:00Z
2019-10-21T05:00:00Z
2019-10-21T06:00:00Z
2019-10-21T07:00:00Z
2019-10-21T08:00:00Z
2019-10-21T09:00:00Z 363351603
2019-10-21T10:00:00Z 531834212
2019-10-21T11:00:00Z 88167896
2019-10-21T12:00:00Z
2019-10-21T13:00:00Z 207135153
2019-10-21T14:00:00Z 372167894
2019-10-21T15:00:00Z 26619332
2019-10-21T16:00:00Z
2019-10-21T17:00:00Z
2019-10-21T18:00:00Z
2019-10-21T19:00:00Z
2019-10-21T20:00:00Z
2019-10-21T21:00:00Z
2019-10-21T22:00:00Z
2019-10-21T23:00:00Z

选择

阿里云InfluxDB®支持的聚合函数有:BOTTOM()FIRST()LAST()MAX()MIN()PERCENTILE()SAMPLE()TOP()
查询某支股票2019-10-21日P99的成交价格:

> select percentile(price, 90) from tick_data where code='000001.SZ' and time >= '2019-10-21T00:00:00Z' and time <= '2019-10-21T23:59:59Z'
name: tick_data
time                 percentile
----                 ----------
2019-10-21T10:27:42Z 16.91

随机对某支股票2019-10-21日9:00am~3:00pm成交价格进行平均采样:

> select sample(price, 10) from tick_data where code='000001.SZ' and time >= '2019-10-21T09:00:00Z' and time <= '2019-10-21T15:00:00Z'
name: tick_data
time                 sample
----                 ------
2019-10-21T10:27:18Z 16.93
2019-10-21T11:02:48Z 16.82
2019-10-21T11:11:36Z 16.87
2019-10-21T13:19:21Z 16.78
2019-10-21T13:22:24Z 16.77
2019-10-21T13:41:09Z 16.78
2019-10-21T13:44:18Z 16.78
2019-10-21T14:19:15Z 16.83
2019-10-21T14:19:21Z 16.83
2019-10-21T14:22:30Z 16.85

转换

阿里云InfluxDB®支持的转换函数有:ABS()ACOS()ASIN()ATAN()ATAN2()CEIL()COS()CUMULATIVE_SUM()DERIVATIVE()DIFFERENCE()ELAPSED()EXP()FLOOR()HISTOGRAM()LN()LOG()LOG2()LOG10()MOVING_AVERAGE()NON_NEGATIVE_DERIVATIVE()NON_NEGATIVE_DIFFERENCE()POW()ROUND()SIN()SQRT()TAN()
计算某支股票2019-10-21日每15分钟成交价格的变化:

> select derivative(mean(price)) from tick_data where code='000001.SZ' and time >= '2019-10-21T00:00:00Z' and time <= '2019-10-21T23:59:59Z' group by time(15m)
name: tick_data
time                 derivative
----                 ----------
2019-10-21T09:30:00Z 0.18167224080267985
2019-10-21T09:45:00Z 0.049361092530652684
2019-10-21T10:00:00Z 0.13140000000000995
2019-10-21T10:15:00Z 0.10268372352284771
2019-10-21T10:30:00Z 0.02356981183064022
2019-10-21T10:45:00Z -0.02005673170050315
2019-10-21T11:00:00Z -0.056542594898782994
2019-10-21T11:15:00Z 0.02164948213387774
2019-10-21T11:30:00Z -0.0037370242214223026
2019-10-21T13:00:00Z -0.009116331096188665
2019-10-21T13:15:00Z -0.026667201136095997
2019-10-21T13:30:00Z -0.010301478953412158
2019-10-21T13:45:00Z 0.03505827505824399
2019-10-21T14:00:00Z 0.029964323811768168
2019-10-21T14:15:00Z 0.012986349675813358
2019-10-21T14:30:00Z 0.02997171129489118
2019-10-21T14:45:00Z 0.026839533796877646
2019-10-21T15:00:00Z -0.013153526970953067

计算某支股票2019年10月的月K线情况:

> SELECT moving_average(last("close"), 30) FROM "daily" WHERE ("code" = '000001.SZ') AND time >= '2019-09-01T00:00:00Z' and time <= '2019-10-31T00:00:00Z' GROUP BY time(1d) fill(previous)
name: daily
time                 moving_average
----                 --------------
2019-10-01T00:00:00Z 14.985999999999994
2019-10-02T00:00:00Z 15.023999999999994
2019-10-03T00:00:00Z 15.066999999999991
2019-10-04T00:00:00Z 15.105333333333325
2019-10-05T00:00:00Z 15.13899999999999
2019-10-06T00:00:00Z 15.16499999999999
2019-10-07T00:00:00Z 15.19099999999999
2019-10-08T00:00:00Z 15.237333333333321
2019-10-09T00:00:00Z 15.289333333333323
2019-10-10T00:00:00Z 15.345666666666656
2019-10-11T00:00:00Z 15.420666666666655
2019-10-12T00:00:00Z 15.491666666666655
2019-10-13T00:00:00Z 15.562666666666654
2019-10-14T00:00:00Z 15.64733333333332
2019-10-15T00:00:00Z 15.730666666666654
2019-10-16T00:00:00Z 15.808666666666655
2019-10-17T00:00:00Z 15.890666666666654
2019-10-18T00:00:00Z 15.960666666666652
2019-10-19T00:00:00Z 16.01633333333332
2019-10-20T00:00:00Z 16.05533333333332
2019-10-21T00:00:00Z 16.10699999999999
2019-10-22T00:00:00Z 16.14299999999999
2019-10-23T00:00:00Z 16.177666666666656
2019-10-24T00:00:00Z 16.21899999999999
2019-10-25T00:00:00Z 16.241333333333323
2019-10-26T00:00:00Z 16.264999999999993
2019-10-27T00:00:00Z 16.282333333333327
2019-10-28T00:00:00Z 16.29966666666666
2019-10-29T00:00:00Z 16.316999999999997
2019-10-30T00:00:00Z 16.344666666666665
2019-10-31T00:00:00Z 16.372333333333334

预测

阿里云InfluxDB®支持的预测函数有:HOLT_WINTERS()
HOLT_WINTERS采用季节性方法返回N个预测的Field Value。HOLT_WINTERS可用于:

  • 预测时间什么时候会超过给定的阈值
  • 将预测值与实际值进行比较,检测数据中的异常
    对降雨量和气温的预测我们常常可以采用此方法,由于股票交易周期性不明显,在此便不再赘述。

报表展示

Grafana接入阿里云InfluxDB®可以参考文档,下图在Grafana上展示了某支股票近5年的交易情况:
image

数据告警

Grafana告警

如下图所示,Grafana支持简单的数据告警,用户可以根据需求自定义告警规则:
image

Kapacitor告警

Kapacitor作为TICK生态中的数据处理框架,用于告警、ETL(Extract-Transform-Load)和检测异常。主要特性包含:

  • 既可以处理流数据(streaming data),也可以处理批量数据(batch data)
  • 定期从InfluxDB查询数据,执行InfluxQL支持的函数,并将处理结果存回InfluxDB
  • 支持添加用户自定义的函数检测异常
  • 与HipChat、OpsGenie、Alerta、Sensu、PagerDuty和Slack等集成

    下面的price.tick脚本以batch的方式处理某支股票的成交价格并设置告警提示:

batch
    |query('''
        SELECT max(price) AS mprice
        FROM "tick"."rp1"."tick_data"
        WHERE "code" = "000001.SZ"
    ''')
        .period(1d)
        .cron('*/5 * * * *')
    |alert()
        .warn(lambda: "mprice" >= 18.5)
    |influxDBOut()
        .database('alert')
        .measurement('price')
        .tag('kapacitor', 'true')

运行kapacitor define max-price -tick price.tick -type batch -dbrp tick.rp1 和kapacitor enable max-price便会每5分钟以batch的方式获取股票最高成交价格并告警提示,在alert中可以添加email或者hook推送报警。

总结

目前集成TIG(Telegraf/InfluxDB/Grafana)生态的阿里云InfluxDB®已经上线,用户可以在阿里云官网直接购买。当前我们采集了一些沪深股票的日线、历史交易日的分笔数据,以及实例运行主机的cpu、磁盘、内存监控,提供展示Demo供用户实践更好地了解时间序列数据和阿里云InfluxDB®。

image

参考文献

  1. 浅谈时序数据库那些事
  2. TSDB for InfluxDB®与自建InfluxDB对比优势
  3. 阿里云时序数据库InfluxDB®主页
  4. 5分钟快速完成系统监控搭建实践

阿里云优惠新机+优惠券

本文转载自网络,如有侵权,请联系我们删除。

COPYRIGHT © 2018-2019,WWW.51MIMU.COM,ALL RIGHTS RESERVED版权所有 © 广州米姆信息科技有限公司 粤ICP备18145377号

地址:广州市天河区广园东路2191号时代新世界中心南塔21楼07、08单元 电话:020-22822863
14737363737