ClickHouse源码阅读计划(一) Everything About MergeTree.docxVIP

ClickHouse源码阅读计划(一) Everything About MergeTree.docx

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
ClickHouse源码阅读方案(一) - Everything About MergeTree 我们晓得数据以列存方式组织,那么即便是读取一行数据也要把整个.bin文件加载到内存,那么这样是很消耗IO的,那CK是如何在存储引擎来处理IO读放大问题呢? ClickHouse引入了颗粒度这个概念。每个data part都会被规律划分为若干个Granules,Granule作为CK在内存中进行数据扫描的单位。写入数据会依据index_granularity或者index_granularity_bytes 参数来积累成一个Granule,默认是8192行一个Granule ,当若干个Granule在内存的buffer中又积累到肯定量(min_compress_block_size 默认64KB)的时候就会触发数据压缩和落盘操作而生成一个Block。每个Granule会对应.mrk文件中的一个mrk。 Block Block作为CK进行磁盘IO的基本单位和文件压缩/解压缩的基本单位。每一个Block都有若干个Granules。在CK的代码内我们也可以看到很多以Block为单位的字节流接口,说明数据在读写字节流中都是以Block为单位进行传输的。block的大小范围取决于max_compress_block_size和min_compress_block_size,每个block的文件头都会保存该block压缩前后大小,用于数据校验。 这里顺便引见一下header:在CompressionInfo.h头文件中我们可以看到其内存规划 /** The compressed block format is as follows: * * The first 16 bytes are the checksum from all other bytes of the block. Now only CityHash128 is used. * In the future, you can provide other checksums, although it will not be possible to make them different in size. * * The next byte specifies the compression algorithm. Then everything depends on the algorithm. * * 0x82 - LZ4 or LZ4HC (they have the same format). * Next 4 bytes - the size of the compressed data, taking into account the header; 4 bytes is the size of the uncompressed data. * * NOTE: Why is 0x82? * Originally only QuickLZ was used. Then LZ4 was added. * The high bit is set to distinguish from QuickLZ, and the second bit is set for compatibility, * for the functions qlz_size_compressed, qlz_size_decompressed to work. * Although now such compatibility is no longer relevant. * * 0x90 - ZSTD * * All sizes are little endian. */ 16bytes用于存储校验和 1byte用于标记接受的压缩算法 两个4byte用来存储压缩前后大小 到这里我们就能回答我们刚才提出的两个问题: 1.mrk文件存储着若干个mrk,每个mrk对应一个Granule,分记录着Granule所在的block在压缩文件.bin的偏移量,Granule在block压缩后的偏移量,还记录着每一个Graunle的行数,分别占8个bytes,即一个mark占24个bytes。 2.有了.mrk文件,CK即便是读取一行数据,也不需要把整个.bin文件加载到内存,只需要通过.mrk文件快速定位所查询数据所在的Granule,首先依据该Granule所在的block在.bin文件中的偏移量把block找出来,然后解压,解压之后有依据.mrk中记录的该Granule在解压后的block的偏移量把该Granule找出来。然后就

文档评论(0)

bob157641554 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档