[转帖]clickhouse存储机制以及底层数据目录分布
https://www.cnblogs.com/MrYang-11-GetKnow/p/15818141.html#:~:text=%E6%AF%8F%E4%B8%80%E4%B8%AA%E6%95%B0%E6%8D%AE%E5%BA%93%E9%83%BD%E4%BC%9A%E5%9C%A8clickhouse%E7%9A%84data%E7%9B%AE%E5%BD%95%E4%B8%AD%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E5%AD%90%E7%9B%AE%E5%BD%95%EF%BC%8Cclickhouse%E9%BB%98%E8%AE%A4%E6%90%BA%E5%B8%A6default%E5%92%8Csystem%E4%B8%A4%E4%B8%AA%E6%95%B0%E6%8D%AE%E5%BA%93%E3%80%82,default%E9%A1%BE%E5%90%8D%E6%80%9D%E4%B9%89%E5%B0%B1%E6%98%AF%E9%BB%98%E8%AE%A4%E6%95%B0%E6%8D%AE%E5%BA%93%EF%BC%8Csystem%E6%98%AF%E5%AD%98%E5%82%A8clickhouse%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9B%B8%E5%85%B3%E4%BF%A1%E6%81%AF%E7%9A%84%E6%95%B0%E6%8D%AE%E5%BA%93%EF%BC%8C%E4%BE%8B%E5%A6%82%E8%BF%9E%E6%8E%A5%E6%95%B0%E3%80%81%E8%B5%84%E6%BA%90%E5%8D%A0%E7%94%A8%E7%AD%89%E3%80%82
在大部分的DBMS中,数据库本质上就是一个由各种子目录和文件组成的文件目录,clickhouse当然也不例外。clickhouse默认数据目录在/var/lib/clickhouse/data目录中。所有的数据库都会在该目录中创建一个子文件夹。下图展示了clickhouse对数据文件的组织。

每一个数据库都会在clickhouse的data目录中创建一个子目录,clickhouse默认携带default和system两个数据库。default顾名思义就是默认数据库,system是存储clickhouse服务器相关信息的数据库,例如连接数、资源占用等。
分区目录
分区目录下的子目录和文件的含义如下:
| 目录名 | 类型 | 说明 |
| 202103_1_10_2 | 目录 | 分区目录一个或多个,由于分区+LSM生成的 |
| detached | 目录 | 通过DETACH语句卸载后的表分区存放位置 |
| format_version.txt | 文本文件 | 纯文本,记录存储的格式 |
分区目录构成
分区目录的构成,按照 分区ID_最小数据块编号_最大数据块编号_层级构成。在本例中,分区ID是202103,最小数据块编号是1,最大数据库编号是10,层级是2。数据块编号从1开始自增,新创建的数据库最大和最小编号相同,当发生合并时会将其修改为合并的数据块编号。同时每次合并都会将层级增加1。
分区ID由用户在创建表时制定,允许用户创建多个分区键,每个分区键之间用‘-’相连。在本例中只使用了一个分区键,即时间字段,按照年月分区。分区的好处在于提高并发度和加速部分查询。
数据目录
进入分区目录后,就能看到数据真实存储的数据目录的结构了。
columns.txt
该文件是一个文本文件,存储了表结构信息,可以用文本编辑打开。
count.txt
该文件也是一个文本文件,存储了该分区下的行数。可以用文本文件打开。在用户执行select count(*) from xxx时本质上就是直接返回了该文件的内容,而不需要遍历数据。因此clickhouse的count(*)的速度非常快。
同时,这边也对比一下MySQL和PostgreSQL的实现,在上述两个关系型数据库中,其常用的存储引擎,都没有使用clickhouse的这种方案。读者们能否回答出为了MySQL或pg要舍弃简单的方案而使用遍历么?
这个问题的答案是由于事务的可见性,MySQL和pg都是用MVCC机制的事务控制技术,这意味着对于不同事务中执行select count(*)的结果是不同的,对于A事务中执行的insert或delete,对于本事务中是可见的,也就是说在本事务中执行的count是计算了insert和delete影响的。而对于B事务,在A事务提交前,是不能看到A事务中对数据的操作的。因此AB两个事务中执行的count后的结果可能是不同的。如果使用clickhouse的方案,就无法实现上述需求。而clickhouse则不需要支持事务,因此使用了相对简单的方案。
primary.idx
主键索引
checksums.txt
二进制文件
default_compression_codec.txt
新版本增加的一个文件,在旧版本时无。该文件是一个文本文件,存储了数据文件中使用的压缩编码器。clickhouse提供了多种压缩算法供用户选择,默认使用LZ4。
[column].mrk3
列的标记文件
[column].bin
真正存储数据的数据文件。每一列都会生成一个单独的bin文件。
skp_idx_[column].idx
跳数索引,在使用了二级索引时会生成,否则这不生成。
skp_idx_[column].mrk
跳数索引标记文件,在使用了二级索引时会生成。否则这不生成
数据组织
如何读取bin文件。由于bin文件是二进制文件,在读取时需要借助工具,无法使用文本文件进行读取。在windows操作系统下建议使用winhex,mac系统推荐hex friend。
数据文件结构

上图展示了一个bin文件的结构。bin文件使用小端字节序存储。bin文件中按block为单位排列数据,每个block文件有16字节校验和,1字节压缩方式,4字节压缩后大小和4字节的压缩前大小组成。每个block起始地址由如下公式确定:
- offset(n)=offset(n-1)+25+压缩后大小 (n>=2)
- offset(1)=0
校验和
前16为检验和区域用于快速验证数据是否完整。
压缩方式
默认为0x82。clickhouse共支持4种压缩方式,分别为LZ4(0x82)、ZSTD(0x90)、Multiple(0x91)、Delta(0x92)。
压缩后大小
存储在data区域的数据的大小。需要依据此大小计算下一个BLOCK的偏移量。
压缩前大小
data区域存储的数据在压缩前的大小。可以依据此计算压缩比。
data区
data区存储数据,大小为头信息第18~21字节表示的大小。拿到data区数据后,由于是压缩后的,因此无法直接识别,需要按照压缩方式进行解压缩后,才能识别。
[转帖]clickhouse存储机制以及底层数据目录分布的更多相关文章
- Java提高篇——通过分析 JDK 源代码研究 Hash 存储机制
HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员,其中 HashMap 是 Map 接口的常用实现类,HashSet 是 Set 接口的常用实 ...
- 通过分析 JDK 源代码研究 Hash 存储机制
通过 HashMap.HashSet 的源代码分析其 Hash 存储机制 实际上,HashSet 和 HashMap 之间有很多相似之处,对于 HashSet 而言,系统采用 Hash 算法决定集合元 ...
- 通过分析 JDK 源代码研究 Hash 存储机制--转载
通过 HashMap.HashSet 的源代码分析其 Hash 存储机制 集合和引用 就像引用类型的数组一样,当我们把 Java 对象放入数组之时,并不是真正的把 Java 对象放入数组中,只是把对象 ...
- Kafka 存储机制和副本
1.概述 Kafka 快速稳定的发展,得到越来越多开发者和使用者的青睐.它的流行得益于它底层的设计和操作简单,存储系统高效,以及充分利用磁盘顺序读写等特性,和其实时在线的业务场景.对于Kafka来说, ...
- Hash存储机制 - HashMap原理 HashSet原理
HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员,其中 HashMap 是 Map 接口的常用实现类,HashSet 是 Set 接口的常用实 ...
- 《Java并发编程的艺术》Java并发机制的底层实现原理(二)
Java并发机制的底层实现原理 1.volatile volatile相当于轻量级的synchronized,在并发编程中保证数据的可见性,使用 valotile 修饰的变量,其内存模型会增加一个 L ...
- java-通过 HashMap、HashSet 的源码分析其 Hash 存储机制
通过 HashMap.HashSet 的源码分析其 Hash 存储机制 集合和引用 就像引用类型的数组一样,当我们把 Java 对象放入数组之时,并非真正的把 Java 对象放入数组中.仅仅是把对象的 ...
- 6.redis 的持久化有哪几种方式?不同的持久化机制都有什么优缺点?持久化机制具体底层是如何实现的?
作者:中华石杉 面试题 redis 的持久化有哪几种方式?不同的持久化机制都有什么优缺点?持久化机制具体底层是如何实现的? 面试官心理分析 redis 如果仅仅只是将数据缓存在内存里面,如果 redi ...
- Java 并发系列之二:java 并发机制的底层实现原理
1. 处理器实现原子操作 2. volatile /** 补充: 主要作用:内存可见性,是变量在多个线程中可见,修饰变量,解决一写多读的问题. 轻量级的synchronized,不会造成阻塞.性能比s ...
- RocketMQ存储机制与确认重传机制
引子 消息队列之前就听说过,但一直没有学习和接触,直到最近的工作流引擎项目用到,需要了解学习一下.本文主要从一个初学者的角度针对RocketMQ的存储机制和确认重传机制做一个浅显的总结. 存储机制 我 ...
随机推荐
- Unity3d_Rewired官方文档翻译:概念(一):InputManager、Players、Actions
仅翻译了官方文档中的Essentials(要点).Concepts(概念)两部分,这是文档中最重要的部分,理解了这两部分的内容应该足以让你将Rewired运用到你的项目中,之后再去阅读文档的其他部分也 ...
- 斯坦福课程 UE4 C++ ActionRoguelike游戏实例教程 0.绪论
前言 UE C++在国内目前还处于比较新的一个领域,网上能找到的教程多为蓝图教程,且质量良莠不齐.终于在B站找到了外网搬运的斯坦福UE C++课程,目前看下来是一个完整的ARPG游戏实例教学,对于入门 ...
- flutter常用的音乐播放器库
audioplayers: 优势:audioplayers 是一个简单易用的音乐播放器库,支持主流平台(Android.iOS)并提供了丰富的功能,比如播放.暂停.快进.音量控制等. 缺点:audio ...
- Unreal学习笔记1-打印输出
1. 概述 相比各种打断点调试的办法,还是更习惯使用打印输出来进行调试. 2. 详论 2.1. 代码 这里写了三个函数:分别是输出到屏幕,输出到警告日志,输出错误日志. Output.h: #prag ...
- gitee图床不能用了,心态崩了
起因 大概上周五晚上吧,想着可以正常下班了.也没啥事,正好可以逛逛自己的小破站,看看有没有小伙伴留言什么的. 然后发现小破站图片显示不出来了... 一开始也没在意,想着可能是Gitee又挂了,可能一会 ...
- Xshell与Xftp安装与使用
Xshell与Xftp安装 软件安装:官网或者应用商店 安装结束 nslicense.dll替换 下载文件 使用 登录 双击刚刚建立的连接 表示建立成功 点击文件传输 右边就是服务器的文件,左边就是本 ...
- 技术实践丨PostgreSQL插件之pg_dirtyread "闪回查询"
摘要:Oracle数据库有时候不小心删除掉数据,想查询这些数据,或者恢复数据,就可以使用带有as of子句的select语句进行闪回查询. PG粉有福了,下面介绍一种类似"闪回查询" ...
- 5步教你将MRS数据导入DWS
摘要:GaussDB(DWS)支持在相同网络中,配置一个GaussDB(DWS)集群连接到一个MRS集群,然后将数据从HDFS中的文件读取到GaussDB(DWS). MapReduce服务(MapR ...
- 华为云FusionInsight MRS:千余节点滚动升级业务无中断
摘要:滚动升级作为大集群数据底座的必备能力,能够完美解决了传统大数据平台操作繁琐.业务停机.升级成本高等问题,实现一个架构的持续演进,业务无中断. 华为开发者大会2021(Cloud)大会期间,由华为 ...
- MRS +Apache Zeppelin,让数据分析更便捷
摘要:选择轻量化.免运维.低成本的大数据云服务是业界趋势,如果搭建Zeppelin再同步自建一套Hadoop生态成本太高!因此我们通过结合华为云MRS服务构建数据中台. 本文分享自华为云社区<M ...