Influxdb自定义数据采样(CQ)
来源:互联网 发布:东北林大网络教学平台 编辑:程序博客网 时间:2024/06/05 20:48
Influxdb提供了两种方式来进行数据的整合Continuous Queries (CQ:连续查询) 和 Retention Policies (RP:保留策略)。这两种方式结合使用,在降低精度的前提下,既可以保留很久以前的数据,又可以减轻数据所占用系统资源。一般都把连续查询成为数据采样,相信看这篇文章的朋友都对这些有所了解。
官网上提供的数据采样精度最大只能到周,如果我想实现按月采样,按季度采样后者按年采样,使用Influxdb的CQ是无法实现的,必须要自己来处理。
这里我们说下用JAVA来实现数据的自定义时间采样,其它语言也是同样道理,也可参考。
首先我们说下需求,对现有数据进行按天采样和按月采样。
先造数据:
从现在开始往前几百个小时,每小时一条,其中myname和address是tag,age是field,这里按照平均年龄采样。
注:name在Influxdb中类似于关键字的存在,所以最好别用,如果使用的话,一般查询的时候需要加引号。
首先按照日采样,这个功能Influxdb的CQ就能完成,这里我们采用代码的方式来实现,方便下面月的采样的理解。
先说明下采样执行的sql:
select mean(age) as age into database.rp.day_test from database.rp.mytest where time >=startTime and time <endTime group by time(1h),*
注:
1、这个sql可以在CQ执行的时候通过influx的日志获取到。
2、其中被采样的表我在执行的时候有时加上database和rp的时候查询不到,下面我把被采样的表的数据库和保留策略都省掉。但是采样之后的数据插入表必须要说明数据库和保留策略。
3、group by time(1h)这里的时间是根据自己的采样区间设定的,设定的时候如果时间不大于1h可以直接设定单位,如果大于1h,如1d就需要考虑时间偏移了。而我们这里的startTime和endTime就是我们的采样区间,直接就确定了这里time中的时间,所以我们把time()给省掉,这也是我们能够实现月采样或者季度年等实现的关键。去掉后startTime会成为被采样之后所有数据的时间,整合符合需求。
4、group by中的*表示所有的tag,如果只需要其中某些tag可以单独列出来。
日采样,我们设定每天执行一次(或者几次),这个跟CQ逻辑一样。看代码:
public void dayCQ(){ HashMap<String,String> hashMap=this.yesterdayTimeZone(); String url="http://localhost:8086/query?db=billingrecord"; MultiValueMap<String,String> postParameter=new LinkedMultiValueMap<>(); String q="SELECT mean(age) as age INTO billingrecord.rp_90d.day_test FROM mytest WHERE time >="+hashMap.get("startTime")+" AND time < "+hashMap.get("endTime")+" group by *"; System.out.println("q:"+q); postParameter.add("q",q); RestTemplate restTemplate=new RestTemplate(); restTemplate.postForObject(url,postParameter,Object.class); } //获取起始时间和结束时间,为了避免时间差,我这里直接使用的时间戳public static HashMap yesterdayTimeZone(){ long zero = System.currentTimeMillis()/(1000*3600*24)*(1000*3600*24) - TimeZone.getDefault().getRawOffset(); long startTime=zero-3600*24*1000; long endTime=zero; HashMap<String,String> hashMap=new HashMap(); hashMap.put("startTime",startTime+"000000"); hashMap.put("endTime",endTime+"000000"); return hashMap; }
执行之后的day_test表:
所有的时间点都落在了Utc时间的24日16点,转成东八区时间正好是15日0点。
做一下特殊处理,对mytest中所有数据都分别进行日采样,以便我们执行月采样:
public void dayCQ(){ for(int i=1;i<100;i++){ HashMap<String,String> hashMap=this.yesterdayTimeZone(i); String url="http://localhost:8086/query?db=billingrecord"; MultiValueMap<String,String> postParameter=new LinkedMultiValueMap<>(); String q="SELECT mean(age) as age INTO billingrecord.rp_90d.day_test FROM mytest WHERE time >="+hashMap.get("startTime")+" AND time < "+hashMap.get("endTime")+" group by *"; System.out.println("q:"+q); postParameter.add("q",q); RestTemplate restTemplate=new RestTemplate(); restTemplate.postForObject(url,postParameter,Object.class); } }public static HashMap yesterdayTimeZone(int num){ long zero = System.currentTimeMillis()/(1000*3600*24)*(1000*3600*24) - TimeZone.getDefault().getRawOffset(); long startTime=(zero/1000-3600*24*num)*1000; long endTime=(zero/1000-3600*24*(num-1))*1000; HashMap<String,String> hashMap=new HashMap(); hashMap.put("startTime",startTime+"000000"); hashMap.put("endTime",endTime+"000000"); return hashMap; }
这里在正常采样中是用不到的,只是为了测试写的,另外注意处理时间数据,很可能会出现数值越界。
现在我们在日采样的基础上进行月采样:
public void monthCQ(){ HashMap<String,String> hashMap=this.lastMonthTimeZone(); String url="http://localhost:8086/query?db=billingrecord"; MultiValueMap<String,String> postParameter=new LinkedMultiValueMap<>(); String q="SELECT mean(age) as age INTO billingrecord.rp_90d.month_test FROM rp_90d.day_test WHERE time >="+hashMap.get("startTime")+" AND time < "+hashMap.get("endTime")+" group by *"; postParameter.add("q",q); RestTemplate restTemplate=new RestTemplate(); restTemplate.postForObject(url,postParameter,Object.class); }public static HashMap lastMonthTimeZone(){ SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM"); Calendar cal=Calendar.getInstance(); String endTime=sdf.format(cal.getTime()); cal.add(Calendar.MONTH,-1); String startTime=sdf.format(cal.getTime()); try { startTime=sdf.parse(startTime).getTime()+"000000"; endTime=sdf.parse(endTime).getTime()+"000000"; }catch (Exception e){ System.err.println("InfluxDB time deal error"); } HashMap<String,String> hashMap=new HashMap(); hashMap.put("startTime",startTime); hashMap.put("endTime",endTime); return hashMap; }
执行的sql为:
SELECT mean(age) as age INTO billingrecord.rp_90d.month_test FROM rp_90d.day_test WHERE time >=1498838400000000000 AND time < 1501516800000000000 group by *
注:不知道为啥,这次测试的时候time< 1501516800000000000这个一直没法使用,在其它表中都是ok的,只要加上time<这个判断就没数据,不过每月的第一天执行其实不加time<,对日进行采样,获取的数据都是一样的。这个我会继续测试找出具体原因。
看下结果:
换算成东八区之后时间都落在7月1号的零点。
按照季度采样和按照年采样也按这种方式执行就OK。
- Influxdb自定义数据采样(CQ)
- spring对接InfluxDB(一)--创建数据库和数据写入
- spring对接InfluxDB(三)--数据获取之多条语句
- 数据采样
- InfluxDB数据备份与恢复
- InfluxDB
- InfluxDB
- 时间序列(二)数据重采样
- 特征工程(2)--数据采集、数据清洗、数据采样
- [CQ省队互测Round1](受虐记)
- [CQ省队互测Round2](酱油记)
- [CQ省队胡策Round3](出题记)
- spring对接InfluxDB(二)--数据获取之单条查询
- 通过HTTP API 向InfluxDB传入数据
- 时序数据监控系统Influxdb+Grafana+Fluented
- FL2440 ADC 数据采样
- oracle中的采样数据
- 【CQ】如何查询duplicate类型的上下游数据
- java interface 接口 及 接口的调用 实例及误区
- java执行字符串中的运算公式
- 缓存第五篇:无框架的自定义页面缓存---从后台到页面
- C中函数的声明
- 语音口令红包软件系统开发
- Influxdb自定义数据采样(CQ)
- 数据库的备份与恢复
- 面试集锦
- java读入一个不确定长度的一维数组
- [知了堂学习笔记]_EasyUi快速搭建一个权限管理的模块(1)--RBAC概述和数据库设计
- java面向对象
- hdoj 1856 More is better 【并查集 求最大节点数】
- kali终端快捷键-如何给kali linux终端添加快捷键
- 【Android】AlertDialog对话框