Tdengine流式计算实现聚合查询

概要

之前业务需要实现聚合查询,使用taos流式计算实现,本文记录其中流式计算中遇到的坑。

流式计算概念

流式计算(Stream Processing),也称为实时流计算,是一种计算模式,它能够对连续生成的数据流进行实时处理和分析。与传统的批处理(Batch Processing)模式不同,流式计算不需要等待所有数据到齐后才开始处理,而是以数据产生为驱动,边接收数据边进行处理。
多用于物联网,金融等大量连续数据处理中

例如数采软件,近期数据存储原始数据,同时通过流式计算存储聚合数据,过期时删除原始数据,只查询聚合数据即可大大降低数据量

Taos流式计算语句

1.创建流式运算语句

CREATE STREAM [IF NOT EXISTS] stream_name [stream_options] INTO stb_name[(field1_name, ...)] [TAGS (create_definition [, create_definition] ...)] SUBTABLE(expression) AS subquery

其中stream_options中的参数为

stream_options: {
 TRIGGER        [AT_ONCE | WINDOW_CLOSE | MAX_DELAY time]
 WATERMARK      time
 IGNORE EXPIRED [0|1]
 DELETE_MARK    time
 FILL_HISTORY   [0|1]
 IGNORE UPDATE  [0|1]
}

TRIGGER:触发器,设置什么时候触发流式计算
WATERMARK:水印,判断时间戳是否已经计算
IGNORE_EXPIRED:是否忽略过期数据
DELETE_MARK:删除时间标记,超时自动删除
FILL_HISTORY:是否启动流式时计算历史数据
IGNORE_UPDATE:是否忽略修改数据

其中subquery的参数为

subquery: SELECT select_list
    from_clause
    [WHERE condition]
    [PARTITION BY tag_list]
    [window_clause]

subquery代表了定义的流式查询语句

创建聚合库

上面简单介绍了流式查询语句,下面根据聚合时间规划数据库
数据库 DATABASE_6M:用来存储6小时、1天、7天聚合
数据库 DATABASE_1Y:用来存储1月聚合

创建6小时聚合流语句

CREATE STREAM IF NOT EXISTS STREAM_6h fill_history 1 INTO DATABASE_6M.TABLE_NUMERICAL_6h SUBTABLE(CONCAT('p_6h_',id)) AS  SELECT _WSTART AS TS, MAX(POINTVALUE) AS MAX_VALUE ,MIN(POINTVALUE) AS MIN_VALUE, AVG(POINTVALUE) AS AVG_VALUE, FIRST(POINTVALUE) AS FIRST_VALUE, LAST(POINTVALUE) AS LAST_VALUE, APERCENTILE(POINTVALUE,50) AS APERCENTILE_VALUE, COUNT(POINTVALUE) AS COUNT_VALUE FROM DATABASE_3M.TABLE_NUMERICAL PARTITION BY EQPID ID  INTERVAL(6h) 

该语句创建STREAM_6h流,同时计算历史数据,定义了子表的命名规则为p_6h_加pid,间隔6小时
通过之前实现的createStream方法创建流

    @Override
    public void initStream() {
        //原始数据数据库名
        String originSource = TDengineDatabaseParamEnums.MONTH_THREE.getDatabaseName() + "." + TDengineConstants.TABLE_NUMERICAL_NAME;
        TDengineDatabaseParamEnums[] values = TDengineDatabaseParamEnums.values();
        for (TDengineDatabaseParamEnums value : values) {
            String databaseName = value.getDatabaseName();
            if (databaseName.equals(TDengineDatabaseParamEnums.MONTH_THREE.getDatabaseName())) {
                continue;
            }
            //原始数据源
            List<String> aggregateTimeList = StringUtil.getAggregateTimeByDatabaseName(databaseName);
            aggregateTimeList.forEach(aggregateTime -> {
                String streamName = TDengineConstants.STREAM_NAME_PREFIX + aggregateTime;
                String stbName = TDengineConstants.STREAM_TABLE_PREFIX + aggregateTime;
                //查询内容
                String subquery = StrUtil.format(TDengineSqlConstants.STREAM_SUBQUERY, originSource, aggregateTime);
                createStream(streamName, null, stbName, subquery);
            });
        }
    }

具体实现详见上篇文章Tdneing整合MybatisPlus

创建完成后结构如下在这里插入图片描述

获取聚合数据

1.创建聚合结构实体

@EqualsAndHashCode(callSuper = true)
@Data
@TableName("table_numerical_6h.table_numerical_6h;")
public class TableNumerical extends BaseTaosModel<TableNumerical> {

    @ApiModelProperty("最大值")
    private Float maxValue;

    @ApiModelProperty("最小值")
    private Float minValue;

    @ApiModelProperty("平均值")
    private Double avgValue;

    @ApiModelProperty("开始值")
    private Float firstValue;

    @ApiModelProperty("结束值")
    private Float lastValue;

    @ApiModelProperty("中位数")
    private Double apercentileValue;

    @ApiModelProperty("总数")
    private Long countValue;

    @ApiModelProperty("groupId")
    private Long groupId;
}

其余文件省略,查询时根据条件查询即可,示例如下

    public void test(){
        Timestamp startTime = Timestamp.valueOf(LocalDateTime.now());
        Timestamp endTime = Timestamp.valueOf(LocalDateTime.now().plusDays(1));
        // 查询子表为4617573834247140801的今天的数据,聚合6小时
        List<TableNumerical> list = tableNumericalService.lambdaQuery()
                .eq(TableNumerical::getGroupId, "4617573834247140801")
                .le(TableNumerical::getTs, endTime)
                .ge(TableNumerical::getTs, startTime)
                .list();
    }

总结

到此,聚合查询实现完毕,最好结合上一篇MybatisPlus整合观看,其中stream_options参数最好根据实际结构决定,本结构用于处理历史数据,所以使用了FILL_HISTORY参数,但是流式计算占用硬盘和内存非常高,暂未测试此参数和taos版本与服务器硬件关联

  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: TDengine是一个高性能的开源时序数据库,专门用于存储和查询大规模时序数据。TDengine支持流式计算,能够对实时数据进行实时分析和处理。 TDengine流式计算基于SQL语言和UDF(User-Defined Function)扩展函数,支持对数据进行多维度聚合、过滤、排序等操作。用户可以通过UDF扩展函数来自定义自己的数据处理逻辑,以实现更加复杂的计算需求。 TDengine还支持多种流式数据输入方式,包括Kafka、MQTT、HTTP、本地Socket等。用户可以根据自己的实际需求选择合适的输入方式,并使用TDengine提供的API来实现数据的实时处理和存储。 总的来说,TDengine流式计算能力非常强大,可以帮助用户轻松实现对实时数据的实时处理和分析,是一款非常实用的时序数据处理工具。 ### 回答2: TDengine流式计算是一种高效、实时的数据处理方式。它是由TDengine数据库提供的一项功能,用于处理实时数据流,并进行实时计算分析。 首先,TDengine流式计算具有高效处理的能力。它采用了分布式架构和多线程处理技术,使得可以同时处理多个数据流,并且能够将计算结果实时返回。这使得TDengine可以在毫秒级别对大规模数据进行处理,大大提高了数据分析的效率。 其次,TDengine流式计算具备灵活和强大的计算能力。它支持多种计算操作,如聚合、过滤、投影等,可以根据实际需求提取、转换和过滤出所需数据。此外,TDengine还支持自定义函数和表达式,可以根据不同的场景进行灵活的计算操作。 另外,TDengine流式计算还支持事件触发和实时报警功能。它可以根据实时数据的变化情况,通过设定规则和条件来触发相应的事件和报警。这样可以及时发现和处理异常情况,提高数据监控和处理的效率。 总体而言,TDengine流式计算是一种能够实现高效、实时的数据处理和分析的技术。它帮助用户快速提取和分析大规模数据,对实时业务进行监控和预警,并为用户提供灵活的计算操作。这使得TDengine在物联网、金融、电力等领域得到广泛应用,为用户提供了高效、可靠的数据处理解决方案。 ### 回答3: TDengine流式计算是一种高性能的实时数据处理技术,可用于处理海量的流式数据。它结合了高速存储和强大的查询分析能力,能够迅速地处理连续产生的数据流。 TDengine流式计算的核心是其高速的数据存储引擎。它采用了时序数据库的架构,能够快速地存储和检索时序数据。与传统的关系型数据库不同,TDengine使用了列存储的方式,大大提高了数据的读写速度和压缩率。同时,它还支持数据分区和数据压缩等技术,使得在处理大规模数据时更加高效。 TDengine流式计算还提供了强大的查询和分析能力。它支持SQL查询语言,可以通过简单的SQL语句进行复杂的数据分析。此外,它还提供了灵活的数据过滤和聚合功能,可以根据具体需求对数据进行筛选和汇总。这些查询和分析功能都是实时的,可以在数据流进入系统时实时进行处理,不需要等待离线批处理。 TDengine流式计算具有广泛的应用场景。例如,在物联网领域,传感器设备产生的数据量很大,需要实时地进行处理和分析,以及进行预测和决策;在金融领域,股票交易、支付等数据也需要实时地进行处理和分析,提供实时的决策支持。 总而言之,TDengine流式计算是一种高性能、高效率的实时数据处理技术。它通过高速存储引擎和强大的查询分析功能,可以实现实时处理和分析海量的流式数据,为各行各业提供了实时决策的支持。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值