小?T?導讀:今天我們來探討一下——TDengine中的時序數據到底是如何存儲的?
在上一期的文章《五分鐘掌握 TDengine 時序數據的保留策略》中,我們知道了TDengine是如何按照時間段對數據進行分區來管理數據的。
接下來,我們和大家一起從產品使用者的視角繼續向前探索——TDengine中的時序數據到底是如何存儲的?
在那篇文章里,在我們第一次寫入數據并重啟數據庫服務后,在vnode xx路徑下看到了這三個文件。
這哥仨,其實就是TDengine中廣義上的數據文件,也可以說它們是一個數據文件組。
從后綴上看,仿佛.data這個文件就是數據文件組中的數據文件。而其他二位都是為它保駕護航的“輔助”。但是這個感覺是不夠準確的,因為.last文件同樣也會存儲數據。而.head文件則是存儲數據塊的索引的文件。
在了解它們之前,首先我們要知道兩個參數:
1.minRows:數據塊中記錄的最小條數,單位為條,默認值為100。
2.maxRows:數據塊中記錄的最大條數,單位為條,默認值為4096。
數據塊,是每個.data數據文件里存儲數據的單位,每一個數據塊都只能存儲一個表的數據。所以上面的參數描述的意思就是——形成一個數據塊默認的最小行數是100行,最多就是4096行。
那么,對于一張表來說,小于100行的話數據會去哪兒呢?大于4096行的話數據又去哪兒了呢?
答案是,.last文件正是表行數不足100時數據存放的位置;而大于4096行的表會生成一個新的數據塊。最終在.data文件中,數據塊的分布方式如下:
當然,這樣講會比較抽象,我們繼續用實例說明:
我們假設創建庫時使用的參數為 maxrows=1000,minrows=100。某庫中有兩張表A和B,我們向其中分別插入1000行和99行數據。然后,我們重啟taosd服務,以上數據就會從內存中落盤到存儲上。這個時候.data文件中會生成1個數據塊,它就是表A的數據塊1,里面擁有1000條數據。而表B的99條數據因為不足minrows所以就進入了.last文件。
接下來,繼續向它們分別插入1000行和99行,然后重啟taosd服務落盤。這個時候表A總共擁有2000條數據,新寫入的1000行數據會被寫入進表A的數據塊2。而表B的數據量現在已經有了198行,大于了100行。于是它們也會被寫入.data文件里面,成為表B的數據塊1。
值得注意的是,當.last文件小于32k的時候,所有數據都只會追加進來。但是當.last文件大于32k的時候,每次落盤.last文件都是重寫生成的了——這個的32k限制是為了防止數據的移動過于頻繁。
所以,我們在做測試的時候會發現:為什么當該表行數從99到100行以上時,.data文件的大小已經增加可.last文件卻沒有變小。只有當.last文件大于32k的時候,才能看到符合我們心理預期的效果——.last文件把數據移到.data文件,.last文件變小,.data文件變大。
以上場景只針對兩個表,但其實放大到100個表,1000個表都是一樣的邏輯。盡管每個vnode內存里存儲的大量數據分屬于不同的表,但是每次落盤只要這些表的行數保證大于minrows,它們都會落入到.data文件的數據塊中。不滿足上述條件的表數據被寫入.last文件后,繼續等待新數據的寫入,直到該表滿足了行數minrows的大小后,.last文件中該表的數據會被讀入到內存,之后一起寫入到.data文件中。
最后總結一下:
.data類文件存儲的是真正的時序數據,為多個數據塊構成。一個數據塊只屬于一張表,且數據塊的順序只與落盤的先后順序有關。
.last文件與.data文件一樣,也是存儲時序數據的,只不過.last文件存儲的塊中的數據條數小于minRows。
本篇文章重點講述的是.last與.data文件的關系。
關于.head文件,我們會在后面的文章中講解。在此之前,我們只要知道它是用來方便查詢數據的索引文件就可以了。.head文件的用途是什么?它會影響到哪些重要的功能?minrows和maxrows的變化會給性能帶來多大的影響呢?以上這類問題都會涉及到很廣泛的性能問題,我們將會在今后的日子慢慢討論。
如果不了解TDengine的體系架構,對于用戶來說很可能是事倍功半的。現在,濤思數據的每一期內容推送都是在為大家未來可以事半功倍而做的內容沉淀。
關于 TDengine
TDengine ?是一款專為物聯網、工業互聯網等場景設計并優化的大數據平臺,其核心模塊是高性能、集群開源、云原生、極簡的時序數據庫。