ClickHouse 诞生之处是为了服务Yandex自家的WEB流量分析产品Metrica,在超过20万亿数据的场景下,ClickHouse能做到90%查询在一秒内返回的效果,但是对于一款OLAP的数据库来说也有不适用的场景:

  • 不支持事务
  • 不擅长根据主键按行进行查询
  • 不擅长按行删除数据

为了获得极致的查询性能,OLAP数据库会相应放弃很多其他功能的弱化

ClickHouse是一款列式存储+数据压缩的数据库,数据压缩的本质就是对一定步长内的重复数据进行转换,案例:

压缩前:abcdefghi_bcdefghi
压缩后:abcdefghi_(9,8)

这个就表示压缩后下划线开始向前推移9个字节会有8个字节的数据重复

ClickHouse高性能的原因是由于结合了所有其他类型数据库的高性能特点,多线程分布式技术也是,使用了底层向量化SIMD技术+多线程技术结合,ClieckHouse没有采用主从架构,而是使用了多主架构,所有操作落在不同节点都可以完成操作

分区表

数据分区(partition)和数据分片(shard)是两种不同的概念,数据分区是针对本地表而言的,是一种数据的纵向切分,数据分片是一种横向切分,但是ClickHouse并不是所有存储引擎都支持分区,目前只有合并树系列的表引擎才支持数据分区

要查看一个表的分区状态,可以通过sysytem.parts系统表,查看分区状态:

select * from system.parts where table = 'xx'

但是也不是分区数量越多性能就越高,一般我们分区字段不要使用粒度太细的字段,如果按照小时分区,那么会导致分区数量太多,性能的下降

MergeTree原理

ClickHouse的表引擎决定了一张数据表的最终性格,在内部众多的表引擎中,合并树最为强大,MergeTree提供了主键索引、数据分区、数据副本和数据采样等基本能力,家族中其他的引擎在MergeTree上坐了不同的改进,ReplacingMergeTree引擎具有删除重复数据的能力,SummingMergeTree表引擎具有按照排序键自动聚合数据能力。

MergeTree在写入一段数据时,数据总会以数据片段的形式写入磁盘,且数据片段不可修改,为了避免片段过多,后台会有线程定期合并这些数据片段,属于相同分区的数据片段会被合并成一个新的数据片段,这个就是合并树的由来

数据分区的规则是按照分区ID决定的,而具体到每个数据分区的id则由分区键的取值确定的,前面我们通过SQL查询表的分区情况时会看到一串奇怪的数字,202204_1_3_0:

  • 202204 代表的partitionId
  • 1代表最小块num
  • 3代表最大块num
  • 0代表level,合并的层级,代表当前分区被合并的次数,或者理解为这个分区的年龄,数值越高年越大

  • MergeTree的分区目录是在数据写入过程中被创建的。也就是一张新建的表,如果没有任何数据,那么也不会有任何的分区存在。
  • MergeTree的分区目录伴随着每一批数据的写入(一次insert语句),mergetree都会生成一批新的分区目录,即便不同批次写入的数据属于相同分区,也会生成不同的分区目录。
  • 每次insert都会产生一个分区,那么就存在多个相同分区的情况,clickhouse会通过后台任务再将相同分区的多个目录合并成一个新的目录。已经存在的旧目录并不会立即被删除,而是在之后的某个时刻通过后台被删除。
  • 同属于一个分区的多个目录,在合并之后会形成一个全新的目录,目录中的索引和数据文件也会相应的进行合并。新目录名称的合并规则如下:
    • MinBlockNum: 取同一分区内所有目录中最小的MinBlockNum值。
    • MaxBlockNum: 取同一分区内所有目录中最大的MaxBlockNum值。
    • Level: 取同一分区内最大Level值并加1。

数据存储

​​​​​​​

数据TTL

在ClickHouse 中,TTL可以设置值的生命周期,它既可以为整张表设置,也可以为每个列字段单独设置。表级别的 TTL 还会指定数据在磁盘和卷上自动转移的逻辑。TTL 表达式的计算结果必须是 日期(date) 或 日期时间(datetime),如果同时设置了列级别的和表级别的TTL则以先到期的为准。

字段级别TTL

当列字段中的值过期时, ClickHouse会将它们替换成数据类型的默认值。如果分区内,某一列的所有值均已过期,ClickHouse会从文件系统中删除此列。ClickHouse的INTERVAL(数据时间间隔)支持的操作有:second(秒),minute(分钟),hour(小时),day(日),week(周),month(月),quarter(季度),year(年)。

-- 创建时指定 TTL
CREATE TABLE example_table
(
d DateTime,
a Int TTL d + INTERVAL 1 day,
b Int TTL d + INTERVAL 1 day,
c String
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(d)
ORDER BY d;
-- 为表中已存在的列字段添加 TTL
ALTER TABLE example_table
MODIFY COLUMN `c` String TTL d + toIntervalDay(1)
-- 修改列字段的 TTL
ALTER TABLE example_table
MODIFY COLUMN
c String TTL d + INTERVAL 1 WEEK;

表级别TTL

表可以设置一个用于移除过期行的表达式,以及多个用于在磁盘或卷上自动转移数据片段的表达式。当表中的行过期时,ClickHouse 会删除所有对应的行。

示例:event_date超过一个月的数据自动删除

-- 创建时指定 TTL
CREATE TABLE example_table
(
`event_date` Date,
`uid` Int32,
`name` String
)
ENGINE = AggregatingMergeTree()
PARTITION BY event_date
ORDER BY uid
TTL event_date + toIntervalMonth(1)
SETTINGS index_granularity = 128;
-- 修改表的 TTL,event_date超过三个月的数据自动删除
ALTER TABLE example_table
MODIFY TTL event_date + toIntervalMonth(3);

MergeTree之间的关系

可以看到,在具体的实现逻辑部分,7种MergeTree共用一个主体,在触发Merge动作时,调用了各自独有的合并逻辑。

而除开MergeTree之外的其他6个变种表引擎,它们的Merge合并逻辑,全部是建立在MergeTree基础之上的,如下图所示:

  • 组合关系

ReplicatedMergeTree与普通的MergeTree又有什么区别呢? 我们接着看下面这张图:

图中的虚线框部分是MergeTree的能力边界,而ReplicatedMergeTree在它的基础之上增加了分布式协同的能力。

借助ZooKeeper的消息日志广播,实现了副本实例之间的数据同步功能。

ReplicatedMergeTree系列可以用组合关系来理解,如下图所示:

  • 数据去重

ReplacingMergeTree通过ORDER BY,表示判断唯一约束的条件。当分区合并之时,根据ORDER BY排序后,相邻重复的数据会被排除。

由此,可以得出几点结论:

第一,使用ORDER BY作为特殊判断标识,而不是PRIMARY KEY。关于这一点网上有一些误传,但是如果理解了ORDER BYPRIMARY KEY的作用,以及合并逻辑之后,都能够推理出应该是由ORDER BY决定。

ORDER BY的作用, 负责分区内数据排序;

PRIMARY KEY的作用, 负责一级索引生成;

Merge的逻辑, 分区内数据排序后,找到相邻的数据,做特殊处理。

第二,只有在触发合并之后,才能触发特殊逻辑。以去重为例,在没有合并的时候,还是会出现重复数据。

第三,只对同一分区内的数据有效。以去重为例,只有属于相同分区的数据才能去重,跨越不同分区的重复数据不能去重。

  • 预聚合(数据立方体)

​​​​​​​有这么一类场景,它的查询主题是非常明确的,也就是说聚合查询的维度字段是固定,并且没有明细数据的查询需求,这类场合就可以使用SummingMergeTree或是AggregatingMergeTree,如下图所示:

可以看到,在新分区合并后,在同一分区内,ORDER BY条件相同的数据会进行合并。如此一来,首先表内的数据行实现了有效的减少,其次度量值被预先聚合,进一步减少了后续计算开销。

ClickHouse 深度解析第二篇相关推荐

  1. OpenSea合约深度解析——atomicMatch_ 篇

    很多朋友在Opensea上购买NFT时,会发现自己的钱包正在调用一个名为Atomic Match_的方法,正好这段时间做的项目需要和Opensea交互,研究了一下Opensea的合约,今天就从 ato ...

  2. C++基础与深度解析第二章:对象与基本类型

  3. 【转载】本文,是《Feign Ribbon Hystrix 三者关系 , 史上最全 深度解析》篇,为大家解读如果Feign Ribbon Hystrix 三者关系,大家可以藏好,一定有用的到时候。

    本文转自:https://www.cnblogs.com/crazymakercircle/p/11664812.html https://www.cnblogs.com/crazymakercirc ...

  4. IT创业失败案例解析 - 第二篇

    前段时间我们关闭了Overto公司,这是一家我参与的创业公司.从公司停业便不难看出这是一次失败的创业经历. 因为我们从失败中学到了很多,我认为对创业失败做一个可靠性分析对您应该有用.希望大家不要重蹈我 ...

  5. 视频教程:Java常见面试题目深度解析!

    视频教程:Java常见面试题目深度解析! Java作为目前比较火的计算机语言之一,连续几年蝉联最受程序员欢迎的计算机语言榜首,因此每年新入职Java程序员也数不胜数.很多java程序员在学成之后,会面 ...

  6. [深蓝学院]c++基础与深度解析

    c++基础与深度解析 第二章 对象与基本类型 从初始值/赋值语句说起.类型讲起

  7. 一篇看懂CVPR 2017五大研究前沿 | 腾讯AI Lab深度解析

    感谢阅读腾讯AI Lab微信号第二篇文章,我们将深度解析本届CVPR热门研究.第一部分是五大前沿领域的重点文章解析,包括低中层视觉.图像描述生成.3D视觉.计算机视觉与机器学习.弱监督下的图像识别等. ...

  8. clickhouse原理解析与应用实践_Hybrid App (混合应用) 技术全解析 方案原理篇

    引言 随着 Web 技术和移动设备的快速发展,Hybrid 技术已经成为一种最主流最常见的方案.一套好的 Hybrid架构方案 能让 App 既能拥有极致的体验和性能,同时也能拥有 Web技术 灵活的 ...

  9. 深度学习经典网络解析图像分类篇(二):AlexNet

    深度学习经典网络解析图像分类篇(二):AlexNet 1.背景介绍 2.ImageNet 3.AlexNet 3.1AlexNet简介 3.2AlexNet网络架构 3.2.1第一层(CONV1) 3 ...

  10. 深度解析Istio系列之策略与遥测篇

    注:以下讲述的案例环境场景是基于Kubernetes环境基础上部署的istio环境. 涉及到的Pilot和Envoy的了解请参考深度解析Istio系列之流量控制篇,本文重点在于介绍Mixer. Mix ...

最新文章

  1. GAN--提升GAN训练的技巧汇总
  2. jQuery scroll事件
  3. python 中的爬虫· scrapy框架 重要的组件的介绍
  4. 怎么修改ppt的虚线间隔_还有一小时下班,领导交给我一份ppt,做不完不许走!...
  5. Java并发编程(06):Lock机制下API用法详解
  6. 数据结构与算法分析-用C语言实现栈(数组方式)
  7. 关于语言选择、输入和产出的关系
  8. 何恺明“终结”ImageNet预训练时代:从0开始训练神经网络,效果比肩COCO冠军
  9. 新版 IDEA 发布,牛逼!网友:内存占用有所好转!
  10. 小说Symbian的签名
  11. 计算机兴趣小组活动教学教案,计算机兴趣小组计划教案.doc
  12. 生成对抗网络GANs的用途
  13. 使用HbuilerX运行微信小程序到微信小程序模拟器
  14. iPhone 如何将图片转换为文字
  15. 路由器RIP简单配置和讲解
  16. IM开发干货分享:网易云信IM客户端的聊天消息全文检索技术实践
  17. 根据RGB​值判断颜色是否深浅色(附深浅色颜色集合)
  18. 查看路由器拨号的宽带密码
  19. 使用了 23 的 Java 真的收费了吗?
  20. C语言———字符与字符串

热门文章

  1. 心灵捕手~ 鸡汤悄悄话
  2. XSS靶场练习 https://xss.haozi.me
  3. CC2652RB1F开发板烧录ZNP的固件
  4. 火车头采集器用法说明
  5. 来自《星际迷航》的灵感启发
  6. python列表元素按条件分组_python-按值分组列表
  7. R语言-豆瓣电影top250数据爬取和分析
  8. ps盖印图层在哪里_盖印图层在哪
  9. 高登复习笔记之Http网络协议和Servlet
  10. macOS Big Sur 11.6.5 (20G527) 正式版 ISO、PKG、DMG、IPSW 下载