首页 > 其他分享 >大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引

大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引

时间:2024-09-25 15:56:15浏览次数:3  
标签:idx 分区 跳数 primary 索引 137 txt 数据


点一下关注吧!!!非常感谢!!持续更新!!!

目前已经更新到了:

  • Hadoop(已更完)
  • HDFS(已更完)
  • MapReduce(已更完)
  • Hive(已更完)
  • Flume(已更完)
  • Sqoop(已更完)
  • Zookeeper(已更完)
  • HBase(已更完)
  • Redis (已更完)
  • Kafka(已更完)
  • Spark(已更完)
  • Flink(已更完)
  • ClickHouse(正在更新···)

章节内容

上节我们完成了如下的内容:

  • 表引擎详解 介绍
  • 日志部分
  • Log部分
  • Memory部分
  • Merge部分

MergeTree

ClickHouse中最强大的表引擎当属 MergeTree(合并树)引擎及该系列(*MergeTree)中的其他引擎。
MergeTree 引擎系列的基本理念如下,当你有巨量数据要插入到表中,你要高效的一批批写入数据片段,并希望这些数据片段在后台按照一定规则合并,相比在插入时不断修改(重写)数据进存储,这种策略会高效很多。

存储结构

创建新表

CREATE TABLE mt_table(date Date, id UInt8, name String) 
ENGINE = MergeTree PARTITION BY toYYYYMM(date) ORDER BY id;

CREATE TABLE mt_table3 (
  `date` Date,
  `id` UInt8,
  `name` String
) ENGINE = MergeTree PARTITION BY toYYYYMM(date) ORDER BY id;

执行的结果如下图所示:

大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引_clickhouse

插入数据

INSERT INTO mt_table VALUES ('2024-07-31', 1, 'wzk');
INSERT INTO mt_table VALUES ('2024-07-30', 2, 'icu');
INSERT INTO mt_table VALUES ('2024-07-29', 3, 'wzkicu');

执行结果如下图所示:

大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引_clickhouse_02

查看目录

cd /var/lib/clickhouse/data/default/mt_table
ls

执行结果如下图所示:

大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引_sql_03


我们随便进入一个目录,可以看到:

  • bin 是按列保存数据的文件
  • mrk 保存块偏移量
  • primary.idx 保存主键索引

存储结构

.
├── 202407_1_1_0
│   ├── checksums.txt
│   ├── columns.txt
│   ├── count.txt
│   ├── data.bin
│   ├── data.mrk3
│   ├── default_compression_codec.txt
│   ├── minmax_date.idx
│   ├── partition.dat
│   └── primary.idx
├── 202407_2_2_0
│   ├── checksums.txt
│   ├── columns.txt
│   ├── count.txt
│   ├── data.bin
│   ├── data.mrk3
│   ├── default_compression_codec.txt
│   ├── minmax_date.idx
│   ├── partition.dat
│   └── primary.idx
├── 202407_3_3_0
│   ├── checksums.txt
│   ├── columns.txt
│   ├── count.txt
│   ├── data.bin
│   ├── data.mrk3
│   ├── default_compression_codec.txt
│   ├── minmax_date.idx
│   ├── partition.dat
│   └── primary.idx
├── detached
└── format_version.txt

执行结果如下图所示:

大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引_大数据_04

  • checknums.txt 二进制校验文件,保存了余下文件的大小size和size的hash值,用于快速校验文件的完整和正确性
  • columns.txt 明文的列信息
  • date.bin 压缩格式(默认LZ4)的数据文件,保存了原始数据,以列名 bin 命名。
  • date.mrk2 使用了自适应大小的索引间隔
  • primary.idx 二进制一级索引文件,在建表的时候通过 order by 或者 primary key 声明稀疏索引。

数据分区

数据是以分区目录的形式组织的,每个分区独立分开存储。这种形式,在数据查询的时候,可以有效的跳过无用的数据文件。

分区规则

分区键的取值,生成分区ID,分区根据ID决定,根据分区键的数据类型不同,分区ID的生成目前有四种规则:

  • 不指定分键
  • 使用整型
  • 使用日期类型 toYYYYMM(date)
  • 使用其他类型
    数据在写入的时候,会按照分区ID落入对应的分区。

分区目录生成

  • BlockNum 是一个全局整型,从1开始,每当新创建一个分区目录,此数字就累加1。
  • MinBlockNum:最小数据块编号
  • MaxBlockNum:最大数据块编号
  • 对于一个新的分区,MinBlockNum和MaxBlockNum的值是相同的

分区目录合并

MergeTree 的分区目录在数据写入过程中被创建,不同的批次写入数据属于同一分区,也会生成不同的目录,在之后某个时刻再合并(写入后10-15分钟),合并后的旧分区目录默认8分钟后删除。

同一个分区的多个目录合并以后得命名规则:

  • MinBlockNum:取同一分区中MinBlockNum值最小的
  • MaxBlockNum:取同一分区中MaxBlockNum最大的
  • Level:取同一分区最大的Level值+1

一级索引

稀疏索引

文件:primary.idx
MergeTree的主键使用PrimaryKey定义,主键定义之后,MergeTree会根据index_granularity间隔(默认8192)为数据生成一级索引并保存至primary.idx中,这种方式就是稀疏索引。
简化形式:通过 ORDER BY 指代 主键

primary.idx 文件的一级索引采用稀疏索引。

  • 稠密索引:每一行索引标记对应一行具体的数据记录
  • 稀疏索引:每一行索引标记对应一段数据记录(默认索引粒度是8192)

大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引_大数据_05


稀疏索引占用空间小,所以primary.idx内的索引数据常驻内存,取用速度快。

生成规则

primary.idx文件,由于稀疏索引,所以MergeTree要间隔index_granularity行数据才会生成一个索引记录,其他索引值会根据声明的主键字段获取。

查询过程

索引是如何工作的?对primary.idx文件的查询过程

  • MarkRange: 一小段数据区间,按照 index_granularity的间隔粒度,将一段完整的数据划分成多个小的数据段,小的数据段就是MarkRange
  • MarkRange与索引编号对应

小案例:

  • 200行数据
  • index_granularity大小为5
  • 主键ID为int,取值从0开始

共200行数据/5 = 40个MarkRange

大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引_java_06


假设索引查询 where Id = 3

  • 第一步:形成区间格式 [3,3]
  • 第二步:进行交集 [3,3] ∩ [0, 199]
    以MarkRange的步长大于8分块,进行剪枝:
  • 第三步:合并, MarkRange(start0, end20)

在ClickHouse中,MergeTree引擎表的索引列在建表使用ORDER BY语法来指定。

而在官方中,用了下面一副图来说明。

大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引_大数据_07


这张图示出了以 CounterID、Date两列为索引列的情况,即先以CounterID为主要关键字排序,再以Date为次要关键字排序,最后用两列的组合作为索引键。Marks与MarkNumbers就是索引标记,且Marks之间的间隔就由建表时的索引粒度参数index_granularity来制定,默认是8192。在 ClickHouse 之父Alexey Milovidov分享的PPT中,有更加详细的图示:

大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引_sql_08

这样,每一列都通过ORDER BY列进行了索引,查询时,先查找到数据所在的parts,再通过mrk2文件确定bin文件中数据的范围即可。
不过,ClickHouse的稀疏索引与Kafka的稀疏索引不同,可以由用户自由组合多列,因此也要格外注意不要加入太多索引列,防止索引数据过于稀疏,增大存储和查找成本。另外,基数太小(即区分度太低)的列不适合做索引列,因为很有可能横跨多个mark值仍然相同,没有索引的意义了。

跳数索引

  • index_granularity 定义了数据的粒度
  • granularity定义了聚合信息汇总的粒度
  • granularity定义了一行跳数索引能够跳过多少个index_granularity区间的数据

可用类型

  • minmax存储指定表达式的极值(如果表达式是tuple,则存储tuple中每个元素的极值),这些信息用于跳过数据块,类似主键
  • set(max_rows)存储指定表达式的唯一值(不超过max_rows个,max_rows=0则表示无限制)。这些信息可以用于检查 WHERE 表达式是否满足某个数据块
  • ngrambf_v1 存储包含数据块中所有N元短语的布隆过滤器。只可用于字符串上,用于优化equals、like和in表达式的性能。
  • tokenbf_v1 跟 ngrambf_v1 类似,不同于ngrams 存储字符串指定长度的所有片段,它只存储被非字母数据字符分割的片段。


标签:idx,分区,跳数,primary,索引,137,txt,数据
From: https://blog.51cto.com/wuzikang/12110152

相关文章

  • 【Elasticsearch系列七】索引 crud
    ......
  • SQL Server的Descending Indexes降序索引
    SQLServer的DescendingIndexes降序索引 SQLServer的DescendingIndexes降序索引   背景索引是关系型数据库中优化查询性能的重要手段之一。对于需要处理大量数据的场景,合理的索引策略能够显著减少查询时间。特别是在涉及多字段排序的复杂查询中,选择合适的索引类型......
  • 向量数据库常见算法 | 七十九、向量数据库与索引算法
    索引算法则是向量数据库中的核心技术之一,它决定了数据库的检索效率和性能。本文将探讨向量数据库与索引算法的完美结合,以及它们在实际应用中的优势。1.向量数据库的优势高效检索:向量数据库采用高效的索引算法,如倒排索引、KD树、LSH等,可以快速地检索和查询向量数据。高维度支持:向量......
  • 笔记1 搜索引擎分类,搜索指令
    搜索引擎分类:目录式分类搜索引擎和全文式检索搜索引擎搜索引擎有Google、Baidu、Bing、搜狗、夸克等等......使用减号(-)指令,可以排除含有特定关键词的搜索结果,如搜索“原神-广告”,就能得到包含原神但不包含广告的结果filetype指令可以查询特定格式的文件:关键词+空格+filetype:+do......
  • Linux内核文件系统-虚拟文件系统-索引节点对象
    建议点击这里查看个人主页上的最新原文作者:陈孝松主页:chenxiaosong.com公网主页:replace_with_public_ip_or_delete_this_line哔哩哔哩:陈孝松课程:chenxiaosong.com/courses博客:chenxiaosong.com/blog贡献:chenxiaosong.com/contributions邮箱:chenxiaosong@ch......
  • 大数据-138 - ClickHouse 集群 表引擎详解3 - MergeTree 存储结构 数据标记 分区 索引
    点一下关注吧!!!非常感谢!!持续更新!!!目前已经更新到了:Hadoop(已更完)HDFS(已更完)MapReduce(已更完)Hive(已更完)Flume(已更完)Sqoop(已更完)Zookeeper(已更完)HBase(已更完)Redis(已更完)Kafka(已更完)Spark(已更完)Flink(已更完)ClickHouse(正在更新···)章节内容上节我们完成了如下的内容:MergeTree存储结构Me......
  • 后台操作出错:索引中丢失 IN 或 OUT 参数:: 22
    简单记录下:今天mybatis中遇到一个错误:org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [INSERT INTO law_enforce_user(user_code,name,sex,birthday) VALUES(?,?,?,?)]; SQL state [99999];......
  • 【字节跳动面试100题精讲】MySQL 索引文件写入磁盘的完整过程
    欢迎您的阅读,接下来我将为您一步步分析:MySQL索引文件写入磁盘的完整过程。让我们通过多个角度来深入探讨这个问题。MySQL索引文件写入磁盘的完整过程关键词:MySQL、索引、B+树、缓冲池、脏页、检查点、双写缓冲、文件系统缓存、磁盘I/O文章目录MySQL索引文件写入磁......
  • MySQL索引
    一.索引是什么MySQL索引是一种数据结构,用于加快数据库查询的速度和性能。大家可以自己试一下有索引和没索引的区别,两者的速度都不是在一个量级上。索引是极大的加快查询数据库的速度。当然,索引这么快也是有代价的,创建索引后会生成索引树,它是占磁盘空间的。磁盘IO是很耗时间......
  • 如何让带参数变量的mysql查询走索引?
    1,问题的提出mysql5.7的数据库,jx_performance表含索引idx_performance。该索引关联两个字段:`date`,`user_id`。在运行sql语句时发现,如果where条件采用参数变量,则查询不走索引。  图1,带参数变量查询  图2,采用字符串常数查询 上图1和图2,实际上查询条件一样,因为查询......