源码分析 | ClickHouse和他的朋友们(6)MergeTree存储结构

语音数据标注工具与平台 最近在做语音深度学习的项目,整理了一下语音数据标注工具和语音标注平台,供大家参考 语音标注工具–Praat Praat是目前已经成为比较流行也比较专业的语音处理的软件,可以进行语音数据标注、语音录制、语音合成、语音分析等等,具有免费、占用空间小、通用性强、可移植性好等特点 官网链接 http://www.fon.hum.uva.nl/praat/ 汉化版下载 http://www.hejingzo... 阅读详情

本文首发于 2020-06-30 21:41:12

《ClickHouse和他的朋友们》系列文章转载自圈内好友 BohuTANG 的博客,原文链接:
https://bohutang.me/2020/06/26/clickhouse-and-friends-merge-tree-disk-layout/
以下为正文。

上篇的 存储引擎技术进化与MergeTree 介绍了存储算法的演进。

存储引擎是一个数据库的底盘,一定要稳和动力澎湃。

接下来我们将一起来探索下 ClickHouse MergeTree 列式存储引擎,解构下这台“跑车”最重要的部件。

所有的存储引擎,无论精良与粗制滥造,最终都是要把数据回写到磁盘,来满足存储和索引目的。

磁盘文件的构造可以说是算法的物理体现,我们甚至可以通过这些存储结构反推出其算法实现。

所以,要想深入了解一个存储引擎,最好的入手点是它的磁盘存储结构,然后再反观它的读、写机制就会有一种水到渠成的感觉。

如果这个分析顺序搞反了,会有一种生硬的感觉,网上大部分教程都是这种“生硬”式教学,本文将直击灵魂从最底层谈起,彻底搞明白4个问题:

  1. MergeTree 有哪些文件?
  2. MergeTree 数据如何分布?
  3. MergeTree 索引如何组织?
  4. MergeTree 如何利用索引加速?

话不多说,上表:

CREATE TABLE default.mt
(
    `a` Int32,
    `b` Int32,
    `c` Int32,
    INDEX `idx_c` (c) TYPE minmax GRANULARITY 1
)
ENGINE = MergeTree
PARTITION BY a 
ORDER BY b
SETTINGS index_granularity=3

造点数据:

insert into default.mt(a,b,c) values(1,1,1);
insert into default.mt(a,b,c) values(5,2,2),(5,3,3);
insert into default.mt(a,b,c) values(3,10,4),(3,9,5),(3,8,6),(3,7,7),(3,6,8),(3,5,9),(3,4,10);

磁盘文件

ls ckdatas/data/default/mt/
1_4_4_0  3_6_6_0  5_5_5_0  detached  format_version.txt

可以看到,生成了 3 个数据目录,每个目录在 ClickHouse 里称作一个分区(part),目录名的前缀正是我们写入时字段 a 的值: 1,3,5,因为表分区是这样定位的:PARTITION BY a。

现在我们看看 a=3 分区:

ls ckdatas/data/default/mt/3_6_6_0/
a.bin  a.mrk2  b.bin  b.mrk2  c.bin  checksums.txt  c.mrk2  columns.txt  count.txt  minmax_a.idx  partition.dat  primary.idx  skp_idx_idx_c.idx  skp_idx_idx_c.mrk2
  • *.bin 是列数据文件,按主键排序(ORDER BY),这里是按照字段 b 进行排序
  • *.mrk2 mark 文件,目的是快速定位 bin 文件数据位置
  • minmax_a.idx 分区键 min-max 索引文件,目的是加速分区键 a 查找
  • primay.idx 主键索引文件,目的是加速主键 b 查找
  • skp_idx_idx_c.* 字段 c 索引文件,目的是加速 c 的查找

在磁盘上,MergeTree 只有一种物理排序,就是 ORDER BY 的主键序,其他文件(比如 .mrk/.idx)是一种逻辑加速,围绕仅有的一份物理排序,要解决的问题是:

在以字段 b 物理排序上,如何实现字段 a、字段 c 的快速查找?

MergeTree 引擎概括起来很简单:
整个数据集通过分区字段被划分为多个物理分区,每个分区內又通过逻辑文件围绕仅有的一种物理排序进行加速查找。

存储结构

数据文件

对于单个物理分区內的存储结构,首先要明确一点,MergeTree 的数据只有一份:*.bin。

a.bin 是字段 a 的数据,b.bin 是字段 b 的数据,c.bin 是字段 c 的数据,也就是大家熟悉的列存储。

各个 bin 文件以 b.bin排序对齐(b 是排序键),如图:

这样会有一个比较严重的问题:
如果 *.bin 文件较大,即使读取一行数据,也要加载整个 bin 文件,浪费了大量的 IO,没法忍。

granule

高、黑科技来了,ClickHouse MergeTree 把 bin 文件根据颗粒度(GRANULARITY)划分为多个颗粒(granule),每个 granule 单独压缩存储。

SETTINGS index_granularity=3 表示每 3 行数据为一个 granule,分区目前只有 7 条数据,所以被划分成 3 个 granule(三个色块):

为方便读取某个 granule,使用 *.mrk 文件记录每个 granule 的 offset,每个 granule 的 header 里会记录一些元信息,用于读取解析:

这样,我们就可以根据 mark 文件,直接定位到想要的 granule,然后对这个单独的 granule 进行读取、校验。

目前,我们还有缺少一种映射:每个 mark 与字段值之间的对应,哪些值区间落在 mark0,哪些落在 mark1 …?

有了这个映射,就可以实现最小化读取 granule 来加速查询:

  1. 根据查询条件确定需要哪些 mark
  2. 根据 mark 读取相应的 granule

存储排序

在了解 MergeTree 索引机制之前,需要明白以下两点:

  1. 只有一份全量数据,存储在 *.bin 文件
  2. *.bin 按照 ORDER BY 字段降序存储

稀疏索引

因为数据只有一份且只有一种物理排序,MergeTree在索引设计上选择了简单、高效的稀疏索引模式。

什么是稀疏索引呢?就是从已经排序的全量数据里,间隔性的选取一些点,并记录这些点属于哪个 mark。

1. primary index

主键索引,可通过[PRIMARY KEY expr]指定,默认是 ORDER BY 字段值。

注意 ClickHouse primary index 跟 MySQL primary key 不是一个概念。

在稀疏点的选择上,取每个 granule 最小值:

2. skipping index

普通索引。

INDEX idx_c(c) TYPE minmax GRANULARITY 1 针对字段 c 创建一个 minmax 模式索引。

GRANULARITY 是稀疏点选择上的 granule 颗粒度,GRANULARITY 1 表示每 1 个 granule 选取一个:

如果定义为GRANULARITY 2 ,则 2 个 granule 选取一个:

3. partition minmax index

针对分区键,MergeTree 还会创建一个 min/max 索引,来加速分区选择。

4. 全景图

查询优化

现在熟悉了 MergeTree 的存储结构,我们通过几个查询来体验下。

1. 分区键查询

语句:

select * from default.mt where a=3

查询会直接根据 a=3 定位到单个分区:

<Debug> InterpreterSelectQuery: MergeTreeWhereOptimizer: condition "a = 3" moved to PREWHERE
<Debug> default.mt (SelectExecutor): Key condition: unknown
<Debug> default.mt (SelectExecutor): MinMax index condition: (column 0 in [3, 3])
<Debug> default.mt (SelectExecutor): Selected 1 parts by a, 1 parts by key, 3 marks by primary key, 3 marks to read from 1 ranges
┌─a─┬──b─┬──c─┐
│ 3 │  4 │ 10 │
│ 3 │  5 │  9 │
│ 3 │  6 │  8 │
│ 3 │  7 │  7 │
│ 3 │  8 │  6 │
│ 3 │  9 │  5 │
│ 3 │ 10 │  4 │
└───┴────┴────┘

2. 主键索引查询

语句:

select * from default.mt where b=5

查询会先从 3 个分区读取 prmary.idx,然后定位到只有一个分区符合条件,找到要读取的 mark:

<Debug> default.mt (SelectExecutor): Key condition: (column 0 in [5, 5])
<Debug> default.mt (SelectExecutor): MinMax index condition: unknown
<Debug> default.mt (SelectExecutor): Selected 3 parts by a, 1 parts by key, 1 marks by primary key, 1 marks to read from 1 ranges
┌─a─┬─b─┬─c─┐
│ 3 │ 5 │ 9 │
└───┴───┴───┘

3. 索引查询

语句:

select * from default.mt where c=5

查询会先从 3 个分区读取 prmary.idx 和 skp_idx_idx_c.idx 进行 granule 过滤(没用的 drop 掉),然后定位到只有 3_x_x_x 分区的一个 granule 符合条件:

<Debug> InterpreterSelectQuery: MergeTreeWhereOptimizer: condition "b = 5" moved to PREWHERE
<Debug> default.mt (SelectExecutor): Key condition: unknown
<Debug> default.mt (SelectExecutor): MinMax index condition: unknown
<Debug> default.mt (SelectExecutor): Index `idx_c` has dropped 1 / 1 granules.
<Debug> default.mt (SelectExecutor): Index `idx_c` has dropped 1 / 1 granules.
<Debug> default.mt (SelectExecutor): Index `idx_c` has dropped 2 / 3 granules.
<Debug> default.mt (SelectExecutor): Selected 3 parts by a, 1 parts by key, 5 marks by primary key, 1 marks to read from 1 ranges
┌─a─┬─b─┬─c─┐
│ 3 │ 9 │ 5 │
└───┴───┴───┘

总结

本文从磁盘存储结构入手,分析 ClickHouse MergeTree 的存储、索引设计。

只有了解了这些底层机制,我们才好对自己的 SQL 和表结构进行优化,使其执行更加高效。

ClickHouse MergeTree 设计简单、高效,它首要解决的问题是:在一种物理排序上,如何实现快速查找。

针对这个问题,ClickHouse使用稀疏索引来解决。

在官方 roadmap 上,列举了一个有意思的索引方向:Z-Order Indexing,目的是把多个维度编码到一维存储,当我们给出多维度条件的时候,可以快速定位到这个条件点集的空间位置,目前 ClickHouse 针对这个索引设计暂无进展。


欢迎关注我的微信公众号【数据库内核】:分享主流开源数据库和存储引擎相关技术。

标题网址
GitHubhttps://dbkernel.github.io
知乎https://www.zhihu.com/people/…
思否(SegmentFault)https://segmentfault.com/u/db…
掘金https://juejin.im/user/5e9d3e…
开源中国(oschina)https://my.oschina.net/dbkernel
博客园(cnblogs)https://www.cnblogs.com/dbkernel
吊打原版YOLOv8!ASF-YOLO多尺度融合+注意力机制实战解析(遥感/医疗/质检均适用) ASF-YOLO融合YOLOv8的创新目标检测框架摘要 ASF-YOLO是针对小目标检测优化的先进框架,采用三重特征编码器和尺度序列融合技术增强多尺度特征提取能力。核心创新包括: 三重特征编码器(TPE)融合跨层级信息 尺度序列特征融合(SSFF)模块通过3D卷积处理多尺度信息 通道-位置注意力机制(CPAM)聚焦关键特征区域 Zoom_cat模块实现自适应多尺度特征融合 该框架特别适用于医学影像、遥感检测等小目标密集场景,通过动态特征权重调整显著提升检测精度。关键技术实现包含多尺度特征统一、3D卷积序列处 阅读详情

相关推荐

Cadence 17.4 PSpice仿真555定时器输出方波

这里利用555定时器组成多谐振荡器产生1Hz的方波并用PSpice仿真其输出的方波波形。555定时器是一种广泛应用的中规模集成电路。根据其内部组成的不同,可分为双极型(555B)和CMOS型(555C)两类。两种类型的定时器各有所长。双极型定时器具有较大的驱动能力,其输出电流可达200mA,可直接驱动发光二级管、扬声器、继电器等负载。而CMOS型定时器的输入阻抗高、功耗低。

tj_nonstoper的博客 1万+

ClickHouse-MergeTree引擎

order by 设定了分区内的数据按照哪些字段顺序进行有序保存 order by是MergeTree中唯一一个必填项目,甚至primary key还重要,因为用户不设置主键的情况,很多处理会依照order by 的字段进行处理 主键必须是order by字段的前缀字段必须包含主键字段 创建二级索引测试表: CREATE TABLE t_order_mt2 ( id UInt32, sku_id String, total_amount DECIMAL ( 16, 2 ), create_

just love code 1067

项目经理面试 5 大高频题 + 实战回答模板,帮你稳拿 offer

项目经理面试5大高频问题及应答技巧 摘要:本文总结了项目经理岗位常见的5个面试问题及回答策略,帮助求职者更有针对性地准备面试。核心问题包括:1)描述负责过的典型项目;2)常用项目管理工具;3)项目遇到的挑战及解决方案;4)风险管理方法;5)项目成功标准。每个问题都从面试官考察重点、回答技巧、实战案例三个维度进行分析,强调要用STAR法则(情境-任务-行动-结果)结构化表达,突出解决问题的能力而非简单罗列经历。特别提醒要量化项目成果(如提前2周上线、节省8%预算等),并注意展示商业思维和团队协作能力。

逸尘谈PM 2108

Clickhouse_6_原理解析 - MergeTree

生生不息,“折腾”不止;Java晋升指北,让天下没有难学的技术

Java晋升指北 1万+

静态时序分析(Static Timing Analysis, STA):简介及内容导航

静态时序分析(简称STA)是用来验证数字设计时序的技术之一,另外一种验证时序的方法是时序仿真,时序仿真可以同时验证功能和时序。“时序分析”这个术语就是用来指代“静态时序分析“或”时序仿真“这两种方法之一,简单来说,时序分析的目的就是为了解决设计中的各种时序问题。STA被称为静态的原因是其对于设计的分析是静态地执行的,并不依赖于施加在输入端口上的激励。相比之下,时序仿真则可以被视作动态地执行对设计的分析,具体过程描述如下:施加一组激励,观察在这组激励下电路行为是否符合要求,然后换一组激。

Starry__的博客 1997

PCB层叠结构与阻抗计算

1.Core 和 PP PCB两个重要组成部分:Core 和 Prepreg(半固态片,简称PP)。 如下图所示, Core 的两个表面都铺有铜箔,可作为信号层、电源层、地层等导电层,Core的上下表面之间填充的是固态材料; PP的表面不铺铜,在PCB中起填充作用,其材质是半固体的树脂材料,因此比Core略软一些。 在制作多层板时,需配合使用Core和PP,一般在两个Core 之间应选PP作为填...

sinat_15677011的博客 1万+

Clickhouse学习(二):MergeTree存储结构

clickhouse

nzbing的博客 662

『OPEN3D』1.2 mesh处理 python篇

介绍open3d对mesh的基本处理操作

NNNNNathan的博客 4648

ClickHouse MergeTree原理解析

本文介绍了ClickHouse MergeTree的基本原理

stable_zl的博客 1504

安装anaconda3时出现错误:Failed to link extracted packages to D:\anaconda!...如何解决?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1483

【GlobalMapper精品教程】073:像素到点(Pixels-to-Points)从无人机图像轻松生成点云

Global Mapper v19引入的新的像素到点工具使用摄影测量原理,从重叠图像生成高密度点云、正射影像及三维模型。它使LiDAR模块成为已经功能很强大的的必备Global Mapper扩展功能。打开GlobalmapperV25.1中文版,点击【Lidar分析】→【像素到点云】,如下所示:V25之前的版本点击工具条上的【像素到点】工具:打开工具,可以【使用向导选】,或者选择【使用主窗口】,都很简单。

智慧空间实验室 1978

《程序是怎么跑起来的》第六章 压缩数据

压缩文件的扩展名有LZH和ZIP等,当文件太大,无法放入软盘中时,或将大附件添加到电子邮箱时,都会采取压缩的方式,将照片保存在计算机上时,也可能使用了JPEG等压缩格式 6.1 文件以字节为单位保存 文件是将数据存储在磁盘等存储媒介中的一种形式,程序文件中存储数据的单位是字节,文件就是字节数据的集合。如果文件中存储的数据是文字,那么文件就是文本文件,如果是图形,那么该文件就是图像文件 文件中的字节数据都是连续存储的 6.2 RLE算法的机制 RLE算法 行程长度编码算法:把文件内容用 数据*重复次数的形式

weixin_43541094的博客 332

【Java基础知识 1】Java入门级概述

优快云最强Java专栏,包含全部Java基础知识点、Java8新特性、Java集合、Java多线程、Java代码实例,理论结合实战,实现Java的轻松学习。

学Java,找哪吒 16万+

源码分析 | ClickHouse和他的朋友们(10)MergeTree Write-Ahead Log

本文首发于 2020-08-20 19:55:14数据库系统为了提高写入性能,会把数据先写到内存,等“攒”到一定程度后再回写到磁盘,比如 MySQL 的 buffer pool 机制。因为数据先写到内存,为了数据的安全性,我们需要一个 Write-Ahead Log (WAL) 来保证内存数据的安全性。今天我们来看看 ClickHouse 新增的 MergeTreeWriteAheadLog 模块,它到底解决了什么问题。对于 ClickHouse MergeTree 引擎,每次写入(即使1条数据)都会在磁盘

dbkernel 的博客 334

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

源码分析 | ClickHouse和他的朋友们(5)存储引擎技术进化与MergeTree

本文首发于 2020-06-22 21:55:1021 世纪的第二个 10 年,虎哥已经在存储引擎一线奋战近 10 年,由于强大的兴趣驱动,这么多年来几乎不放过 arXiv 上与存储相关的每一篇 paper。尤其是看到带有 draft 的 paper 时,有一种乞丐听到“叮当”响时的愉悦。看paper这玩意就像鉴宝,多数是“赝品”,需要你有“鉴真”的本领,否则今天是张三的算法超越xx,明儿又是王二的硬件提升了yy,让你永远跟不上节奏zz,湮灭在这些没有营养的技术垃圾中,浪费大好青春。言归正传,接下来的3篇,

dbkernel 的博客 300

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

设置默认tts引擎_【ClickHouse内核】MergeTree表引擎语法结构

“摘要: 本文主要讲述ClickHouse开源数据库MergeTree表引擎语法结构相关知识点。主要内容如下:概述MergeTree表引擎ReplacingMergeTree表引擎SummingMergeTree表引擎AggregatingMergeTree表引擎GraphiteMergeTree表引擎CollapsingMergeTree表引擎VersionedCollapsingM...

weixin_33531560的博客 329

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Clickhouse源码分析

继承IFunctionpublic::定义返回类型:实现函数逻辑继承IStoragepublic:read:定义数据读取逻辑write:定义数据写入逻辑(可选)alter:支持表结构修改});继承IDataTypepublic::序列化逻辑:反序列化逻辑:创建对应列类型});

Made In SQL 1286

《ClickHouse原理解析与应用实践》读书笔记总结

两周多的时间看完了整本书。ck更新比较快,书中的内容细节有很多地方已经过期了,但是对于了解ck的架构已经足够了。书中并没有多少涉及到代码层面的东西,只是简单提了几个基础类。也没有列出ck的内存模型,并发模型。这些之后都需要根据源码来看的,资料太少。之后我应该会对照源码来梳理一下MergeTree相关的基础操作,比如数据插入和查询时的代码逻辑,数据merge和mutation时的代码逻辑等等。列一个表格来总结一下,我认为从业务侧出发,书中的重点章节,以及原因。第1章 ClickHouse的前世今生第2章 Cl

Aiky哇 379

源码分析 | ClickHouse和他的朋友们(3)MySQL Protocol和Write调用栈

本文首发于 2020-06-08 19:57:10上篇的MySQL Protocol和Read调用里介绍了 ClickHouse 一条查询语句的调用栈,本文继续介绍写的调用栈,开整。建表: 写入数据: 调用栈分析 1. 获取存储引擎 OutputStream 2. 从 SQL 组装 InputStream 如何组装成 inputstream 结构呢? 然后 通过 NullAndDoCopyBlockInputStream的 copyData 方法构造出 Block: 3. 组装 OutputSt

dbkernel 的博客 140

Clickhouse原理&源码分析系列,持续更新

ClickHouse原理&源码分析系列,不定时更新中、

进击的数据小白 564

Clickhouse存储数据流程

由于同一列的数据通常是高度相似的,因此列式存储能够实现极高的压缩比,进一步减少磁盘占用和 I/O 传输量。ClickHouse 的查询引擎在执行查询时,可以快速读取这些经过压缩和排序的数据,并利用分区和索引进一步提升查询速度。这样做可以减少频繁的磁盘写入,提升性能。合并后,ClickHouse 会删除原来的小数据片段,并保留合并后的较大片段,从而优化查询时的 I/O 性能。:ClickHouse 的后台线程会定期执行合并操作,将多个数据片段合并为更大的片段,以提升查询性能,并在必要时进行去重。

goTsHgo的博客 2067

ClickHouse系列教程

ClickHouse系列教程一:Debian/Ubuntu 下ClickHouse的安装和使用 ClickHouse系列教程二:使用航班飞行数据 ClickHouse系列教程三:MergeTree引擎分析 ClickHouse系列教程四:允许远程连接 allow remote access ClickHouse 系列教程五:多种连接方法 - zhangpeterx的博客 - 优快云博客 ...

个人博客 1万+

浅谈clickhouse的Mutation机制(附源码分析)

作者:金科_ 链接:https://www.jianshu.com/p/8f428293594d 来源:简书 最近研究了一点ch的代码。发现一个很有意思的词,mutation。googl...

huzechen的博客 4331

ClickHouse源码阅读(0000 1000) —— PREWHERE optimization

看SQL的执行日志的时候经常会出现这样一条日志如下图,今天来结合源码分析一下: 1、PREWHERE 关键字介绍 PREWHERE Clause This clause has the same meaning as the WHERE clause. The difference is in which data is read from the table. When usin...

B_e_a_u_tiful1205的博客 1690

ClickHouse核心设计

ClickHouse核心设计列式存储数据压缩向量化执行引擎关系模型表引擎多线程和分布式多主架构在线查询数据分片和查询 列式存储 数据压缩 向量化执行引擎 关系模型 表引擎 多线程和分布式 多主架构 在线查询 数据分片和查询 ...

dhylanyu1的博客 231

ClickHouse版本管理深度解析:架构演进与生产环境实战指南

ClickHouse版本管理是企业级实时分析数据库运维的核心技能,直接关系到生产环境的稳定性、数据安全性和系统性能。随着ClickHouse版本的快速迭代,如何制定科学的升级策略、规避兼容性风险、确保数据一致性,成为数据库管理员面临的关键挑战。ClickHouse版本升级不仅仅是软件包的替换,更是一次系统架构的优化过程,需要从底层存储引擎到上层查询优化的全方位考量。 ## 🔍 ClickHou

gitblog_00253的博客 613
上一篇: 源码分析 | ClickHouse和他的朋友们(5)存储引擎技术进化与MergeTree
下一篇: 源码分析 | ClickHouse和他的朋友们(8)纯手工打造的SQL解析器
dbkernel
博客等级 码龄4年 60粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值