Clickhouse MergeTree 存储引擎架构总结——Clickhouse 架构篇(二)

news2024/11/15 21:34:19

文章目录

  • 前言
  • MergeTree存储引擎的三大特点
  • MergeTree 的数据组织
  • MergeTree的文件组织
    • 数据文件、元数据文件、索引文件和其他文件
    • 分区
    • 数据库和表
  • 索引
  • 与事务数据库存储引擎的对比
  • 存储引擎如何影响查询速度
  • MergeTree存储引擎的工作过程

前言

存储引擎是ClickHouse非常重要的一个组件,MergeTree表引擎又是 Clickhouse 引擎中最流行的,同时 Clickhouse 之所以查询速度快,与它又密切相关。
本文将对 Clickhouse 中的 MergeTree 表引擎架构设计进行说明,进而了解该引擎加速查询的原理,最后将列举 SQL 说明 MergeTree 表引擎的工作过程。

MergeTree存储引擎的三大特点

三级数据组织

  • 按照3个层级组织数据及数据文件,分别是数据库、数据表、数据分区。
  • 数据库由一个或多个数据表组成。
  • 数据表由一个或多个数据分区组成。
  • 数据只能被放到数据分区内,如果用户没有明确指定分区,则数据存储于默认名为all的分区。

数据不可变

  • MergeTree中的数据一旦写入,就不能再修改。
  • Clickhouse 中数据不可变的原因是为了提升并发能力,减少数据操作竞争。

密集堆放

  • 数据在内存和文件中都被密集堆放,应尽可能减少控制信息,以降低磁盘I/O、内存占用,提高查询速度。

MergeTree 的数据组织

数据组织说明

  • 数据组织主要描述用户保存的数据是如何在数据文件中保存的。
  • 数据组织是存储引擎的基础,相同的数据可以以不同的数据组织形式写入数据文件。
  • 不同的数据组织形式会带来不同的效果,例如在数据的写入速度、读取速度、检索速度、事务能力等多个方面直接影响着上层计算引擎的功能及运作效率。

数据最小单位

  • Clickhouse 中数据的最小组织单位是**块,**块的大小默认为8192行,即ClickHouse一次性处理8192行数据。

数据堆放方式

  • Clickhouse 是列式存储,不同的列会存储在不同的数据文件中,因此在ClickHouse中只需要考虑数据如何按行堆放。
  • 其中不同的数据类型又决定了数据的堆放方式:定长数据类型和变长数据类型。
  • 定长数据类型的堆放方式类似于数组,可以通过下标访问元素,实现简单、随机取数效率高、空间利用率高、算法实现简单。
  • 变长数据类型的堆放方式有三种堆叠方式:
    • 使用固定的分隔符
    • 在另一个数组中记录每个元素的长度
    • 将数据写入额外的数据文件,在当前数据文件中记录定长的偏移量

其中 Clickhouse 使用的是第二种方式,变长数据类型在内存中会维护两个数组:一个是存储数据的字节数组;另一个是存储元素长度的定界数组。
数据压缩

  • Clickhouse 将数据堆叠成块后,会对数据进行压缩,默认支持3种压缩方式:LZ4、LZ4HC、zstd。ClickHouse默认使用LZ4压缩。
  • 压缩是为了减少磁盘 I/O,提升查询速度,使用 CPU 计算来弥补 磁盘 I/O 瓶颈问题。

MergeTree的文件组织

前边说到的只是 Clickhouse 的数据组织方式,MergeTree 并没有将元数据信息保存到块中。
Clickhouse 将 MergeTree 数据写入文件,以文件组织作为元数据信息管理。
在MergeTree中,数据库、数据表和数据分区都被物化为文件夹表示,数据由一组不同类型的文件组成。MergeTree的文件组织形式如下图所示:
image.png

数据文件、元数据文件、索引文件和其他文件

MergeTree的数据由3种文件组成,分别是数据(bin)文件、索引文件和标记文件。这3种文件是MergeTree进行读取和写入时不可缺少的文件,丢失任意一个文件,都会造成数据损坏,无法读取。除此之外,还有一些辅助文件用于校验、加速查询等功能,这类文件的丢失不会导致数据损坏,可以依据数据进行重建。

数据文件
数据文件的结构如下图所示:
image.png

  • .bin结尾的文件,包含多个块,可以通过该文件获取块字节数据,但是无法对数据进行解析。
  • 每个块数据中包括压缩信息数据和保存实际数据。

元数据文件

  • 元数据文件中存储表结构、字段数据类型、字段数据长度等元数据信息。
  • 文件名固定为Columns.txt,可以直接打开查看相关元信息。
  • 数据文件必须配合元数据文件才能被正确解析。

索引文件

  • 索引文件由索引和标记文件共同组成,分别对应idxmrk后缀.

其他文件

  • checksums.txt:一个二进制文件,存储整个分区数据的校验和。用于快速校验数据是否被篡改。
  • count.txt:文本文件,存储该分区下的行数,可以用文本编辑器打开。在执行select count() from xxx命令时,会直接返回该文件的内容,而不需要遍历数据。
  • default_compression_codec.txt:ClickHouse新版本增加的一个文件,该文件是一个文本文件,存储了数据文件中使用的压缩编码器。ClickHouse提供了多种压缩算法供用户选择,默认使用LZ4。

分区

传统的大数据系统也会使用到分区来加速查询,比如说 Hive。但是在 Clickhouse 中的分区并不是为了加速查询而设计的,而是便于对数据的管理。

相反,在使用 Clickhouse 的时候过多的分区反而会降低查询速度,因为过多的分区意味着更多的文件夹(需要打开更多的文件描述符),在 Clickhouse 中不是通过分区加速查询,是通过索引来加速查询的。

在 Clickhouse 中大部分情况下是不需要创建分区的,创建完分区,分区下对应的文件和子目录说明如下:
image.png

  • 分区目录的格式为分区ID_最小数据块编号_最大数据块编号_层级。
  • 数据块编号从1开始自增,新创建的数据库最大和最小编号相同,当发生合并时会将其修改为合并的数据块编号。同时每次合并都会将层级增加1。

数据库和表

ClickHouse中的数据库和表都被组织为文件夹。
每个数据库都会在ClickHouse的data目录中创建一个子目录,ClickHouse默认携带default和system两个数据库。
default就是默认数据库,system是存储ClickHouse服务器相关信息的数据库,例如连接数、资源占用等。

索引

索引机制是ClickHouse查询速度快的一个很重要的原因,Clickhouse 通过主键索引标记快速查找目标。
主键索引

  • 记录每个块的首个值(最小值),索引数据存储于primary.idx文件。
  • Clickhouse 在插入数据的时候,会通过 LSM 算法保证插入数据的顺序按照用户定义的顺序排列,这样每个块就是有序的,就可以通过主键索引快速定位到数据在哪个块。

主键索引只能定位到数据在哪个块,但是块的位置需要通过标记确定。
标记

  • 通过索引文件和标记文件,才能共同确定一个数据所在的文件位置。
  • 在查询时,首先通过索引确认数据所在的块,然后依据标记确认块所在的物理地址,最后通过物理地址从硬盘上读取数据。

与事务数据库存储引擎的对比

Clickhouse事物数据库
基本单位
- 最小单位是块,块的大小一般在64KB~1MB之间
- 通过一次性操作整个块以提高I/O效率

- 基本单位是页,大小一般为4KB或8KB
- 对行的操作记录到内存页中,定期以页为单位写入磁盘,以提高I/O效率
数据顺序
- 对数据按照表结构进行排序并写入存储设备

- 事务数据库则按照事务的先后顺序写入存储设备
索引方式
- 使用稀疏索引,且数据在写入时已经完成了排序,足以支撑快速的范围查询

- 使用B+树建立稠密索引,将索引进行排序后以实现更快的范围查询
控制信息
- 控制信息占用数据量小
- 不适合点查

- 控制信息占用数据量大
- 适合点查
压缩
- MergeTree将数据压缩后写入存储设备
- 查询瓶颈在于磁盘I/O

- 不对数据压缩
- 通过锁机制和MVCC实现原子性和隔离性,通过WAL机制实现持久性,通过完整性约束提供一致性保证

存储引擎如何影响查询速度

Clickhouse 在对数据进行保存的时候就以便利查询为目的进行保存,因此 Clickhouse 可以快速查询到数据所在位置,Clickhouse 查询大量的时间消耗在磁盘 I/O 上,因此如何减少磁盘 I/O 就是存储引擎要做的事情。
预排序

  • Clickhouse 在写入数据时会对数据进行排序,这样在进行范围查询的时候就可以将随机读转换为顺序读,提高 I/O 效率。
  • 预排序虽然提升了查询性能,相对的降低了写入性能。
  • Clickhouse 使用修改过的 LSM 算法实现预排序,不允许数据修改,降低了传统 LSM 算法读放大效应,进一步缩短了磁盘 I/O 时间。

列存

  • 列式存储中每一列的数据是在同一个文件中保存着的,在磁盘上数据是连续的,特别适合 OLAP 查询。
  • 由于列存的保存方式,表中列的增加不会带来额外的开销,因此 Clickhouse 特别适合创建大宽表,便于查询分析。

压缩

  • 压缩可以减少读取和写入的数据量,从而减少I/O时间,由于列存数据相关性很高,因此 Clickhouse 对于数据压缩支持很好,拥有比较大的压缩比。
  • ClickHouse的最小处理单元是块,块一般由8192行数据组成,ClickHouse进行一次压缩针对的是8192行数据,这就极大降低了CPU的压缩和解压缩时间。

MergeTree存储引擎的工作过程

数据库、数据表的创建过程

  • 数据库和数据表在MergeTree存储引擎中对应一个文件夹,当执行下列SQL语句时,本质上就是由MergeTree存储引擎在磁盘上的数据目录中创建一个对应的文件夹。
    create database xxx;
    create table xxx (xxx string ...)
    

数据插入过程

  • 插入操作会在表所在的文件夹下创建一个新的分区文件夹
  • 然后按照MergeTree的文件组织原则在分区文件夹中创建对应的数据文件、元数据文件、索引文件和其他文件。

分区合并和删除过程

  • Clickhouse 存在两种分区:逻辑分区和物理分区,逻辑分区是按照用户建表时所设置的规则进行的分区,物理分区是MergeTree存储引擎在实现内部算法时,不可避免地对用户逻辑分区进行物理拆分而得到的分区。
  • MergeTree的分区合并指的是物理分区的合并,不支持对逻辑分区进行合并。
  • MergeTree的分区删除指的是逻辑分区的合并,不支持对物理分区进行删除。
  • 分区合并是MergeTree引擎自行启动的,而分区删除是按照用户指令启动的,用户无法直接操作物理分区,只能通过控制逻辑分区,间接控制物理分区

数据读取过程

  • Clickhouse 通过索引进行加速查询,在写入数据的时候会预排序,MergeTree引擎的查询加速效果与表结构密切相关,同一条查询语句,在不同的表结构上有着不同的表现。

我们在定义表的时候一定要注意 ORDER BY的使用,假设有一张用户信息表如下:

idsexage
1Male27
2Femal33

查询 SQL 如下:

SELECT AVG(age) FROM tb1 WHERE sex = 'Male';
  • sex作为唯一排序键(主键)

    CREATE TABLE tb1
    (
      id UInt 64,
      sex String comment '性别',
      age int comment '年龄'
    )ENGINE = MergeTree()
    ORDER BY sex;
    
  • sex作为联合排序键(主键)之一且在最左侧

    -- Clickhouse 的索引匹配也满足最左侧匹配原则,下边的建表方式查询时也会走索引
    CREATE TABLE tb1
    (
      id UInt 64,
      sex String comment '性别',
      age int comment '年龄'
    )ENGINE = MergeTree()
    ORDER BY sex,age;
    
  • sex作为联合排序键(主键)之一且不在最左侧

    CREATE TABLE tb1
    (
      id UInt 64,
      sex String comment '性别',
      age int comment '年龄'
    )ENGINE = MergeTree()
    ORDER BY age,sex;
    

    使用上边SQL语句创建tbl表。在这种情况下,tbl表中的sex列作为排序键之一且不在最左侧,需要依据主键左侧列和sex列的数据分布进行判断,是一个不确定的场景。
    最好的情况是左侧主键和sex存在很强的相关性,此时性能接近于sex作为联合排序键(主键)之一且在最左侧的情况。
    最差的情况是完全独立的两个列,且sex分布于每一个块中,此时会触发全表扫描,性能接近于未将sex作为排序键的情况。

  • sex不属于排序键(主键)

    -- 上边的查询会触发全表扫描,性能最差
    CREATE TABLE tb1
    (
      id UInt 64,
      sex String comment '性别',
      age int comment '年龄'
    )ENGINE = MergeTree()
    ORDER BY age;
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1705407.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS(七)

文章目录 CSS(七)1. 精灵图(重点)1.1 为什么需要精灵图1.2 精灵图(sprites)的使用1.3 案例:拼出自己名字1.3.1 案例效果1.3.2 代码参考 2. 字体图标2.1 字体图标的产生2.2 字体图标的优点**2.3*…

2951. 找出峰值

找出数组中的峰值 给你一个下标从 0 开始的数组 mountain 。你的任务是找出数组 mountain 中的所有 峰值。 以数组形式返回给定数组中 峰值 的下标,顺序不限 。 注意 峰值 是指一个严格大于其相邻元素的元素。数组的第一个和最后一个元素 不 是峰值。 示例 1 …

当下sprign boot最火最全的经典面试题

基础概念 什么是Spring Boot?Spring Boot的核心优势是什么?Spring Boot与传统的Spring MVC项目相比,有哪些显著的区别?Spring Boot如何实现“约定优于配置”原则?请举例说明。解释Spring Boot中的Starter POMs概念及其…

创建你的RedTeam基础架构

随着RedTeaming行业的发展,我们对构建可靠环境的需求也越来越高。至关重要的是要拥有维护健壮的基础架构的能力,该基础架构要保证一旦出现问题就可以重新创建,更重要的是,我们需要确保环境在部署时不会出现问题。 今天&#xff0c…

git@gitee.com: Permission denied (publickey)

1、报错信息 $ git clone gitgitee.com:你的用户名/项目名.git Cloning into 项目名... gitgitee.com: Permission denied (publickey). fatal: Could not read from remote repository.Please make sure you have the correct access rights and the repository exists.、 2、…

Unity 权限 之 Android 【权限 动态申请】功能的简单封装

Unity 权限 之 Android 【权限 动态申请】功能的简单封装 目录 Unity 权限 之 Android 【权限 动态申请】功能的简单封装 一、简单介绍 二、Android 权限 动态申请 三、实现原理 四、注意事项 五、案例实现简单步骤 附录: 一、进一步优化 二、多个权限申请…

AI日报|苹果将在iOS 18中引入ChatGPT,联想或成AI PC最大受益者

文章推荐 AI日报|阿里8亿美元购入月之暗面36%股份,Meta首席杨立昆建议不要研究大模型 阿里通义降价,百度文心免费,一图对比谁是最具性价比大模型? 苹果与OpenAI达成协议:将在iOS 18中提供ChatGPT聊天机器…

服务器数据恢复—EVA存储异常断电重启后虚拟机无法启动如何恢复数据?

服务器存储数据恢复环境: 某品牌EVA8400,服务器上安装VMware ESXi虚拟化平台,虚拟机的虚拟磁盘包括数据盘(精简模式)快照数据盘,部分虚拟机中运行oracle数据库和mysql数据库。 服务器存储故障&检测&…

精准数据提取:提升业务分析与决策效率

在当今信息爆炸的时代,数据已经成为企业运营和决策的核心驱动力。然而,面对海量的数据,如何快速、准确地提取出有价值的信息,成为了摆在众多企业面前的一大挑战。本文将探讨如何通过精准数据提取来提升业务分析与决策的效率。 一…

数据中台建设方案(Word版源文档)

建设大数据管理中台,按照统一的数据规范和标准体系,构建统一数据采集﹣治理﹣共享标准、统一技术开发体系、统一接口 API ,实现数据采集、平台治理,业务应用三层解耦,并按照统一标准格式提供高效的…

有趣的css - 双开门按钮

大家好,我是 Just,这里是「设计师工作日常」,今天分享的是一个双开门的按钮,交互效果比较强,但是实现很简单,快学起来吧。 最新文章通过公众号「设计师工作日常」发布。 目录 整体效果核心代码html 代码cs…

【Redis】 关于 Redis 集合类型

文章目录 🍃前言🌳普通命令🚩sadd🚩smembers🚩sismember🚩scard🚩spop🚩smove🚩srem 🌲集合间操作🚩sinter🚩sinterstore&#x1f6a9…

Serpens3通过 运行脚本,向python传参

def main(a):print(a)#pid等变量名,需要和serpens中同名 main(pid)若.py文件要运行更多的逻辑,可以传参定义执行哪个函数 如何将执行完成的python返回参数给serpens3

2024年湖北水平能力测试能搞定吗?

武汉中级职称报名正式高一段落,意味着今年武汉市中级职称报名除开东湖高新区之外,其余地方都已经正式截止了,那么接下来大家都在准备6月中下旬的水平能力测试考试。 水平能力测试分为两种:面试答辩或者笔试机考试卷,面…

嵌入式进阶——温湿度传感器

🎬 秋野酱:《个人主页》 🔥 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 DHT11温湿度模块原理图官方参考电路数据线通讯协议单总线传送数据位定义数据格式:校验位数据定义 协议实现 DHT11温湿度模块 DHT1…

哇!数据中台竟是企业数字化转型的关键力量!

在当今数字化浪潮席卷的时代,数据中台正成为企业实现数字化转型的关键力量。那么,究竟什么是数据中台呢?它乃是一种持续让企业数据活跃起来的机制,能够将企业内各部分数据汇聚至一个平台,达成数据的统一化管理。 数据中…

idea中快速找到当前git地址

idea中快速找到当前git地址 然后双击就可以看到地址了

apexcharts数据可视化之饼图

apexcharts数据可视化之饼图 有完整配套的Python后端代码。 本教程主要会介绍如下图形绘制方式: 基础饼图单色饼图图片饼图 基础饼图 import ApexChart from react-apexcharts;export function SimplePie() {// 数据序列const series [44, 55, 13, 43, 22]// …

IEEE Account个人姓名修改方法,5分钟解决!

一、背景 之前在注册IEEE Account时,最基础的first name是名,last name是姓都搞错了,太粗心了。然后发现IEEE账户的姓名不能随便修改,需要联系IEEE support center,然后经过一系列探索,发现下面两种方法可…

微软如何打造数字零售力航母系列科普11 - 什么是Microsoft Fabric中的数据工程?

什么是Microsoft Fabric中的数据工程? 目录 1. Lakehouse(湖边小屋) 2. Apache Spark Job Definition (作业定义) 3. Notebook(笔记本) 4. Data Pipeline (数据管道) Microsoft Fabric中的数据工程使用户能够设计、构建和维护基础架构和系统,使其组…