Carbondata源碼系列(二)文件格式詳解

在上一章當中,寫了文件的生成過程。這一章主要講解文件格式(V3版本)的具體細節。數組

一、字典文件格式詳解

字典文件的做用是在存儲的時候將字符串等類型轉換爲int類型,好處主要有兩點:ui

一、減小存儲佔用空間編碼

二、用在須要group by的字段上比較合適,能夠減小計算時的shuffle的數據量。spa

每個字典列都有對應的三種文件.dict, .sortindex, .dictmeta文件,輸出格式都是thrift格式code

1.1 .dict文件

字典的值每滿1000就做爲一個chunk輸出一次,具體的類是ColumnDictionaryChunkblog

相關參數:排序

carbon.dictionary.chunk.size索引

1.2 .sortindex文件

把字段的值sort了一下以後,計算出每一個值的sortIndex和invertedIndex,具體的類是ColumnSortInfoci

一、List<SortIndex>,記錄着每一個字典值的surrogate,從1開始字符串

二、List<SortInvertedIndex>,記錄着每一個字典surrogate在數組中的位置,從1開始

它們的關係以下:

      sortIndex[i] = dictionarySortModel.getKey();
      // the array index starts from 0 therefore -1 is done to avoid wastage
      // of 0th index in array and surrogate key starts from 1 there 1 is added to i
      // which is a counter starting from 0
      sortIndexInverted[dictionarySortModel.getKey() - 1] = i + 1;

假設字典值是beijing,shenzhen,shanghai

城市 surrogate sortIndex invertIndex
beijing 1 1 1
shenzhen 2 3 3
shanghai 3 2 2

 

 

 

1.3 .dictmeta文件

該文件主要記錄字典的如下屬性,具體的類是ColumnDictionaryChunkMeta

一、最小key

二、最大的key

三、開始offset

四、結束offset

五、chunk的數量

二、數據文件詳解

2.1 數據塊的組成部分

CarbonRow在sort階段會被分紅3個部分:

一、字典列

二、非字典維度列和高基數列

三、度量值列

在寫入的時候,先寫入到TablePage裏,TablePage會把數據拆分紅4部分

// one vector to make it efficient for sorting
private ColumnPage[] dictDimensionPages;
private ColumnPage[] noDictDimensionPages;
private ComplexColumnPage[] complexDimensionPages;
private ColumnPage[] measurePages;

 每一個TablePage都會記錄如下幾個Key:

private byte[][] currentNoDictionaryKey;
// MDK start key
private byte[] startKey;
// MDK end key
private byte[] endKey;
// startkey for no dictionary columns
private byte[][] noDictStartKey;
// endkey for no diciotn
private byte[][] noDictEndKey;
// startkey for no dictionary columns after packing into one column
private byte[] packedNoDictStartKey;
// endkey for no dictionary columns after packing into one column
private byte[] packedNoDictEndKey;

數據在一行一行寫到TablePage以後,最後會作一次統一的編碼,詳細的方法請看TablePage的encode方法。

Page的meta信息

  private DataChunk2 buildPageMetadata(ColumnPage inputPage, byte[] encodedBytes)
      throws IOException {
    DataChunk2 dataChunk = new DataChunk2();
    dataChunk.setData_page_length(encodedBytes.length);
    fillBasicFields(inputPage, dataChunk);
    fillNullBitSet(inputPage, dataChunk);
    fillEncoding(inputPage, dataChunk);
    fillMinMaxIndex(inputPage, dataChunk);
    fillLegacyFields(dataChunk);
    return dataChunk;
  }

一個blocket的閾值是64MB,一個blocket包括N個TablePage,當寫滿一個TablePage以後,就把blocket寫入到文件當中。

carbondata的BTree索引,是一個記錄着每一個Blocklet的mdk的startKey和endKey,以及Blocklet當中全部TablePage的列的最大最小值

那麼數據文件的詳細格式,基本和官網上介紹的是一致的

2.2 What is MDK

mdk和hbase的rowkey是一個性質的,詳細能夠看下面這張圖,排序方式跟hbase沒有任何區別。可是carbondata的mdk只能是字典列,若是我沒有設置字典列的話,只是設置了SORT_COLUMN,Carbondata的過濾只是靠列的最大最小值

 

三、索引文件詳解

索引文件以.carbonindex結尾

索引文件包括三個部分:索引頭,索引兩部分

索引頭包括:

一、文件格式版本(當前版本是V3)

二、Segment信息(有多少列,列的基數)

三、列的信息

四、bucket ID

 

索引信息包括如下信息:

一、Blocket的記錄數

二、數據文件名

三、Blocket的meta信息offset

三、BlockletIndex (BTree索引,包含blocket的startKey、endKey,以及每一列的最大最小值,這個前面已經講過了)

四、BlocketInfo(記錄數,每一個TablePage的offset,每一個TablePage的長度,維度列dimension_offsets的起始位置,度量值measure_offsets的起始位置,有多少個TablePagenumber_number_of_pages)

 

索引文件的信息在文件的footer當中也是存在的,在carbondata1.2當中索引文件仍是有不少個,感受有點多餘。

到carbondata1.3會被合併成一個文件,這樣就能大大縮短啓動的時候加載索引的開銷。

 

 

岑玉海

轉載請註明出處,謝謝!

 

個人博客即將搬運同步至騰訊雲+社區,邀請你們一同入駐:https://cloud.tencent.com/developer/support-plan

相關文章
相關標籤/搜索