kudu CFile设计文档个人翻译.

CFile

CFile是一种在磁盘上的存放了数据和其相关B-树索引的列式存储结构,在一个DiskRowSet中每一列和DeltaFile都会映射到一个CFile上,此外DIskRowSet的布隆过滤器也会被存储在CFile中,如果这张表含有复合主键,那么与其相关的ad-hoc index也会被存储在各自的CFile中。

  尽管叫CFile,一个CFile也并不一定和真实文件系统中的一个文件一一对应,CFiles和文件系统之间的映射由BlockManager来抽象实现,一个CFile被写入单个的BlockManager Block(不要把它和CFile blocks搞混淆,CFile blocks存在于CFiles中,稍后会对其进行详细的讨论)

一个CFile由一个header,一些blocks,和一个footer组成,可能会有一些不同类型的blocks,每类都有着不同的格式:data blocks(数据块),nullable data blocks(可空数据块),index blocks(索引块),和dictionary blocks(字典块).

其中数据块由一些连续的值组成,每个值都都被分配了一个ordinal index(序数索引),或者一个offset(偏移量),例如,一个CFile的前三块可能具有序号索引范围[0,55],[56,132]和[133,511].

  为了高效的对一个CFile内任意的序数进行索引,一个相对起始序数索引的位置索引可能会被包含在data block中,CFile index文档部分对此有更详细的解释。

  对于内部数据有序的CFiles(比如一个包含了主键列的CFile),它可能会创建一个value index(值索引).值索引能够更高效地在CFile中寻找任意的值,有关详细信息请参阅CFile index文档。

File Format

CFile header,blocks和footer被没有间隔地连续写入一个文件中。

Header 格式

fieldwidth (bytes)notes
magic8see below
length432-bit unsigned length of the following Protobuf message
messagevariableencoded CFileHeaderPB Protobuf message
checksum4optional CRC-32 checksum of magic, length, and message

Footer 格式

fieldwidth (bytes)notes
checksum4optional CRC-32 checksum of message, magic, and length
magic8see below
messagevariableencoded CFileFooterPB Protobuf message
length4unsigned 32-bit length of the preceding Protobuf message

Versioning(版本号)

CFile header和Footer都包含一个magic字符串来指明版本号.

versionstring
CFile v1kuducfil
CFile v2kuducfl2

Data Block 格式

fieldwidth (bytes)notes
datavariableencoded data values
checksum4optional CRC-32 checksum of the data

如果Cfile被配置为使用压缩算法,那么将会在压缩编码后再计算循环冗余检测码.

Nullable Data Block 格式

被标记为可空的列将会被存放在Nullable Data Block中,将会有一个bitmap来表明那些行(或序数偏移量)为空或者非空。

fieldwidth (bytes)notes
value countvariableLEB128 encoded count of values
bitmap lengthvariableLEB128 encoded length of the following null bitmap
null bitmapvariableRLE encoded bitmap
datavariableencoded non-null data values
checksum4optional CRC-32 checksum of the value count, bitmap length, null bitmap, and data

Checksums(校验)

 校验码可以被选择性的写或者更改,当对 header, data, 或者 footer使用checksums时,CFileFooterPB message 会使用incompatible_features bitset 中的一个"checksum"位来让reader知道校验码的存在。

 如果在读数据前发现校验码的存在,那么reader可以选择性的使用校验码来验证数据的正确性.

Data Encodings(数据编码)

block数据在存储之前被编码。如果使用了压缩算法,则首先对块数据进行编码,然后再进行压缩。

数据块大小限制为--cfile-default-block-size字节,如果超出范围CFile添加将增加新块。

Plain Encoding(纯文本编码)

最简单的编码方式,以原本形式存放数值.

固定宽度(整数)类型的纯文本编码由小字节序值组成,后包含两个小字节序 uint32s 的trailer来表明值的数量和其在block中的序数位置。

BINARY或STRING(可变宽度)列的纯文本编码方式如下:

ordinal positionlittle-endian uint32
num valueslittle-endian uint32
offsets positionlittle-endian uint32
valuessequential values with no padding
offsetsgroup-varint frame-of-reference encoded value offsets

 

Dictionary Encoding(字典编码)

字典编码可用于BINARY或STRING列。CFile中的所有字典编码块共有一个相同的字典。如果字典变满(不太理解这句话),CFile中的后续块将切换为纯文本编码。字典被存储为纯文本编码的二进制块,并且编码后的码子被存储为 bitshuffle encoded uint32 s

 

Prefix Encoding(前缀编码)

目前用于BINARYSTRING数据块。这或多或少是基于LevelDB数据块使用的编码格式。

Starts with a header of four Group Varint encoded uint32s:(这部分没有合适的翻译,直接使用原文更准确)

field
number of elements
ordinal position
restart interval
unused

Followed by prefix-compressed values. Each value is stored relative to the value preceding it using the following format:

fieldtype
shared_bytesvarint32
unshared_bytesvarint32
deltachar[unshared_bytes]

Periodically there will be a "restart point" which is necessary for faster binary searching. At a "restart point", shared_bytes is 0 but otherwise the encoding is the same.

At the end of the block is a trailer with the offsets of the restart points:

fieldtype
restart_pointsuint32[num_restarts]
num_restartsuint32

The restart points are offsets relative to the start of the block, including the header.

Run-length Encoding(不知道怎么翻译)

可以作用于整数和bool类型,其具有简单的格式:以小段序列unint32存放值的数量和其序号偏移量,接着是Run-length 编码的数据.如果数据不适用于Run-length 编码,将自动回退到bit-packed (literal) 编码.

Bitshuffle Encoding(不知道怎么翻译)

适用于整数类型,Bitshuffle编码的块自动进行LZ4压缩,因此不建议进行额外的压缩.

Group Varint Frame-of-Reference Encoding(不知道怎么翻译)

 用于内部的UINT32 blocks,因为kudu的列数据不支持无符号整数,所以这种编码方式不适用于列数据.

Starts with a header of four group-varint encoded uint32s:

field
number of elements
minimum element
ordinal position
unused

 ordinal position是指当前file中第一个item的ordinal position,比如,如果当前file中第一个data block的ordinal position为0,如果这个data block又包含400个值,那么第二个data block的ordinal position就是400.

 Followed by the actual data, each set of 4 integers using group-varint. The last group is padded with 0s. Each integer is relative to the min element in the header.(不会很好的翻译,直接贴原文)

CFile Index

CFile可以选择性的包含 positional (ordinal) index (序数索引)和 value index(值索引),Positional indexes用于解决像"查找这个CFile中包含第N项的data block"这样的询问,而Value indexes用于处理像"查找这个Cfile中包含 123 的data block".只有在数据有序时CFile中才会有 Value indexes(比如包含主键).

序数索引和值索引被组织成一个以index blocks(索引块)构成的B-Tree,当写入data block时,entries会被加到叶子节点的后边,当叶子节点的大小达到上限时,它将被添加到树上方的另一个索引块中,并启动一个新叶子,如果中间索引块填满,它将创建一个新的中间块并涌入到更高层的块。

例如: 

                      [Int 0]
           -----------------------------
           |                           |
        [Int 1]                     [Int 2]
   -----------------             --------------
   |       |       |             |            |
[Leaf 0]  ...   [Leaf N]     [Leaf N+1]   [Leaf N+2]

  在这个例子中,我们写入N个叶子节点块,他们已经填满了编号为Int 1的中间节点,此时writer会闯进一个Int 0节点来指向int 1,.其他两个叶子块(N + 1和N + 2)将被写入新的中间节点(Int 2),当file写入完成后,INT2 也会涌向INT 0(这句翻译可能有问题)。

请注意,此策略不会产生完全平衡的B树,而是在每个level的所有节点上产生100%的“填充因子”,除了写入的最后一个节点。

对于两种类型的索引,索引块的编码方式类似:

<key> <block offset> <block size>
<key> <block offset> <block size>
...
   key: vint64 for positional, otherwise varint-length-prefixed string
   offset: vint64
   block size: vint32

<offset to first key>   (fixed32)
<offset to second key>  (fixed32)
...
   These offsets are relative to the start of the block.

<trailer>
   A IndexBlockTrailerPB protobuf
<trailer length>

使用后序遍历来写入索引块,并且索引块可以与数据块交叉(??)

trailer protobuf 包含了一个field来指明一个block是B-Tree的一个叶子节点还是中间节点,reader可以以此判断指针是指向另一个索引块还是数据块.

DeltaFile(原文准确)

Every DeltaFile in a DiskRowSet is written to a CFile; in fact, a DeltaFile is just a wrapper around CFile which specializes it for REDO and UNDO delta data. The deltas associated with a row update are grouped into a RowChangeList and written to as a binary values to the underlying CFile. Each value is prefixed with a DeltaKey, which consists of the ordinal row index (within the DiskRowSet), and the timestamp. The CFile includes a value index so that the delta belonging to a specific row can be located efficiently.

BloomFile

BloomFile is a wrapper around CFile which stores a bloomfilter datastructure.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值