IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> ClickHouse 深度解析第二篇 -> 正文阅读

[大数据]ClickHouse 深度解析第二篇

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条件相同的数据会进行合并。如此一来,首先表内的数据行实现了有效的减少,其次度量值被预先聚合,进一步减少了后续计算开销。?

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:49:30  更:2022-04-18 17:52:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:48:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码