TDengine 時序性資料庫為什麼海量資料下不卡頓呢

語言: CN / TW / HK

本文正在參加「技術專題19期 漫談資料庫技術」活動

前言

TDengine 是一款高效能、分散式、支援 SQL 的時序資料庫

  • 學習新知識,無非就是搞懂他是什麼,能解決什麼痛點,該如何快速入門

功能介紹

  • 他是一個高效能、分散式、支援SQL的時序性資料庫,這就是他的功能。
  • 除此以外他還支援快取、訂閱、流計算功能。這麼一聽是不是感覺TDengine=Mysql+Redis+MQ+Stream了

image-20220507111320561.png

image-20220507111552816.png

使用場景

  • TDengine作為時序性資料庫他的場景肯定就是針對那種時序場景。說到時序就是對應我們物聯網裝置。裝置的資料上報是即時性的,在物聯網系統中讀少寫多。其中只有讀寫,基本不存在刪除和更新這兩個操作。比如我們的電錶資料上報,只會隨著時間的遞增疊加式推送資料。不可能說前一分鐘推送的資料他需要修改一下的。作為點表裝置他也不支援這個功能。
  • 所以TDengine的使用場景就是針對物聯網,車聯網,工業互聯等場景。或者說是資料持續性輸出的場景,比如我們網際網路系統中的日誌管理。

image-20220507112302958.png

  • 目前我們公司系統是對醫院進行資料採集,從而基於採集裝置的資料進行資料彙總報告。
  • 我們有電錶測量電流,電壓,相位等資料;還有水錶測量水壓,用水量等資料;還有空調採集裝置測量空調出風情況等資料;
  • 而且每一型別的裝置中會針對不同地方設定多個裝置分別測量。在TDengine中每一種型別對應一張超級表(STable)。同一型別下的裝置,每一個裝置對應Stable下的一張單獨的表。

以下表格摘自於官網

| 裝置ID | 時間戳 | | 採集量 | | 標籤 | | | --------- | ------------- | ------- | ------- | ----- | ---------------- | ------- | | Device ID | Time Stamp | current | voltage | phase | location | groupId | | d1001 | 1538548685000 | 10.3 | 219 | 0.31 | Beijing.Chaoyang | 2 | | d1002 | 1538548684000 | 10.2 | 220 | 0.23 | Beijing.Chaoyang | 3 | | d1003 | 1538548686500 | 11.5 | 221 | 0.35 | Beijing.Haidian | 3 | | d1004 | 1538548685500 | 13.4 | 223 | 0.29 | Beijing.Haidian | 2 | | d1001 | 1538548695000 | 12.6 | 218 | 0.33 | Beijing.Chaoyang | 2 | | d1004 | 1538548696600 | 11.8 | 221 | 0.28 | Beijing.Haidian | 2 | | d1002 | 1538548696650 | 10.3 | 218 | 0.25 | Beijing.Chaoyang | 3 | | d1001 | 1538548696800 | 12.3 | 221 | 0.31 | Beijing.Chaoyang | 2 |

  • DeviceId對應的就是我們實際的一個採集點的採集裝置。Time Stamp是TDengine規定的必有欄位。
  • currentvoltagephase分別是裝置測量的資料,表示電流,電壓,相位等資料
  • locationgroupId是裝置的靜態屬性資料,location可以表示裝置出廠廠家地址,groupId可以表示分組批次。總之標籤屬性可以作為裝置的描述功能使用
  • TDengine為什麼要這麼設計呢?每一個裝置對應一張表這樣做的好處是每個裝置的資料是連貫的且不受干擾的。
  • 另外還有一點一個裝置的採集頻率是固定,或者說裝置採集頻率是個常量值,這個在儲存的一段時間就能夠預測出來的。也方便我們彙總一段時間的資料統計,TDengine也提供函式幫我們統計一段週期INTERVAL(1s, 500a),500毫秒開始統計1S間隔時間內的資料情況。

為什麼裝置對應表

  • TDengine中有幾個關鍵名詞【採集量】【標籤】【採集點】
  • 所謂的採集點就是我們的採集裝置。在一個物理裝置上可以能配備多個採集裝置。這個也很好理解比如我們的空調裝置就可能有采集電的採集裝置,也有采集出風的採集裝置。按採集的功能區分的這些採集裝置TDengine中可以理解為【採集點】
  • 上面我們已經知道了一個採集點實際上對應一張表,這樣就能保證這張表只有一個寫入口,所以TDengine就不需要考慮事物的問題了。單入口效能提升很大
  • 1個採集點不一定只採集一處資料,上面的電錶採集了電流,電壓,相位三個資料,我們稱之為【採集量】
  • 針對採集點來說,除了採集量是隨著時間的推移不斷變換的屬性外,還有一些針對裝置的描述的屬性是不會發生變化的。這些對應TDegine中的【標籤】
  • 另外因為一個裝置對應一張表,資料都是時效性的,這樣在寫資料的時候只需要追加即可,從這個角度也能說明TDengine的寫入效能會很高。
  • 和mysql按頁儲存一樣,TDengine是按照塊進行儲存讀取的。因為物聯網的特性,我們關注的也是一段時間內的資料。所以按塊讀取也能夠提升我們的命中率。比如說用電量,我們不關注某一刻用多少點。我們更加關注的是1天用了多少,1月用了多少。

分的那麼徹底,聚合怎麼辦?

  • 在大資料時代下,分庫分表是一種趨勢,目前關於分庫分表的技術也在不斷的迭代完善。TDengine的分表策略正好符合分庫分表的需求。在結合TDengine的分散式特性。這就是一種分庫分表的實踐。關於分庫分表我們這裡不做贅述
  • 既然你是一種分庫分表,那在查詢時候需要關聯時該怎麼辦?總不能讓我join下去吧。

image-20220507135801919.png

  • 針對醫院不同樓層都有單獨一套採集裝置。e代表電錶,這個時候我想看醫院一天總用電量,就需要聚合e1-e3電錶測量的所有資料。

select * from e1 union all select * from e2 ...

  • 顯然,這不是最優的方式,要知道這種程式碼寫在程式裡一旦部署了就是靜態程式碼,如果哪天醫院電錶壞了更換了那麼他的DeviceId就不一樣了。對於我們程式來說就丟失了新電錶的查詢記錄了。
  • 那麼該如何解決呢? TDengine給我引出了超級表的概念。超級表是針對同一型別的裝置而言的一種描述性表結構,我們在新添子表時也可以從模板中直接新增

image-20220507140901841.png

  • 根據模板建立表時我們只需要填寫標籤資料即可

CREATE TABLE ttt USING meters TAGS ("nanjing.liuhe", 2);

安裝

  • 好了,前面我們介紹了些TDengine理論性的東西,下面我們就來實際操作一把吧。想要能夠操作前我們還的先安裝好。官網推薦的方式時Docker 。 我這裡也推薦使用Docker方式安裝,但是Docker實在沒啥可說的,這裡我就演示安裝包方式安裝吧。
  • 點我下載

sudo dpkg -i TDengine-server-2.4.0.18-Linux-x64.deb

  • 安裝的時候注意了,如果是叢集方式安裝那麼FQDN需要填寫一致

sudo dpkg -r tdengine  # 解除安裝

image-20220507144756900.png

  • 我們關注的就是cfg目錄下是關於TDengine的配置,在安裝的時候需要我們配置FQDN,如果設定了又後悔了我們可以在cfg中找到配置。
  • 另外就是data資料夾裡儲存的是資料表的資訊與資料。
  • TDengine是通過systemed方式啟動的。關於服務的管理大致我們需要以下命令即可

| 功能 | 命令 | | -- | ------------------------- | | 啟動 | systemctl start taosd | | 關停 | systemctl stop taosd | | 重啟 | systemctl restart taosd | | 狀態 | systemctl status taosd |

  • 服務安裝好之後,我們就可以連線資料庫了。在server安裝中預設會有Client的安裝。我們只需要在安裝的伺服器上輸入taos即可。

image-20220507150956570.png

本文正在參加「技術專題19期 漫談資料庫技術」活動

「其他文章」