ClickHouse MergeTree引擎:从核心架构到三级索引实战

摘要

        MergeTree是ClickHouse最核心的存储引擎,采用列式存储+LSM-Tree架构设计,支持高效的数据写入、合并和查询。本文将全面解析MergeTree引擎的基础概念、数据流、核心架构、索引系统以及常见问题。

基础篇:

一、MergeTree引擎基础概念

1. 定义

MergeTree是ClickHouse中最高性能的存储引擎,专为大规模数据分析场景设计,具有以下核心特性:

特性分类

详细说明

技术价值

列式存储结构

数据按列而非按行存储,每列独立压缩

提升压缩率5-10倍,减少I/O消耗70%+

主键索引

稀疏索引设计(默认8192行粒度),支持ORDER BY键快速定位

使范围查询效率提升100倍+

自动数据分区

按PARTITION BY表达式自动划分数据目录

实现分区裁剪,减少90%+无关数据扫描

后台合并机制

异步合并小Parts为优化后的大Part(LSM-Tree架构)

写入吞吐量可达50MB/s,查询性能提升300%

衍生引擎变种

包括Replacing/Summing/Aggregating等7种变体

覆盖去重、预聚合等专项场景需求

2. 引擎家族图谱

引擎类型

主要变种

核心特性

基础变种

ReplacingMergeTree

支持数据去重

基础变种

SummingMergeTree

预聚合计算

基础变种

AggregatingMergeTree

高级聚合功能

分布式变种

ReplicatedMergeTree

支持数据副本

分布式变种

Distributed

分片集群支持

二、核心架构与数据流

1. 存储架构分层图‌

关键说明‌:

  • 分区(Partition)是数据物理隔离的最小单位,按分区键自动裁剪
  • 每个Part包含列文件、标记文件和主键索引三要素
  • 跳数索引通过minmax/set等算法加速查询

2. 数据写入时序图‌

关键说明‌:

  • 采用两阶段提交保证分布式一致性
  • 临时Part经后台合并转为正式Part
  • 元数据变更通过ZooKeeper同步

3. 后台合并流程时序图‌

关键说明‌:

  • 合并策略基于Part大小/数量自动触发
  • 合并过程产生新Part并原子替换旧Part
  • 后台线程默认10分钟执行一次

4. 数据查询时序图‌

关键说明‌:

  • 查询采用MPP并行处理模式
  • 跳数索引实现"预过滤"优化
  • 列存储实现按需读取

三、索引解析:三级索引协同工作原理‌

1. 三级索引体系架构图‌

‌2. 索引功能对照表‌

索引类型

物理结构

触发条件

优化效果

项目案例

一级索引

内存中的稀疏索引

WHERE涉及PRIMARY KEY

减少99%数据扫描

用户画像查询从12s→0.3s

分区索引

分区目录元数据

WHERE涉及PARTITION BY列

大表查询速度提升8-10倍

日志分析按day分区后QPS提升430%

跳数索引

Granule级元数据

WHERE涉及普通列

减少I/O 30-70%(取决于索引类型)‌

商品搜索使用布隆过滤器降低60%IO

‌3. 协同工作深度解析‌

阶段一:分区裁剪(Partition Pruning)

# 分区表达式示例
partition_expr = "toYYYYMMDD(event_time)"
# 查询优化器自动转换为分区范围
WHERE event_time > '2023-01-01' 
→ 转换为分区ID范围:20230101 ≤ partition_id ≤ 20231231

阶段二:主键定位(Primary Key Lookup)

// ClickHouse内核处理流程
1.WHERE user_id=123转为Mark Range(区间标记)
2. 通过稀疏索引定位到Granule(数据块) 42(假设每8192行一个Mark)
3. 仅加载对应Granule的列文件(.bin)

阶段三:跳数索引过滤(Skipping Index Filter)

索引类型

适用场景

项目配置

性能收益

minmax(极值索引)

数值范围查询

INDEX idx_price TYPE minmax GRANULARITY 3

减少45%读取量

bloom_filter布隆过滤器)

IN/等值查询

INDEX idx_sku TYPE bloom_filter(0.025)

降低60%CPU开销

实战篇:

‌四数据更新与删除策略深度解析

1. 核心设计理念

        ClickHouse采用LSM-Tree架构,其数据变更处理遵循"追加写入+后台合并"原则。与传统OLTP数据库不同,ClickHouse原生设计更侧重高性能分析而非高频单行变更,这导致其UPDATE/DELETE实现具有显著特殊性。

2. 实现原理

变更类型

实现方案

核心机制

适用场景

删除

状态标记法

增加_is_deleted字段(0/1)

需要保留历史记录的删除

墓碑标记法

增加_sign字段(1/-1)

VersionedCollapsing场景

轻量级删除

22.8+版本ALTER TABLE DELETE语法

物理删除需求

更新

版本覆盖法

ReplacingMergeTree+_version字段

通用更新场景

聚合更新法

AggregatingMergeTree+状态函数

指标类数据更新

增量合并法

CollapsingMergeTree+_sign字段

状态变更类更新

3. 技术实现方案案例

场景‌:电商商品数据实时新增/更新

实时管道最佳实践:

mysql binlog  Kafka → Flink实时ETL → ODS → DWD层物化视图)

        物化视图通过预计算和自动更新机制,显著提升大数据分析查询性能,博客《ClickHouse物化视图避坑指南:原理、数据迁移与优化》

clickhouse中的脚本如下:

-- 1. 基础存储层(全量快照)
CREATE TABLE ods.products_snapshot
(product_id UInt64,product_name String,price Decimal(18,2),category_id UInt32,update_time DateTime,_version UInt64 MATERIALIZED toUnixTimestamp(update_time)
)
ENGINE = MergeTree()
ORDER BY (product_id);-- 2. DWD层(版本化视图)
CREATE MATERIALIZED VIEW dwd.products
ENGINE = ReplicatedReplacingMergeTree('/clickhouse/tables/{shard}/dwd_products', '{replica}', _version)
ORDER BY product_id
AS SELECTproduct_id,argMax(product_name, update_time) as product_name,argMax(price, update_time) as price,argMax(category_id, update_time) as category_id,max(update_time) as update_time,max(_version) as _version
FROM ods.products_snapshot
GROUP BY product_id;-- 3. 基础查询(获取最新商品版本)
SELECT product_id,product_name,price,category_id
FROM dwd.products FINAL
WHERE product_id = 123;

核心技术函数说明表

函数类别

关键函数

功能说明

状态函数

argMax/argMin

保留指定字段最新/最旧值

版本控制

toUnixTimestamp(now())

生成版本号

特殊引擎

ReplacingMergeTree

按版本自动去重

五、常见问题

1. 架构设计常见问题

  • 如何选择排序键?推荐采用(ad_id, event_time)等双字段组合键
    • 优先选择低基数且高频过滤的字段
    • 避免过度使用Nullable类型‌
  • 物化视图如何优化?
    • 配合物化视图可实现毫秒级分析‌
    • 建议按业务场景设计专用物化视图

2. 性能优化问题

  • 分区策略优化:
    • 设置分区TTL可自动清理旧数据
    • 控制分区粒度在1-10GB/分区
  • 索引优化:
    • 跳数索引可使查询性能提升
    • 合理设置max_parts_in_total参数‌

3. 工程实践问题

  • 数据分层设计:
    • 通过DWD/DWS分层可降低查询复杂度
    • 建议基于原始底表构建轻聚合明细层(DWD)与指标服务层(DWS)
  • 高并发支撑:
    • 分布式物化视图集群可支撑5000+ QPS高并发查询‌
    • 需考虑查询路由和负载均衡策略

六、总结

        MergeTree引擎通过分层架构实现高性能分析:存储层(列文件+分区)保障数据压缩与局部性,计算层(稀疏索引+跳数索引)实现查询加速,管理层(ZooKeeper协调)确保分布式一致性。这种"写入即合并"的LSM-Tree设计,配合物化视图等衍生能力,使其在OLAP场景实现吞吐量与查询效率的完美平衡。

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

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

相关文章

电脑手机热点方式通信(上)

电脑连接手机热点时的无线链路情况: 电脑上网时(从服务器下载数据,或者上传指令、数据),首先电脑与手机之间基于WiFi协议在2.4G频段或者5G频段通信,然后手机与基站之间再基于4G LTE或者5G NR协议在2412MHz…

MySQL CPU占用过高排查指南

MySQL CPU 占用过高时,排查具体占用资源的表需结合系统监控、数据库分析工具和 SQL 诊断命令。🔍 ​一、快速定位问题根源​​确认 MySQL 进程占用 CPU​使用 top 或 htop 命令查看系统进程,确认是否为 mysqld 进程导致 CPU 飙升。若 MySQL 进…

软件交付终极闸口:验收测试全解析

验收测试:软件交付的关键环节 目录 验收测试:软件交付的关键环节 一、验收测试:软件交付的终极闸口 核心目标与作用 在 SDLC 中的位置 二、验收测试类型详解:精准匹配业务场景 三、验收测试全流程解析:从计划到…

深度学习核心:卷积神经网络 - 原理、实现及在医学影像领域的应用

🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C, C#,Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C、C#等开发语言,熟悉Java常用开发…

多线程(二) ~ 线程核心属性与状态

文章目录一. 线程创建(start)(一)继承Thread类,重写run(二)继承Runnable类,重写run(三)Thread匿名内部类重写(四)Runnable匿名内部类重…

Linux---编辑器vim

一、vim的基本概念1.三种模式①命令模式控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入插入模式或者进去底行模式②插入模式可进行文本输入,按Esc回到命令行模式③底行模式文件保存或退出,也可以进行文件替换&#…

如何在 Ubuntu 24.04 或 22.04 LTS Linux 上安装 Guake 终端应用程序

通过本教程的简单步骤,在 Ubuntu 24.04 或 22.04 LTS Jammy JellyFish 上安装 Guake 终端以运行命令。 Guake(基于 Quake)是一个基于 Python 的终端模拟器。Guake 的行为类似于 Quake 中的终端:通过某个按键(热键)按下时,窗口会从屏幕顶部滚下来,再次按下相同的按键时…

谷歌Gemini 2.5重磅应用:多模态研究助手Multi-Modal Researcher,实现全网自动研究与AI播客生成

在人工智能赋能科研与内容创作的浪潮中,谷歌基于其最新大模型 Gemini 2.5 推出了突破性工具 Multi-Modal Researcher。这一系统通过整合多模态数据(文本、视频、实时网络信息),实现了从自动研究到内容生成的全流程自动化。用户只需输入研究主题或YouTube视频链接,系统即可…

防御综合实验

一、实验拓补图二、实验需求及配置需求一设备接口VLAN接口类型SW2GE0/0/2VLAN 10AccessGE0/0/3VLAN 20AccessGE0/0/1VLAN List : 10 20Trunk[SW2]vlan 10 [SW2]vlan 20 [SW2]interface GigabitEthernet 0/0/2 [SW2-GigabitEthernet0/0/2]port link-type access [SW2-GigabitEt…

堆----2.前 K 个高频元素

347. 前 K 个高频元素 - 力扣(LeetCode) /** 桶排序: 首先遍历数组,使用HashMap统计每个元素出现的次数 创建一个大小为length 1的List数组,下标代表元素出现次数,出现次数一致的元素放在同一个数组中 倒数遍历List数组即可得得到前K个高频元素 细节注…

如何分析Linux内存性能问题

一、Linux中的buffer与cache的区别 Linux的内存管理与监控_linux服务器虚假内存和真实内存怎么区分-CSDN博客文章浏览阅读66次。本文主要是关于【Linux系统的物理内存与虚拟内存讲解】【重点对虚拟内存的作用与用法进行了讲解说明】【最后还对如何新增扩展、优化、删除内存交换…

二次型 线性代数

知识结构总览首先是我们的二次型的定义,就是说什么样的才算是一个二次型。然后就是如何把二次型化为标准型,最后就是正定二次型的定义和判断的一些条件。二次型的定义二次型其实是一种函数表达的方式,如上,含义其实就是每个项都是…

云原生三剑客:Kubernetes + Docker + Spring Cloud 实战指南与深度整合

在当今微服务架构主导的时代,容器化、编排与服务治理已成为构建弹性、可扩展应用的核心支柱。本文将深入探讨如何将 Docker(容器化基石)、Kubernetes(编排引擎)与 Spring Cloud(微服务框架) 无缝…

vue让elementUI和elementPlus标签内属性支持rem单位

vue让elementUI和elementPlus标签内属性支持rem单位 如 Element Plus 的 el-table 默认不直接支持使用 rem 作为列宽单位 解决方法: 将 rem 转换为像素值(基于根元素字体大小) // 计算rem对应的像素值 const calcRem (remValue) > {// 获取根元素(ht…

基于OAuth2与JWT的微服务API安全实战经验分享

引言 在微服务架构中,API 安全成为了保护服务免受未授权访问和攻击的关键要素。本文结合真实生产环境案例,以实战经验为出发点,分享基于 OAuth2 JWT 的微服务 API 安全方案,从业务场景、技术选型、实现细节、踩坑及解决方案&…

scrapy库进阶一

scrapy 库复习 scrapy的概念:Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架 scrapy框架的运行流程以及数据传递过程: 爬虫中起始的url构造成request对象–>爬虫中间件–>引擎–>调度器调度器把request–>引擎…

Objective-C实现iOS平台微信步数修改指南

本文还有配套的精品资源,点击获取 简介:本文介绍如何在iOS平台上使用Objective-C语言,通过苹果的HealthKit框架读取和修改微信步数以及相关健康数据。首先介绍如何引入和使用HealthKit框架,包括请求权限、读取步数数据、写入步…

【ElementPlus】深入探索ElementPlus:前端界面的全能组件库

📚 引言在现代 Web 开发中,创建既美观又功能强大的用户界面是一项挑战。Element Plus,作为 Vue 3 生态中的明星 UI 组件库,以其丰富的组件、优秀的性能和易用性赢得了广大开发者的青睐。本文将全面覆盖 Element Plus 的 常用核心组…

Json Jsoncpp

文章目录Json 介绍Jsoncpp 介绍Json::Value序列化接口反序列化接口序列化操作反序列化操作Json 介绍 JSON(JavaScript Object Notation,JavaScript 对象表示法)是一种轻量级的数据交换格式,具有简洁、易读、跨平台等特点&#xff…

openwrt下安装istore(基于pve)

openwrt下安装istore(基于pve)ssh连接到openwrt,用如下命令安装istore:opkg update || exit 1cd /tmpwget https://github.com/linkease/openwrt-app-actions/raw/main/applications/luci-app-systools/root/usr/share/systools/i…