无码人妻精品一区二区三18禁,影音先锋男人AV橹橹色,污污污污污污www网站免费,日韩成人av无码一区二区三区,欧美性受xxxx狂喷水

TDengine 在住建行業工地管理系統落地的“操作手冊”

必和必拓 研發部

2021-11-18 / ,

作者:必和必拓研發部

小 T 導讀:湖南必和必拓科技發展有限公司定位于智慧城市建設與行業信息化,當前聚焦智慧住建、智慧環保、智慧司法以及智能制造四大領域,既包含各類電子產品安裝施工及維保,也包括自有軟件研發及部署。

智慧工地云平臺
TDengine Database

隨著業務規模的逐漸擴大,傳統數據庫越來越難以滿足某些業務場景對查詢、分析、統計的進一步需求。為了打破當下困局,湖南必和必拓想到了三種解決方案,在進行了嚴謹的分析后,我們決定采用物聯網數據庫,經過選型對比,時序數據庫 TDengine 成為其首選方案。

如何在 TDengine 上進行數據建模、集群搭建、告警模塊搭建?如何將數據更平滑地遷移到 TDengine?在這些操作中,可能會遇到什么問題?又該如何解決?從湖南必和必拓的實踐經驗出發,本文將從代碼層面一一解答。

業務場景及痛點

在一些業務場景中,我們需要將長沙市在建工地的揚塵數據(溫度、濕度、pm2.5、pm10、pm100、噪聲、風向、風速)存儲在數據庫中,以便為業務提供查詢、分析和統計的操作。

但近來出現了一個難題,我們共有監測點 107 個,每分鐘上送 1 條數據,每年就預計有“107*60*24*365 = 56,239,200”條數據,也就是 5600 多萬條。目前已存儲兩年的數據,數據量總計約 1 億多條。這些數據一直都被存儲在 MySQL 數據庫中,龐大的數據量使得查詢速度越發緩慢,甚至部分頁面出現超時問題。

解決方案 1:MySQL 數據庫分庫分表

如果我們將數據庫分散到不同的表上,單表的索引大小就得到了控制,對索引以及表結構的變更會變得更加方便和高效。當數據庫實例的吞吐量達到性能的瓶頸時,我們需要擴展數據庫實例,讓每個數據庫實例承擔其中一部分數據庫的請求,分解總體的大請求量的壓力。

弊端:

  • 分庫分表需要提前對數據做好規劃。如果按照時間對表進行水平劃分,隨著監控點增加,后面的表數據量可能越來越大,容易出現數據熱點問題;如果按照監測點 hash 取模對表進行水平劃分,當監測點增加,進行擴展就會比較困難。例如:之前是 mod4,后面是 mod6,則需要對之前的歷史數據重新進行處理。
  • 在對數據進行統計分析時,可能需要進行多表的聚合查詢,查詢速度會受到影響。

解決方案 2:使用華為云物聯網平臺

華為云物聯網基于物聯網資產模型,整合物聯網數據集成、清洗、存儲、分析、可視化,為物聯網數據開發者提供一站式服務,能夠有效降低開發門檻,縮短開發周期,快速實現物聯網數據價值變現。

弊端:前期需設備廠商針對平臺接口進行適配,接入以后零代碼的方式確實在配置上會比較方便,但是平臺的費用以及實時流式計算按次收費的方式,整體費用過高。

解決方案 3:使用物聯網數據庫

  • InfluxDB:高性能的時序數據庫,可以高效的存儲和查詢時序數據。可惜的是,目前社區版集群功能不開源。
  • TDengine:TDengine 是一個簡單快捷、高性能的時序數據庫,提供高性能的同時也極大降低了安裝、部署和維護的成本。

應用之后,TDengine 能解決之前令我們較為頭疼的一些問題,包括前文中描述的問題,它有以下 5 點主要優勢:

  1. 安裝簡單。下載 rpm 包,一個命令安裝完畢即可運行。
  2. 數據庫開源,支持集群。
  3. 充分考慮時序數據的特點,以超級表為模型,將每個監測點的數據單獨存儲在一張表中,提高了插入和查詢速度。
  4. 有豐富的函數,支持窗口查詢和連續查詢。
  5. 自帶 TDengineAlert 模塊,和 AlertManager 聯合使用,可以推送告警信息

綜合考慮以上解決方法,我們發現,使用 TDengine 后,硬件成本和開發維護成本大大降低,寫入和查詢速度比 OpenTSDB 等還要高出一個級別。于是,TDengine 成為了我們的首選解決方案。

接下來,我將把我們在探索 TDengine 時的一些重要操作、問題點以及解決辦法等經驗傳遞給大家。

關于 TDengine 安裝

官網下載安裝包,文中使用的是 2.0.20.12,即:TDengine-server-2.0.20.12-Linux-x64.tar.gz。安裝包中包含安裝命令, 解壓后直接使用即可。

[root@hnbhbt ~]# tar -zxvf TDengine-server-2.0.20.12-Linux-x64.tar.gz
[root@hnbhbt ~]# cd TDengine-server-2.0.20.12
[root@hnbhbt ~]# ./install.sh
1. 啟動TDengine
[root@hnbhbt ~]# systemctl start taosd
2. 檢查TDengine狀態
[root@hnbhbt ~]# systemctl status taosd
3. 輸入以下命令進入TDengine命令行
taos
出現如下顯示后表示進入成功
Welcome to the TDengine shell from Linux, Client Version:2.0.20.12
Copyright (c) 2020 by TAOS Data, Inc. All rights reserved.
taos>
卸載: 需要手動刪除配置文件以及日志
[root@hnbhbt ~]# sudo rm -rf /var/log/taos/
[root@hnbhbt ~]# sudo rm -rf /var/lib/taos/
[root@hnbhbt ~]# sudo rm -rf /etc/taos/taos.cfg

注: 安裝過程中需要配置 TDengine 的 FQDN 為 hostname,通過 Linux 命令可以查看當前機器的 hostname,配置相應內容即可,官方建議盡量不要使用 localhost, 文中配置的是 hnbhbt.com

數據建模

表設計

-- 創建數據庫
create database db_transfer_platform keep 730 replica 3;
-- 使用數據庫
use db_transfer_platform;
-- 創建超表
create stable if not exists s_dust_history_data(ts timestamp,measured_value double,id int)tags(device_code nchar(30),channel_number nchar(30),signal_code nchar(30),status bool);
-- 刪除超表
drop stable if exists s_dust_history_data;
-- ts 時間戳;measured_value 測量值;id 平臺主鍵;device_code 設備編號;channel_number 通道序號;signal_code 信號編號;status 在線狀態

注:ts 默認為主鍵,不能為空;列名避免取關鍵值,否則無法插入

數據插入

-- example:創建子表,插入數據,查詢數據 
-- 子表名稱[監測信號_設備編號] eg pm_25_1003055表示設備編號為1003055的pm2.5的監測表
create table if not exists eg_pm_25_1003055 using s_dust_history_data tags('1003055','1','18113001',true);
create table if not exists eg_pm_10_1003055 using s_dust_history_data tags('1003055','2','18114001',false);
insert into eg_pm_25_1003055 (ts,measured_value,id) values("2021-07-29 21:43:22",7.0,123);
insert into eg_pm_10_1003055 (ts,measured_value,id) values("2021-07-29 21:43:22",6.0,124);
insert into eg_pm_25_1003055 (ts,measured_value,id) values("2021-07-29 21:43:22",9.0,123);

注:

  1. 全列模式寫入速度會遠快于制定列,建議盡可能采用全列寫入方式
  2. 批量插入數據,寫入速度更快(最多支持同時插入32000條左右,和SQL長度相關)
  3. 對于重復的數據,忽略后面插入的數據

數據查詢

select * from s_dust_history_data where ts > '2021-07-29 00:00:00' and ts < '2021-07-30 00:00:00' and signal_code = '18113001';
TDengine Database

Spring Boot 整合 TDengine

當用戶需要查詢工地設備揚塵數據時,揚塵數據將通過定時任務從第三方接口中定時拉取保存至我們系統的數據庫。由于揚塵數據的量較大,為千萬甚至上億級別,而系統配置相關數據的數據量較小,因此我們選擇將揚塵數據和系統配置數據分離——揚塵數據使用 TDengine 進行存儲,系統配置數據采用 MySQL 進行存儲。

本文使用 MybatisPlus 作為持久層框架,同時接入 TDengine 和 MySQL,做雙數據源配置。下文中將重點講述 TDengine,MySQL 相關內容將省略。

1. taos-jdbcdriver 的選擇

根據官網找到 taos-jdbcdriver 的對應版本,本文使用的 taos-jdbcdriver 版本是 2.0.22。

TDengine Database
<dependency>
    <groupId>com.taosdata.jdbc</groupId>
    <artifactId>taos-jdbcdriver</artifactId>
    <version>2.0.22</version>
    <scope>runtime</scope>
</dependency>

【問題】最開始使用的是較高的版本,結果出現無法正常訪問的情況,最終降低 taos-jdbcdriver 版本后得以解決。

2. 雙數據源配置

在 Spring Boot yml 中配置雙數據源,使用 druid 連接池,將 TDengine 設置為主數據庫,MySQL 設置為副數據庫。

spring:
  datasource:
    dynamic:
      druid:
        initial-size: 10
        min-idle: 10
        max-active: 100
        max-wait: 60000
        test-while-idle: false
      primary: td-engine
      strict: false
      datasource:
        td-engine:
          driver-class-name: com.taosdata.jdbc.TSDBDriver
          url: jdbc:TAOS://address:port/dbname
          username: dbusername
          password: dbpassword
        mysql:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: ...
          username: ...
          password: ...

3. 代碼編寫

核心邏輯是第三方數據的定時拉取以及在本系統進行的查詢,此處主要介紹 TDengine 的 mapper 寫法。

官方提到 TDengine 全列模式寫入速度會遠快于指定列,建議盡可能采用全列寫入方式;而揚塵數據的種類多樣,因此我們采用動態表名 + 批量插入的方式。每次拉取數據時,以設備和揚塵數據種類為維度創建 tags,同時對該維度的數據進行數據插入。

Mapper
a. 創建Tags
<insert id="createTags" parameterType="TagsEntity">
    create table if not exists #{tags名稱}
        using 超級表名稱 tags
    (#{tagsColumn1Value},
    ...
    #{tagsColumnNValue})
</insert>
b. Tags插入單條數據
<insert id="insert" parameterType="TagsEntity">
    insert into #{tags名稱}
        (#{tagsColumn1},
        ...
        #{tagsColumnN})
        values
        (#{tagsColumn1Value},
        ...
        #{tagsColumnNValue})
</insert>

需要注意的是,TDengine 在進行全列寫入時,必須為數據表的每個列都顯式地提供數據,并且一次插入的數據是有上限的,否則會報錯,建議在正式插入之前測試一下全列寫入的上限。

<insert id="batchInsert" parameterType="TagsEntity">
    insert into #{tags名稱}
    values
    <foreach collection="list" item="data">
        (#{data.tagsColumn1Value},
        ...
        #{data.tagsColumnNValue})
    </foreach>
</insert>
JavaBean

如需查詢揚塵數據,創建一個和超級表綁定的實體類即可,里面應該包含超級表本身的屬性以及 tags 的屬性,可以直接使用 MyBatisPlus 的持久層方法進行查詢。

@Data
@TableName(tbname)
public class SuperTableEntity {
    private String colunm1;
    ...
}

【問題一】在編寫完代碼后盡管查詢不會出錯,但插入和創建 tags 會發生錯誤,后來發現此處是 DNS 解析異常,由于 TDengine 配置了 FQDN,因此應該在 hosts 中配置映射關系,之后才能進行正常的插入和創建操作。

【問題二】在進行第三方數據同步時,由于第一次是同步歷史數據,因此插入 TDengine 的數據量較大。盡管 TDengine 本身支持的全列模式寫入已經提升了不少效率,但如果代碼中的批量插入繼續使用普通 for 循環,插入效率仍然較低,這里可以通過切割數據和多線程的方式進行實現。

private void runner(List<Entity> list, int dealSize) throws Exception {
    if (!CollectionUtils.isEmpty(list)) {
        //數據總的大小
        int count = list.size();
        //每個線程數據集
        List<Entity> threadList = null;
        //線程池
        int runSize = (count / dealSize) + 1;
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                runSize,
                350,
                30L, TimeUnit.SECONDS,
                new SynchronousQueue<>());
        
        CountDownLatch countDownLatch = new CountDownLatch(runSize);

        for (int i = 0; i < runSize; i++) {
            //計算每個線程執行的數據
            int startIndex = (i * dealSize);
            if ((i + 1) == runSize) {
                threadList = list.subList(startIndex, count);
            } else {
                int endIndex = (i + 1) * dealSize;
                threadList = list.subList(startIndex, endIndex);
            }
            //TODO 這里寫自己的線程任務
            executor.execute(myThread);
        }
        //計數
        countDownLatch.await();
        //關閉線程池
        executor.shutdown();
    }
}

在使用雙數據源時,Controller 和 Dao 與一般的 Spring Boot + MyBatis 無異,主要在于 Service,由于設置的 primary 數據庫是 TDengine,所以持久層默認會訪問 TDengine 數據庫,如果要切換,需要在 service 的 class 或方法上添加注解 @DS(databaseAlias),括號中填寫 yml 中配置的數據庫別名,如 td-engine、mysql 等,通過這種方式來選擇需要訪問的數據庫。primary 數據庫可以省略 @DS。

@DS("td-engine")
public TestEntity get() {
    return testDao.get();
}

TDengine 數據遷移

當我們需要將揚塵數據從公司本地服務器遷移數據至華為云服務器,文中使用 TDengine 自帶的 dump 工具進行數據遷移。

參考文檔: 

DUMP命令幫助信息
[root@hnbhbt ~]# taosdump --help
關鍵參數:
-h: 主機名稱
-o: 導出文件路徑
-i: 導入文件路徑
-u: TDengine用戶名
-p: TDengine密碼
-A: 導出所有數據庫的數據
-B: 導出指定數據庫(可選多個數據庫)
-S: 開始時間時間戳
-E: 結束時間時間戳
-T: 指定導出數據時,啟動的線程數。建議設置成機器上core的2倍
1. 數據導出
[root@hnbhbt ~]# taosdump -h hostname -o /dump/data-210824 -u username -p password -A -S 1598889600000 -E 1628956800000 -T 500 -N 100
2. 數據導入
[root@hnbhbt ~]# taosdump -u username -p password -i ~/data-210824 -T 4

【問題】此處在配置 hostname 時應該填寫 FQDN,如果不填寫或者填寫服務器 IP,將會產生錯誤。

集群搭建

參考網址:

TDengine 集群安裝、管理

使用 TDengine 進行報警監測 
常見問題
一篇文章說清楚 TDengine 的 FQDN 
Linux 配置 ntp 時間服務器(全)

TDengine Database
可掃描二維碼下載相關附件

告警模塊搭建

參考網址:

Alertmanager 配置概述  

深入 Alertmanager 概念與配置介紹 

alertmanager 配置文件詳解(四) 

java 利用釘釘機器人向釘釘群推送消息 

Alertmanager 企業微信配置 

TDengine Database
可掃描二維碼下載相關附件

小結

應市質安站的監管要求以及藍天辦對空氣污染治理的督查要求,市內所有工地的空氣質量數據及噪音數據均需接入政府監管平臺、納入管理中。監控數據的特點就是時序、結構化、簡單但量大,在處理這類數據上,TDengine 可以說是量身定做。搭載 TDengine 后,監控數據上報后的實時展示、歷史回溯都非常快,加上其本身輕量的特點,對于縮減項目開發運維成本也非常有幫助,完美滿足了業務的需求。