TDengine概述以及架構模型

TDengine

TDengine是一個高效的存儲、查詢、分析時序大數據的平台,專為物聯網、車聯網、工業互聯網、運維監測等優化而設計。

您可以像使用關係型數據庫MySQL一樣來使用它。

 

TDengine介紹
TDengine是濤思數據面對高速增長的物聯網大數據市場和技術挑戰推出的創新性的大數據處理產品,它不依賴任何第三方軟件,也不是優化或包裝了一個開源的數據庫或流式計算產品,而是在吸取眾多傳統關係型數據庫、NoSQL數據庫、流式計算引擎、消息隊列等軟件的優點之後自主開發的產品,在時序空間大數據處理上,有着自己獨到的優勢。

TDengine的模塊之一是時序數據庫。但除此之外,為減少研發的複雜度、系統維護的難度,TDengine還提供緩存、消息隊列、訂閱、流式計算等功能,為物聯網、工業互聯網大數據的處理提供全棧的技術方案,是一個高效易用的物聯網大數據平台。與Hadoop等典型的大數據平台相比,它具有如下鮮明的特點:

  • 10倍以上的性能提升:定義了創新的數據存儲結構,單核每秒能處理至少2萬次請求,插入數百萬個數據點,讀出一千萬以上數據點,比現有通用數據庫快十倍以上。
  • 硬件或雲服務成本降至1/5:由於超強性能,計算資源不到通用大數據方案的1/5;通過列式存儲和先進的壓縮算法,存儲空間不到通用數據庫的1/10。
  • 全棧時序數據處理引擎:將數據庫、消息隊列、緩存、流式計算等功能融為一體,應用無需再集成Kafka/Redis/HBase/Spark/HDFS等軟件,大幅降低應用開發和維護的複雜度成本。
  • 強大的分析功能:無論是十年前還是一秒鐘前的數據,指定時間範圍即可查詢。數據可在時間軸上或多個設備上進行聚合。即席查詢可通過Shell, Python, R, Matlab隨時進行。
  • 與第三方工具無縫連接:不用一行代碼,即可與Telegraf, Grafana, EMQ, HiveMQ, Prometheus, Matlab, R等集成。後續將支持OPC, Hadoop, Spark等, BI工具也將無縫連接。
  • 零運維成本、零學習成本:安裝集群簡單快捷,無需分庫分表,實時備份。類似標準SQL,支持RESTful, 支持Python/Java/C/C++/C#/Go/Node.js, 與MySQL相似,零學習成本。

採用TDengine,可將典型的物聯網、車聯網、工業互聯網大數據平台的總擁有成本大幅降低。但需要指出的是,因充分利用了物聯網時序數據的特點,它無法用來處理網絡爬蟲、微博、微信、電商、ERP、CRM等通用型數據。

數據模型和整體架構

數據模型

在典型的物聯網、車聯網、運維監測場景中,往往有多種不同類型的數據採集設備,採集一個到多個不同的物理量。而同一種採集設備類型,往往又有多個具體的採集設備分佈在不同的地點。大數據處理系統就是要將各種採集的數據匯總,然後進行計算和分析。對於同一類設備,其採集的數據都是很規則的。

以智能電錶為例,假設每個智能電錶採集電流、電壓、相位三個量,其採集的數據類似如下的表格:

 

 

 每一條記錄都有設備ID,時間戳,採集的物理量(如上圖中的電流、電壓、相位),還有與每個設備相關的靜態標籤(如上述表一中的位置Location和分組groupId)。每個設備是受外界的觸發,或按照設定的周期採集數據。採集的數據點是時序的,是一個數據流。

關係型數據庫模型

因為採集的數據一般是結構化數據,同時為降低學習門檻,TDengine採用傳統的關係型數據庫模型管理數據。因此用戶需要先創建庫,然後創建表,之後才能插入或查詢數據。TDengine採用的是結構化存儲,而不是NoSQL的key-value存儲。

一個數據採集點一張表

為充分利用其數據的時序性和其他數據特點,TDengine要求對每個數據採集點單獨建表(比如有一千萬個智能電錶,就需創建一千萬張表,上述表格中的d1001, d1002, d1003, d1004都需單獨建表),用來存儲這個採集點所採集的時序數據。這種設計有幾大優點:

  • 能保證一個採集點的數據在存儲介質上是以塊為單位連續存儲的。如果讀取一個時間段的數據,它能大幅減少隨機讀取操作,成數量級的提升讀取和查詢速度。
  • 由於不同採集設備產生數據的過程完全獨立,每個設備的數據源是唯一的,一張表也就只有一個寫入者,這樣就可採用無鎖方式來寫,寫入速度就能大幅提升。
  • 對於一個數據採集點而言,其產生的數據是時序的,因此寫的操作可用追加的方式實現,進一步大幅提高數據寫入速度。

如果採用傳統的方式,將多個設備的數據寫入一張表,由於網絡延時不可控,不同設備的數據到達服務器的時序是無法保證的,寫入操作是要有鎖保護的,而且一個設備的數據是難以保證連續存儲在一起的。採用一個數據採集點一張表的方式,能最大程度的保證單個數據採集點的插入和查詢的性能是最優的。

TDengine 建議用數據採集點的名字(如上表中的D1001)來做表名。每個數據採集點可能同時採集多個物理量(如上表中的curent, voltage, phase),每個物理量對應一張表中的一列,數據類型可以是整型、浮點型、字符串等。除此之外,表的第一列必須是時間戳,即數據類型為 timestamp。對採集的數據,TDengine將自動按照時間戳建立索引,但對採集的物理量不建任何索引。數據用列式存儲方式保存。

超級表:同一類型數據採集點的集合

由於一個數據採集點一張表,導致表的數量巨增,難以管理,而且應用經常需要做採集點之間的聚合操作,聚合的操作也變得複雜起來。為解決這個問題,TDengine引入超級表(Super Table,簡稱為STable)的概念。

超級表是指某一特定類型的數據採集點的集合。同一類型的數據採集點,其表的結構是完全一樣的,但每個表(數據採集點)的靜態屬性(標籤)是不一樣的。描述一個超級表(某一特定類型的數據採集點的結合),除需要定義採集量的表結構之外,還需要定義其標籤的schema,標籤的數據類型可以是整數、浮點數、字符串,標籤可以有多個,可以事後增加、刪除或修改。 如果整個系統有N個不同類型的數據採集點,就需要建立N個超級表。

在TDengine的設計里,表用來代表一個具體的數據採集點,超級表用來代表一組相同類型的數據採集點集合。當為某個具體數據採集點創建表時,用戶使用超級表的定義做模板,同時指定該具體採集點(表)的標籤值。與傳統的關係型數據庫相比,表(一個數據採集點)是帶有靜態標籤的,而且這些標籤可以事後增加、刪除、修改。一張超級表包含有多張表,這些表具有相同的時序數據schema,但帶有不同的標籤值。

當對多個具有相同數據類型的數據採集點進行聚合操作時,TDengine會先把滿足標籤過濾條件的表從超級表中找出來,然後再掃描這些表的時序數據,進行聚合操作,這樣需要掃描的數據集會大幅減少,從而顯著提高聚合計算的性能。

集群與基本邏輯單元

TDengine 的設計是基於單個硬件、軟件系統不可靠,基於任何單台計算機都無法提供足夠計算能力和存儲能力處理海量數據的假設進行設計的。因此 TDengine 從研發的第一天起,就按照分佈式高可靠架構進行設計,是支持水平擴展的,這樣任何單台或多台服務器發生硬件故障或軟件錯誤都不影響系統的可用性和可靠性。同時,通過節點虛擬化並輔以自動化負載均衡技術,TDengine 能最高效率地利用異構集群中的計算和存儲資源降低硬件投資。

主要邏輯單元

TDengine 分佈式架構的邏輯結構圖如下:

一個完整的 TDengine 系統是運行在一到多個物理節點上的,邏輯上,它包含數據節點(dnode)、TDengine應用驅動(taosc)以及應用(app)。系統中存在一到多個數據節點,這些數據節點組成一個集群(cluster)。應用通過taosc的API與TDengine集群進行互動。下面對每個邏輯單元進行簡要介紹。
物理節點(pnode): pnode是一獨立運行、擁有自己的計算、存儲和網絡能力的計算機,可以是安裝有OS的物理機、虛擬機或Docker容器。物理節點由其配置的 FQDN(Fully Qualified Domain Name)來標識。

數據節點(dnode): dnode 是 TDengine 服務器側執行代碼 taosd 在物理節點上的一個運行實例,一個工作的系統必須有至少一個數據節點。dnode包含零到多個邏輯的虛擬節點(VNODE),零或者至多一個邏輯的管理節點(mnode)。dnode在系統中的唯一標識由實例的End Point (EP )決定。EP是dnode所在物理節點的FQDN (Fully Qualified Domain Name)和系統所配置的網絡端口號(Port)的組合。通過配置不同的端口,一個物理節點(一台物理機、虛擬機或容器)可以運行多個實例,或有多個數據節點。

虛擬節點(vnode): 為更好的支持數據分片、負載均衡,防止數據過熱或傾斜,數據節點被虛擬化成多個虛擬節點(vnode,圖中V2, V3, V4等)。每個 vnode 都是一個相對獨立的工作單元,是時序數據存儲的基本單元,具有獨立的運行線程、內存空間與持久化存儲的路徑。一個 vnode 包含一定數量的表(數據採集點)。當創建一張新表時,系統會檢查是否需要創建新的 vnode。一個數據節點上能創建的 vnode 的數量取決於該數據節點所在物理節點的硬件資源。一個 vnode 只屬於一個DB,但一個DB可以有多個 vnode。一個 vnode 除存儲的時序數據外,也保存有所包含的表的schema、標籤值等。一個虛擬節點由所屬的數據節點的EP,以及所屬的VGroup ID在系統內唯一標識,由管理節點創建並管理。

管理節點(mnode): 一個虛擬的邏輯單元,負責所有數據節點運行狀態的監控和維護,以及節點之間的負載均衡(圖中M)。同時,管理節點也負責元數據(包括用戶、數據庫、表、靜態標籤等)的存儲和管理,因此也稱為 Meta Node。TDengine 集群中可配置多個(開源版最多不超過3個) mnode,它們自動構建成為一個虛擬管理節點組(圖中M0, M1, M2)。mnode 間採用 master/slave 的機制進行管理,而且採取強一致方式進行數據同步, 任何數據更新操作只能在 Master 上進行。mnode 集群的創建由系統自動完成,無需人工干預。每個dnode上至多有一個mnode,由所屬的數據節點的EP來唯一標識。每個dnode通過內部消息交互自動獲取整個集群中所有 mnode 所在的 dnode 的EP。

虛擬節點組(VGroup): 不同數據節點上的 vnode 可以組成一個虛擬節點組(vnode group)來保證系統的高可靠。虛擬節點組內採取master/slave的方式進行管理。寫操作只能在 master vnode 上進行,系統採用異步複製的方式將數據同步到 slave vnode,這樣確保了一份數據在多個物理節點上有拷貝。一個 vgroup 里虛擬節點個數就是數據的副本數。如果一個DB的副本數為N,系統必須有至少N個數據節點。副本數在創建DB時通過參數 replica 可以指定,缺省為1。使用 TDengine 的多副本特性,可以不再需要昂貴的磁盤陣列等存儲設備,就可以獲得同樣的數據高可靠性。虛擬節點組由管理節點創建、管理,並且由管理節點分配一個系統唯一的ID,VGroup ID。如果兩個虛擬節點的vnode group ID相同,說明他們屬於同一個組,數據互為備份。虛擬節點組裡虛擬節點的個數是可以動態改變的,容許只有一個,也就是沒有數據複製。VGroup ID是永遠不變的,即使一個虛擬節點組被刪除,它的ID也不會被收回重複利用。

TAOSC: taosc是TDengine給應用提供的驅動程序(driver),負責處理應用與集群的接口交互,提供C/C++語言原生接口,內嵌於JDBC、C#、Python、Go、Node.js語言連接庫里。應用都是通過taosc而不是直接連接集群中的數據節點與整個集群進行交互的。這個模塊負責獲取並緩存元數據;將插入、查詢等請求轉發到正確的數據節點;在把結果返回給應用時,還需要負責最後一級的聚合、排序、過濾等操作。對於JDBC, C/C++/C#/Python/Go/Node.js接口而言,這個模塊是在應用所處的物理節點上運行。同時,為支持全分佈式的RESTful接口,taosc在TDengine集群的每個dnode上都有一運行實例。

典型的消息流程

為解釋vnode, mnode, taosc和應用之間的關係以及各自扮演的角色,下面對寫入數據這個典型操作的流程進行剖析。

  1. 應用通過JDBC、ODBC或其他API接口發起插入數據的請求。
  2. taosc會檢查緩存,看是否保存有該表的meta data。如果有,直接到第4步。如果沒有,taosc將向mnode發出get meta-data請求。
  3. mnode將該表的meta-data返回給taosc。Meta-data包含有該表的schema, 而且還有該表所屬的vgroup信息(vnode ID以及所在的dnode的End Point,如果副本數為N,就有N組End Point)。如果taosc遲遲得不到mnode回應,而且存在多個mnode, taosc將向下一個mnode發出請求。
  4. taosc向master vnode發起插入請求。
  5. vnode插入數據後,給taosc一個應答,表示插入成功。如果taosc遲遲得不到vnode的回應,taosc會認為該節點已經離線。這種情況下,如果被插入的數據庫有多個副本,taosc將向vgroup里下一個vnode發出插入請求。
  6. taosc通知APP,寫入成功

對於第二和第三步,taosc啟動時,並不知道mnode的End Point,因此會直接向配置的集群對外服務的End Point發起請求。如果接收到該請求的dnode並沒有配置mnode,該dnode會在回復的消息中告知mnode EP列表,這樣taosc會重新向新的mnode的EP發出獲取meta-data的請求。

對於第四和第五步,沒有緩存的情況下,taosc無法知道虛擬節點組裡誰是master,就假設第一個vnodeID就是master,向它發出請求。如果接收到請求的vnode並不是master,它會在回復中告知誰是master,這樣taosc就向建議的master vnode發出請求。一旦得到插入成功的回復,taosc會緩存master節點的信息。

上述是插入數據的流程,查詢、計算的流程也完全一致。taosc把這些複雜的流程全部封裝屏蔽了,對於應用來說無感知也無需任何特別處理。

通過taosc緩存機制,只有在第一次對一張表操作時,才需要訪問mnode,因此mnode不會成為系統瓶頸。但因為schema有可能變化,而且vgroup有可能發生改變(比如負載均衡發生),因此taosc會定時和mnode交互,自動更新緩存。

存儲模型與數據分區、分片

存儲模型

TDengine存儲的數據包括採集的時序數據以及庫、表相關的元數據、標籤數據等,這些數據具體分為三部分:

  • 時序數據:存放於vnode里,由data、head和last三個文件組成,數據量大,查詢量取決於應用場景。容許亂序寫入,但暫時不支持刪除操作,並且僅在update參數設置為1時允許更新操作。通過採用一個採集點一張表的模型,一個時間段的數據是連續存儲,對單張表的寫入是簡單的追加操作,一次讀,可以讀到多條記錄,這樣保證對單個採集點的插入和查詢操作,性能達到最優。
  • 標籤數據:存放於vnode里的meta文件,支持增刪改查四個標準操作。數據量不大,有N張表,就有N條記錄,因此可以全內存存儲。如果標籤過濾操作很多,查詢將十分頻繁,因此TDengine支持多核多線程並發查詢。只要計算資源足夠,即使有數千萬張表,過濾結果能毫秒級返回。
  • 元數據:存放於mnode里,包含系統節點、用戶、DB、Table Schema等信息,支持增刪改查四個標準操作。這部分數據的量不大,可以全內存保存,而且由於客戶端有緩存,查詢量也不大。因此目前的設計雖是集中式存儲管理,但不會構成性能瓶頸。

與典型的NoSQL存儲模型相比,TDengine將標籤數據與時序數據完全分離存儲,它具有兩大優勢:

  • 能夠極大地降低標籤數據存儲的冗餘度:一般的NoSQL數據庫或時序數據庫,採用的K-V存儲,其中的Key包含時間戳、設備ID、各種標籤。每條記錄都帶有這些重複的內容,浪費存儲空間。而且如果應用要在歷史數據上增加、修改或刪除標籤,需要遍曆數據,重寫一遍,操作成本極其昂貴。
  • 能夠實現極為高效的多表之間的聚合查詢:做多表之間聚合查詢時,先把符合標籤過濾條件的表查找出來,然後再查找這些表相應的數據塊,這樣大幅減少要掃描的數據集,從而大幅提高查詢效率。而且標籤數據採用全內存的結構進行管理和維護,千萬級別規模的標籤數據查詢可以在毫秒級別返回。

數據分片

對於海量的數據管理,為實現水平擴展,一般都需要採取分片(Sharding)分區(Partitioning)策略。TDengine是通過vnode來實現數據分片的,通過一個時間段一個數據文件來實現時序數據分區的。

vnode(虛擬數據節點)負責為採集的時序數據提供寫入、查詢和計算功能。為便於負載均衡、數據恢復、支持異構環境,TDengine將一個數據節點根據其計算和存儲資源切分為多個vnode。這些vnode的管理是TDengine自動完成的,對應用完全透明。

對於單獨一個數據採集點,無論其數據量多大,一個vnode(或vnode group, 如果副本數大於1)有足夠的計算資源和存儲資源來處理(如果每秒生成一條16位元組的記錄,一年產生的原始數據不到0.5G),因此TDengine將一張表(一個數據採集點)的所有數據都存放在一個vnode里,而不會讓同一個採集點的數據分佈到兩個或多個dnode上。而且一個vnode可存儲多個數據採集點(表)的數據,一個vnode可容納的表的數目的上限為一百萬。設計上,一個vnode里所有的表都屬於同一個DB。一個數據節點上,除非特殊配置,一個DB擁有的vnode數目不會超過系統核的數目。

創建DB時,系統並不會馬上分配資源。但當創建一張表時,系統將看是否有已經分配的vnode, 且該vnode是否有空餘的表空間,如果有,立即在該有空位的vnode創建表。如果沒有,系統將從集群中,根據當前的負載情況,在一個dnode上創建一新的vnode, 然後創建表。如果DB有多個副本,系統不是只創建一個vnode,而是一個vgroup(虛擬數據節點組)。系統對vnode的數目沒有任何限制,僅僅受限於物理節點本身的計算和存儲資源。

每張表的meda data(包含schema, 標籤等)也存放於vnode里,而不是集中存放於mnode,實際上這是對Meta數據的分片,這樣便於高效並行的進行標籤過濾操作。

數據分區

TDengine除vnode分片之外,還對時序數據按照時間段進行分區。每個數據文件只包含一個時間段的時序數據,時間段的長度由DB的配置參數days決定。這種按時間段分區的方法還便於高效實現數據的保留策略,只要數據文件超過規定的天數(系統配置參數keep),將被自動刪除。而且不同的時間段可以存放於不同的路徑和存儲介質,以便於大數據的冷熱管理,實現多級存儲。

總的來說,TDengine是通過vnode以及時間兩個維度,對大數據進行切分,便於並行高效的管理,實現水平擴展。

Tags: