在上一期的文章(《五分鐘掌握TDengine時序數(shù)據(jù)的保留策略》)中,我們知道了TDengine Database是如何按照時間段對數(shù)據(jù)進行分區(qū)來管理數(shù)據(jù)的。
接下來,我們和大家一起從產(chǎn)品使用者的視角繼續(xù)向前探索——TDengine中的時序數(shù)據(jù)到底是如何存儲的?
在那篇文章里,在我們第一次寫入數(shù)據(jù)并重啟數(shù)據(jù)庫服務(wù)后,在vnode xx路徑下看到了這三個文件。

這哥仨,其實就是TDengine中廣義上的數(shù)據(jù)文件,也可以說它們是一個數(shù)據(jù)文件組。
從后綴上看,仿佛.data這個文件就是數(shù)據(jù)文件組中的數(shù)據(jù)文件。而其他二位都是為它保駕護航的“輔助”。但是這個感覺是不夠準確的,因為.last文件同樣也會存儲數(shù)據(jù)。而.head文件則是存儲數(shù)據(jù)塊的索引的文件。
在了解它們之前,首先我們要知道兩個參數(shù):
1.minRows:數(shù)據(jù)塊中記錄的最小條數(shù),單位為條,默認值為100。
2.maxRows:數(shù)據(jù)塊中記錄的最大條數(shù),單位為條,默認值為4096。
數(shù)據(jù)塊,是每個.data數(shù)據(jù)文件里存儲數(shù)據(jù)的單位,每一個數(shù)據(jù)塊都只能存儲一個表的數(shù)據(jù)。所以上面的參數(shù)描述的意思就是——形成一個數(shù)據(jù)塊默認的最小行數(shù)是100行,最多就是4096行。
那么,對于一張表來說,小于100行的話數(shù)據(jù)會去哪兒呢?大于4096行的話數(shù)據(jù)又去哪兒了呢?
答案是,.last文件正是表行數(shù)不足100時數(shù)據(jù)存放的位置;而大于4096行的表會生成一個新的數(shù)據(jù)塊。最終在.data文件中,數(shù)據(jù)塊的分布方式如下:

當(dāng)然,這樣講會比較抽象,我們繼續(xù)用實例說明:
我們假設(shè)創(chuàng)建庫時使用的參數(shù)為,maxrows=1000,minrows=100。某庫中有兩張表A和B,我們向其中分別插入1000行和99行數(shù)據(jù)。然后,我們重啟taosd服務(wù),以上數(shù)據(jù)就會從內(nèi)存中落盤到存儲上。這個時候.data文件中會生成1個數(shù)據(jù)塊,它就是表A的數(shù)據(jù)塊1,里面擁有1000條數(shù)據(jù)。而表B的99條數(shù)據(jù)因為不足minrows所以就進入了.last文件。
接下來,繼續(xù)向它們分別插入1000行和99行,然后重啟taosd服務(wù)落盤。這個時候表A總共擁有2000條數(shù)據(jù),新寫入的1000行數(shù)據(jù)會被寫入進表A的數(shù)據(jù)塊2。而表B的數(shù)據(jù)量現(xiàn)在已經(jīng)有了198行,大于了100行。于是它們也會被寫入.data文件里面,成為表B的數(shù)據(jù)塊1。
值得注意的是,當(dāng).last文件小于32k的時候,所有數(shù)據(jù)都只會追加進來。但是當(dāng).last文件大于32k的時候,每次落盤.last文件都是重寫生成的了——這個的32k限制是為了防止數(shù)據(jù)的移動過于頻繁。
所以,我們在做測試的時侯會發(fā)現(xiàn):為什么當(dāng)該表行數(shù)從99到100行以上時,.data文件的大小已經(jīng)增加可.last文件卻沒有變小。只有當(dāng).last文件大于32k的時候,才能看到符合我們心理預(yù)期的效果——.last文件把數(shù)據(jù)移到.data文件,.last文件變小,.data文件變大。
以上場景只針對兩個表,但其實放大到100個表,1000個表都是一樣的邏輯。盡管每個vnode內(nèi)存里存儲的大量數(shù)據(jù)分屬于不同的表,但是每次落盤只要這些表的行數(shù)保證大于minrows,它們都會落入到.data文件的數(shù)據(jù)塊中。不滿足上述條件的表數(shù)據(jù)被寫入.last文件后,繼續(xù)等待新數(shù)據(jù)的寫入,直到該表滿足了行數(shù)minrows的大小后,.last文件中該表的數(shù)據(jù)會被讀入到內(nèi)存,之后一起寫入到.data文件中。
最后總結(jié)一下:
.data類文件存儲的是真正的時序數(shù)據(jù),為多個數(shù)據(jù)塊構(gòu)成。一個數(shù)據(jù)塊只屬于一張表,且數(shù)據(jù)塊的順序只與落盤的先后順序有關(guān)。
.last文件與.data文件一樣,也是存儲時序數(shù)據(jù)的,只不過.last文件存儲的塊中的數(shù)據(jù)條數(shù)小于minRows。
本篇文章重點講述的是.last與.data文件的關(guān)系。
關(guān)于.head文件,我們會在后面的文章中講解。在此之前,我們只要知道它是用來方便查詢數(shù)據(jù)的索引文件就可以了。.head文件的用途是什么?它會影響到哪些重要的功能?minrows和maxrows的變化會給性能帶來多大的影響呢?以上這類問題都會涉及到很廣泛的性能問題,我們將會在今后的日子慢慢討論。
如果不了解TDengine Database的體系架構(gòu),對于用戶來說很可能是事倍功半的?,F(xiàn)在,濤思數(shù)據(jù)的每一期內(nèi)容推送都是在為大家未來可以事半功倍而做的內(nèi)容沉淀。為了強化關(guān)于TDengine存儲模型的理解,建議大家可以回頭看看這兩篇文章(《這幾個神秘參數(shù),教你TDengine集群的正確使用方式》,《存儲成本僅為OpenTSDB的1/10,TDengine的最大殺手锏是什么?》),其中的知識點都不是割裂的。
我們擔(dān)心的不是產(chǎn)品不好用,而是產(chǎn)品沒用好。



互聯(lián)網(wǎng).png)



-1.png)










伙伴.png)
伙伴.png)
伙伴.png)



