時序資料庫 Apache-IoTDB 源碼解析之文件數據塊(四)

来源:https://www.cnblogs.com/liutaohua/archive/2020/02/12/12298486.html
-Advertisement-
Play Games

上一章聊到行式存儲、列式存儲的基本概念,並介紹了 TsFile 是如何存儲數據以及基本概念。詳情請見: 時序資料庫 Apache-IoTDB 源碼解析之文件格式簡介(三) 打一波廣告,歡迎大家訪問IoTDB 倉庫,求一波 Star 。歡迎關註頭條號:列炮緩開局,歡迎關註OSCHINA博客 這一章主要 ...


上一章聊到行式存儲、列式存儲的基本概念,並介紹了 TsFile 是如何存儲數據以及基本概念。詳情請見:

時序資料庫 Apache-IoTDB 源碼解析之文件格式簡介(三)

打一波廣告,歡迎大家訪問IoTDB 倉庫,求一波 Star 。歡迎關註頭條號:列炮緩開局,歡迎關註OSCHINA博客

這一章主要想聊一聊:

  1. TsFile的文件概覽
  2. TsFile的數據塊

TsFile文件概覽

文件概覽

一個完整的 TsFile 是由圖中的幾大塊組成,圖中的數據塊與索引塊之間使用 1 個位元組的分隔符 2 來進行分隔,這個分隔符的意義是當 TsFile 損壞的時候,順序掃描 TsFile 時,依然可以判斷下一個是 MetaData 是什麼東西。

1. 識別符(Magic)

現在各種軟體五花八門,很多軟體都擁有自己的文件格式用來存儲數據內容,但當硬碟上文件非常多的時候如何有效的識別是否為自己的文件,確認可以打開呢?經常用 windows 系統的朋友可能會想到用擴展名,但假如文件名丟失了,那我們如何知道這個文件是不是能被程式正確訪問呢?

這時候通常會使用一個獨有的字元填充在文件開頭和結尾,這樣程式只要訪問 1 個固定長度的字元就知道這個文件是不是自己能正常訪問的文件了,當然,TsFile 作為一個資料庫文件,肯定需要在這個識別符上精心打造一番,它看起來是這樣:

   (decimal)  84 115 70 105 108 101
   (hex)      54 73  46 69  6c  65
   (ASCII)    T  s   F  i   l   e

非常 cool 。

2.文件版本(Version)

再精妙的設計也難免產生一些問題,那麼就需要升級,那麼文件內容也一樣,有時候當你的改動特別大了,就會出現完全不相容的兩個版本,這個很好理解不過多解釋。TsFile 中採用了 6 個位元組來保存文件版本信息,當前 0.9.x 版本看起來就是這樣:

   (decimal)  48  48  48  48  48  50
   (hex)      30  30  30  30  30  32
   (ASCII)    0   0   0   0   0   2

3.數據塊

數據塊概覽

3.1 ChunkGroup

文件的數據塊中包含了多個 ChunkGroup ,其中 ChunkGroup 的概念已經在上一章聊過,它代表了設備(邏輯概念上的一個集合)一段時間內的數據,在 IoTDB 中稱為 Device。

在實際的文件中,ChunkGroup是由多個 Chunk 和一個 ChunkGroupFooter 組成。其中最後一個 Chunk 的結尾和 ChunkGroupFooter 之間使用 1 個位元組的分隔符 0 來做區分,ChunkGroupFooter 沒有什麼具體作用,不做詳細解釋。

3.2 Chunk

一個 ChunkGroup 中包含了多個 Chunk,它代表了測點數據(邏輯概念上的某一類數據的集合,如體溫數據),在 IoTDB 中稱為 Measurement。

在實際文件中 Chunk 是由 ChunkHeader 和多個 Page 組成,並被 1 個位元組的分隔符 1 包裹。ChunkHeader中主要保存了當前 Chunk 的數據類型、壓縮方式、編碼方式、包含的 Pages 占用的位元組數等信息。

3.3 Page

一個 Chunk 中包含多個 Page,它是一個數據組織方式,數據大小被限制在 64K 左右。

在實際文件中由 PageHeader 和 PageData 組成。其中 PageHeader 里主要保存了,當前 page 里的一些預聚合信息,包含了最大值、最小值、開始時間、結束時間等。他的存在是非常有意義的,因為當某些特定場景的讀時候,不必要解開 page 的數據就能夠得到結果,比如說 selece 體溫 from 王五 where time > 1580950800 , 當讀到 PageHeader 的時候,找到 startTime 和 endTime 就能判斷是否可以使用當前 page。 這個聚合信息的結構同樣出現在索引塊中,下一章再具體聊這個聚合結構。

3.4 PageData

一個 Page 中包含了一個 PageData,裡面有兩個數組:時間數組和值數組,且這兩個數組的下標是對齊的,也就是時間數組中的第一個對應值數組中的第一個。舉個例子:

timeArray: [1,2,3,4]
valueArray: ['a', 'b', 'c', 'd']

在page中就是這樣保存的數據,其中 1 代表了時間 1970-01-01 08:00:00 後的 1 毫秒,對應的值就是 'a'。

數據塊展示

我們繼續使用上一章聊到的示例數據來展示真正的TsFile中是如何保存的。

時間戳人名體溫心率
1580950800 王五 36.7 100
1580950911 王五 36.6 90

當數據被寫入 TsFile 中,大概就是下麵一個展示的情況,這裡省略了索引部分。

            POSITION|	CONTENT
            -------- 	-------
                   0|	[magic head] TsFile
                   6|	[version number] 000002
                  // 因為 6個位元組的magic + 6個位元組的 version 所以 chunkGroup 從 12 開始
|||||||||||||||||||||	[Chunk Group] of wangwu begins at pos 12, ends at pos 253, version:0, num of Chunks:2
                   // 這裡展示的是 ChunkHeader 中保存的信息
                  12|	[Chunk] of xinlv, numOfPoints:1, time range:[1580950800,1580950800], tsDataType:INT32, 
                     	[minValue:100,maxValue:100,firstValue:100,lastValue:100,sumValue:100.0]
                    |		[marker] 1      //  chunk 的真正開始是從這個分隔符 1 開始的
                    |		[ChunkHeader]    // header 的數據在上面展示了
                    |		1 pages         //這裡保存的具體數據
                    |		time:1580950800; value:100
                   // 下一個 chunk
                 121|	[Chunk] of tiwen, numOfPoints:1, time range:[1580950800,1580950800], tsDataType:FLOAT, 
                     	[minValue:36.7,maxValue:36.7,firstValue:36.7,lastValue:36.7,sumValue:36.70000076293945]
                    |		[marker] 1
                    |		[ChunkHeader]
                    |		1 pages
                    |		time:1580950800; value:36.7
                 230|	[Chunk Group Footer]
                    |		[marker] 0 // chunkFooter 和 chunk 使用 0 作為分隔
                    |		[deviceID] wangwu
                    |		[dataSize] 218
                    |		[num of chunks] 2
|||||||||||||||||||||	[Chunk Group] of wangwu ends

回想我們的查詢語句 select 體溫 from 王五 , 當經歷過索引之後會得到 offset 的值等於 121 ,這時候我們只需要調用reader.seek(121),從這裡開始就是所有體溫數據的開始點,從這裡一直讀到 230 的 ChunkGroupFooter 結構的時候,就可以返回給用戶數據了。

有興趣自己實驗的朋友可以,引入 TsFile 的包,自行實驗,下麵給出測試代碼:

<dependency>
    <groupId>org.apache.iotdb</groupId>
    <artifactId>tsfile</artifactId>
    <version>0.9.1</version>
</dependency>
public static void main(String[] args) throws IOException, WriteProcessException {  
  MeasurementSchema chunk1 = new MeasurementSchema("tiwen", TSDataType.FLOAT, TSEncoding.PLAIN);  
  MeasurementSchema chunk2 = new MeasurementSchema("xinlv", TSDataType.INT32, TSEncoding.PLAIN);  
  
  Schema chunks = new Schema();  
  chunks.registerMeasurement(chunk1);  
  chunks.registerMeasurement(chunk2);  
  
  TsFileWriter writer = new TsFileWriter(new File("test"), chunks);  
  
  RowBatch chunkGroup = chunks.createRowBatch("wangwu");  
  
  long[] timestamps = chunkGroup.timestamps;  
  Object[] values = chunkGroup.values;  
  
  timestamps[0] = 1580950800;  
  float[] tiwen = (float[]) values[0];  
  int[] xinlv = (int[]) values[1];  
  
  // 寫入王五的體溫  
  tiwen[0] = 36.7f;  
  //寫入王五的心率  
  xinlv[0] = 100;  
  chunkGroup.batchSize++;  
  
  timestamps[1] = 1580950800;  
  // 寫入第二條王五的體溫  
  tiwen[1] = 36.6f;  
  //寫入第二條王五的心率  
  xinlv[1] = 90;  
  chunkGroup.batchSize++;  
  
  writer.write(chunkGroup);  
  writer.close();  
}

執行完成之後你可以使用 IoTDB 中的 TsFileSketchTool 來查看文件結構,得到文中示例的展示結果;或者使用 od 等工具查看,祝玩兒的開心。IoTDB 0.9.1 版本下載

這一章聊到了 TsFile 分為了 數據塊 和 索引塊,並且介紹了數據塊的具體組成部分和查詢邏輯。那麼索引塊是什麼結構,怎樣完成了在大量混雜的數據中搜索到的想要的數據,請持續關註。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在調用一些Web API時經常要發送或接收一些數據,在構造Json時可能要創建一些類。 很多都是在調用相關方法才使用到這些類,那使用匿名類型是個不錯的選擇。如果要傳些表結構數據時,就要創建List。 匿名類型創建List還是動一下腦筋的。直接上代碼。 ...
  • flash29老版本安裝說明: 如果你是Google Chrome 54及以上版本,那麼直接安裝 install_flash_player_**_ppapi.exe 即可,Chrome 能識別載入,無須再複製到 Chrome 軟體目錄里(除非你要打包便攜版) 註:即使你將此插件安裝到系統,Chrom ...
  • 一、重啟系統,在開機過程中,快速按下鍵盤上的方向鍵↑和↓。目的是告知引導程式,我們需要在引導頁面選擇不同的操作,以便讓引導程式暫停。 以下是暫停後的界面,可以查看下方的英文可知↑和↓的作用。 二、使用↑和↓將選擇行設置為第一行(背景高亮即為選中),按下鍵盤上的e,進入編輯模式 三、將游標一直移動到 ...
  • 1、在需要無密碼登錄遠程伺服器的機器上(如A→B伺服器)生成密碼對 A:伺服器操作: ssh-keygen -t rsa :輸出的內容直接一路回車即可(enter) 執行上面一步,會在~/.ssh目錄下生成兩個文件id_rsa和id_rsa.pub,其中id_rsa是私鑰,保存在本機;id_rsa. ...
  • 下載地址:https://www.elastic.co/cn/downloads/elasticsearch 下載對應需要的 ES 。我這邊是 Linux 的系統。另外 ES 支持 Docker 方式啟動。另外,ES 7.x 不需要本地 JDK 環境支持: ES 5,安裝需要 JDK 8 以上 ES ...
  • ELK簡介: ELK Stack:ELK是Elasticsearch、Logstash、Kibana的縮寫簡稱,這三者都是開源軟體。ELK是5.0版本前的統稱;這是一套統一的日誌收集分析系統。它能夠方便的為我們收集你想要的日誌並且展示出來。 Elastic Stack:是ELK5.0之後加入了Bea ...
  • 壓縮和解壓縮 最早的:compress/uncompresse 文件名尾碼:.Z 然後是:gzip/gunzip 文件名尾碼:.gz 很久一段gzip是linux的標準壓縮和解壓縮演算法了 然後是:bzip2/bunizip2 文件名尾碼:.bz2 大文件的壓縮比比gzip大一點,但是小文件的壓縮比還 ...
  • 資料庫中存入的是一條一條的用戶信息,現在想取出一個人的個人信息,並封裝為Bean對象,可以使用queryForObject來獲取數據並通過new BeanPropertyRowMapper(Bean.class)將數據轉化為javaBean對象 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...