TDengine3.0全方位安装体验与数据订阅进阶功能实践

牛晓青

背景

2021年我曾写了一个专栏,介绍 TDengine2.x基础实践以及遇到的问题,2022年初又发布了基于EMQX与TDengine的前后端分离项目实践系列文章,前面这些实践中主要用到了 TDengine 作为时序数据库(Time Series Database)能够高效完成海量时序数据的存储与计算功能,关于 TDengine 的高阶功能,诸如流式计算数据订阅功能并未涉及,因此,这篇文章的内容主要是对最新发布的 TDengine3.x 安装体验以及数据订阅功能的实践。其中,数据订阅的场景为:在一系列的监测电压、电流、温度的时序数据中,一旦发现温度值超过50℃时,进行告警。(我曾使用 TDengine-alert 结合 WebHook 实现过类似需求。)

表设计

Note: 建库建表语句如下(以下是经过简化后的,仅写入两条数据,说明问题即可):

-- ts, 时间戳
-- voltage, 电压
-- currente, 电流
-- temperature, 温度
-- sn, 设备序号
-- city, 时间戳
-- groupid, 分组编号

create database if not exists iot;

-- 超级表
create stable if not exists iot.power(ts timestamp, voltage int, currente float, temperature float) tags(sn int, city nchar(64), groupid int);

-- 子表
create table if not exists iot.device0 using iot.power tags(0, "太原", 0);
create table if not exists iot.device1 using iot.power tags(1, "西安", 1);

-- 模拟数据
insert into iot.device0 values("2022-12-29 17:03:18.734", 1, 1.0, 1.0);
insert into iot.device1 values("2022-12-29 17:03:23.734", 2, 2.0, 2.0);

TDengine3.x

我下载的是2022年12月28日刚发布的 3.0.2.2 ,新鲜出炉,香喷喷~

下载安装

TDengine3.x 的下载安装与 2.x 基本一致,除了下载地址更新为 /3.0/ 。这里选用 rpm 方式进行安装。

# 下载
[root@td0 local]# wget https://www.taosdata.com/assets-download/3.0/TDengine-server-3.0.2.2-Linux-x64.rpm
--2022-12-29 03:28:08--  https://www.taosdata.com/assets-download/3.0/TDengine-server-3.0.2.2-Linux-x64.rpm
正在解析主机 www.taosdata.com (www.taosdata.com)... 101.200.125.16
正在连接 www.taosdata.com (www.taosdata.com)|101.200.125.16|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:34081820 (33M) [application/x-redhat-package-manager]
正在保存至: “TDengine-server-3.0.2.2-Linux-x64.rpm”

100%[=========================================>] 34,081,820   993KB/s 用时 25s    

2022-12-29 03:28:34 (1.28 MB/s) - 已保存 “TDengine-server-3.0.2.2-Linux-x64.rpm” [34081820/34081820])

# 安装
[root@td0 local]# rpm -ivh TDengine-server-3.0.2.2-Linux-x64.rpm 
准备中...                          ################################# [100%]
正在升级/安装...
   1:tdengine-3.0.2.2-3.el7           ################################# [100%]
Start to install TDengine...
System hostname is: td0
Enter FQDN:port (like h1.taosdata.com:6030) of an existing TDengine cluster node to join
OR leave it blank to build one:
Enter your email address for priority support or enter empty to skip: 
Created symlink from /etc/systemd/system/multi-user.target.wants/taosd.service to /etc/systemd/system/taosd.service.

To configure TDengine : edit /etc/taos/taos.cfg
To start TDengine     : sudo systemctl start taosd
To access TDengine    : taos -h td0 to login into TDengine server

TDengine is installed successfully!

# 查看状态
[root@td0 local]# systemctl status taosd
● taosd.service - TDengine server service
   Loaded: loaded (/etc/systemd/system/taosd.service; enabled; vendor preset: disabled)
   Active: inactive (dead)

# 启动服务
[root@td0 local]# systemctl start taosd
[root@td0 local]# systemctl status taosd
● taosd.service - TDengine server service
   Loaded: loaded (/etc/systemd/system/taosd.service; enabled; vendor preset: disabled)
   Active: active (running) since 四 2022-12-29 03:31:39 EST; 4s ago
  Process: 21678 ExecStartPre=/usr/local/taos/bin/startPre.sh (code=exited, status=0/SUCCESS)
 Main PID: 21684 (taosd)
   CGroup: /system.slice/taosd.service
           ├─21684 /usr/bin/taosd
           └─21694 /usr/bin/udfd -c /etc/taos/

1229 03:31:39 td0 systemd[1]: Starting TDengine server service...
1229 03:31:39 td0 systemd[1]: Started TDengine server service.

# 启动taosadapter(主要实现通过6041端口进行REST访问)
[root@td0 local]# systemctl status taosadapter
● taosadapter.service - TDengine taosAdapter service
   Loaded: loaded (/etc/systemd/system/taosadapter.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
[root@td0 local]# systemctl start taosadapter
[root@td0 local]# systemctl status taosadapter
● taosadapter.service - TDengine taosAdapter service
   Loaded: loaded (/etc/systemd/system/taosadapter.service; disabled; vendor preset: disabled)
   Active: active (running) since 四 2022-12-29 03:32:27 EST; 4s ago
 Main PID: 22455 (taosadapter)
   CGroup: /system.slice/taosadapter.service
           └─22455 /usr/bin/taosadapter

1229 03:32:27 td0 systemd[1]: Started TDengine taosAdapter service.

# 防火墙处理:我这里是虚拟机环境,直接关闭防火墙,实际生产环境只需开放对应端口即可。
[root@td0 local]# firewall-cmd --state
running
[root@td0 local]# systemctl stop firewalld
[root@td0 local]# firewall-cmd --state
not running
[root@td0 local]# systemctl disable firewalld
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.

命令行客户端

在服务器上使用 TDengine 自带的命令行客户端验证服务的安装、运行情况。

[root@td0 local]# taos
Welcome to the TDengine Command Line Interface, Client Version:3.0.2.2
Copyright (c) 2022 by TDengine, all rights reserved.

   ******************************  Tab Completion  **********************************
   *   The TDengine CLI supports tab completion for a variety of items,             *
   *   including database names, table names, function names and keywords.          *
   *   The full list of shortcut keys is as follows:                                *
   *    [ TAB ]        ......  complete the current word                            *
   *                   ......  if used on a blank line, display all valid commands  *
   *    [ Ctrl + A ]   ......  move cursor to the st[A]rt of the line               *
   *    [ Ctrl + E ]   ......  move cursor to the [E]nd of the line                 *
   *    [ Ctrl + W ]   ......  move cursor to the middle of the line                *
   *    [ Ctrl + L ]   ......  clear the entire screen                              *
   *    [ Ctrl + K ]   ......  clear the screen after the cursor                    *
   *    [ Ctrl + U ]   ......  clear the screen before the cursor                   *
   **********************************************************************************

Server is Community Edition.

taos> show databases;
              name              |
=================================
 information_schema             |
 performance_schema             |
Query OK, 2 row(s) in set (0.002114s)

远程Windows客户端

我这里远程开发用的是 Win 10 操作系统。注意需要下载与服务器端版本一致的客户端:

https://www.taosdata.com/assets-download/3.0/TDengine-client-3.0.2.2-Windows-x64.exe

WindowsClient.jpg
Note: TDengine 默认使用 6030 端口通信,所以在服务器端需要开放 6030TCP 端口。

远程REST客户端

# 测试RESTful远程连接
curl -u root:taosdata -d 'select * from iot.power' td0:6041/rest/sql

RESTClient.jpg

远程REST GUI客户端

tdenginegui Setup 1.0.0 提示:连接失败。。到官方看了一眼,发现有更新!!卸载旧版本,下载安装新版本。

GUIVersion.jpg
TDengineGUI.Setup.1.0.3.exe :连接成功。

GUIClient.jpg

数据订阅-场景

在一系列的监测电压、电流、温度的时序数据中,一旦发现温度值超过50℃时,进行告警。

根据场景需求,先通过 taos 客户端创建一个主题: alarm_temperaturecreate topic alarm_temperature as select * from iot.power where temperature >= 50; 这个主题名称在我们实现消费者端时要用到。以下列出了主题相关的管理操作:创建、查看、删除等。

-- 创建主题
taos> create topic alarm_temperature as select * from iot.power where temperature >= 50;
Create OK, 0 row(s) affected (0.009575s)

-- 查看主题
taos> show topics;
           topic_name           |
=================================
 alarm_temperature              |
Query OK, 1 row(s) in set (0.002781s)

taos> create topic alarm_voltage as select * from iot.power where voltage >= 230;
Create OK, 0 row(s) affected (0.002000s)

taos> create topic alarm_currente as select * from iot.power where currente >= 10;
Create OK, 0 row(s) affected (0.002221s)

taos> show topics;
           topic_name           |
=================================
 alarm_currente                 |
 alarm_voltage                  |
 alarm_temperature              |
Query OK, 3 row(s) in set (0.001895s)

-- 查看消费者
taos> show consumers;
Query OK, 0 row(s) in set (0.004082s)

-- 查看订阅信息
taos> show subscriptions;
           topic_name           |         consumer_group         |  vgroup_id  |      consumer_id      |
========================================================================================================
 alarm_temperature              | demo                           |           2 |                  NULL |
 alarm_temperature              | demo                           |           3 |                  NULL |
Query OK, 2 row(s) in set (0.002721s)

-- 删除主题
taos> drop topic alarm_currente;
Drop OK, 0 row(s) affected (0.001335s)

taos> show topics;
           topic_name           |
=================================
 alarm_voltage                  |
 alarm_temperature              |
Query OK, 2 row(s) in set (0.001956s)

数据订阅-消费者

为了降低使用数据订阅的上手复杂度, TDengine 时序数据库(Time Series Database)的数据订阅功能,提供了与 Kafka 一致的接口。

这里的消费者,基于5-TDengine集成SpringBoot,MyBatis,MyBatisPlusMyBatisPlus 的实例,进行了改造。除了基本的 CRUD 接口外,重点实践了 TDengine 的数据订阅消费者的实现。

SpringBootClient.jpg

pom依赖

核心依赖: SpringBootwebmybatis-plustaos-jdbcdriverspring-boot-configuration-processor 以及 lombok

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.2</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.17</version>
        </dependency>

        <dependency>
            <groupId>com.taosdata.jdbc</groupId>
            <artifactId>taos-jdbcdriver</artifactId>
            <version>3.0.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

这里一定注意 taos-jdbcdriver 的版本要与 TDengine 服务端版本一致或兼容。关于版本兼容性说明,见官方这个表(我的服务端 TDengine 版本为:3.0.2.2):

TaosJDBCDriver.jpg

配置文件

  • application.yml

主要包含数据源、 mybatis-plus 、日志以及自定义的 TDengine 时序数据库(Time Series Database)的数据订阅消费者配置。

spring:
  datasource:
    driver-class-name: com.taosdata.jdbc.TSDBDriver
    url: jdbc:TAOS://td0:6030/iot?charset=UTF-8&locale=en_US.UTF-8&timezone=UTC-8
    username: root
    password: taosdata
    druid:
      initial-size: 5
      min-idle: 5
      max-active: 5
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: false
logging:
  level:
    com:
      taosdata:
        example:
          mybatisplusdemo:
            mapper: debug
td:
  consumer:
    bootstrap-servers: td0:6030
    msg-with-table-name: true
    enable-auto-commit: true
    group-id: demo
    value-deserializer: com.taosdata.example.mybatisplusdemo.deserializer.PowerDeserializer

Note:记得在开发环境配置主机名解析,我这里是 Win10C:\Windows\System32\drivers\etc\hosts

192.168.44.158 td0

ConfigProperties.jpg

  • TdConfigProperties.java

结合 @ConfigurationProperties 注解实现自定义的 TDengine 的数据订阅消费者配置,将配置与代码解耦。

@ConfigurationProperties(prefix = "td.consumer")
@Component
@Data
public class TdConfigProperties {
    
    
    private String bootstrapServers;
    private Boolean msgWithTableName;
    private Boolean enableAutoCommit;
    private String groupId;
    private String valueDeserializer;
}

数据订阅及消费

通过 @PostConstruct 注解,在后端项目启动后自动进行订阅与消费。订阅的实现模型有两种,一种是“推”,即服务器主动将数据发到客户端;另一种是“拉”,即客户端主动向服务器请求数据。 TDengine 时序数据库(Time Series Database)使用的是“拉”模型,因此演示代码中通过一个死循环实现对主题数据的消费(实际生产可考虑其他实现方式)。

@Configuration
@Slf4j
public class SubscribeOnStartUp {
    
    
    private static final String TOPIC = "alarm_temperature";

    @Autowired
    private TdConfigProperties tdConfig;

    @Bean
    public Properties config() {
    
    
        Properties properties = new Properties();
        properties.setProperty(TMQConstants.BOOTSTRAP_SERVERS, tdConfig.getBootstrapServers());
        properties.setProperty(TMQConstants.MSG_WITH_TABLE_NAME, tdConfig.getMsgWithTableName().toString());
        properties.setProperty(TMQConstants.ENABLE_AUTO_COMMIT, tdConfig.getEnableAutoCommit().toString());
        properties.setProperty(TMQConstants.GROUP_ID, tdConfig.getGroupId());
        properties.setProperty(TMQConstants.VALUE_DESERIALIZER, tdConfig.getValueDeserializer());
        return properties;
    }

    @PostConstruct
    public void subscribe() {
    
    
        log.info("PostConstruct");
        // poll data
        TaosConsumer<Power> consumer = null;
        try {
    
    
            consumer = new TaosConsumer<>(config());
            consumer.subscribe(Collections.singletonList(TOPIC));
            while (true) {
    
    
                ConsumerRecords<Power> powerRecords = consumer.poll(Duration.ofMillis(100));
                for (Power power : powerRecords) {
    
    
                    // TODO 告警推送:短信、邮箱、钉钉、企业微信、飞书、WebHook
                    log.info("Consumed: {}", power.toString());
                }
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        } finally {
    
    
            try {
    
    
                if (null != consumer) {
    
    
                    consumer.unsubscribe();
                }
            } catch (SQLException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}

Note:在实际中,当消费了告警数据后,可以进行告警推送:短信、邮箱、钉钉、企业微信、飞书、 WebHook 等,就像下面我们项目中的这样,可选多种告警推送方式。

AlarmNotification.png

告警订阅测试

taos 客户端中模拟数据写入:近3分钟的五条数据,显然,每条数据的温度指标都高于我们设定的阈值:50℃。

taos> insert into device0 values(now - 2m, 220, 5, 50) (now - 90s, 220, 5, 60) (now - 1m, 220, 5, 70) (now - 30s, 220, 5, 80) (now, 220, 5, 90);

在消费者端可以看到,所有的告警数据被成功消费。

PubSubAndConsume.jpg

Reference

Source Code


If you have any questions or any bugs are found, please feel free to contact me.

Your comments and suggestions are welcome!

猜你喜欢

转载自blog.csdn.net/u013810234/article/details/128525908