ClickHouse为什么这么快?ClickHouse原理解析与实践

本篇文章主要在架构&使用上介绍ClickHouse的基本概念&基本查询,抛砖引玉,大家实践的路上多多交流。

说在前头:OLAP的分类与OLAP操作

OLAP的架构分类

1.ROLAP:使用关系模型进行建模,数据建模通常使用星型模型或雪花模型。OLAP最初提出的时候就是建立在关系型数据库上,将多维度分析操作直接转换为SQL查询。

2.MOLAP:为了缓解ROLAP的性能问题,MOLAP使用多维数组的形式保存数据,其核心思想是借助预先聚合的结果,使用空间换时间的形式提升查询性能。依托数据立方体模型框定需要分析的维度字段。其缺点显而易见,维度的膨胀、数据的滞后、维度的固化、明细数据的丢失。

3.HOLAP:混合架构。

OLAP操作:

1.下钻 :从高层次的向底层次的明细数据穿透。例如:省维度的销售数据,下钻到市维度。

2.上卷:从低层次向高层次聚合。例如通常使用的group by操作。

3.切片:观察数据立方体的一层。例如订单数据三位立方体:时间,运力,地域;对单个运力维度如特价车进行固化,基于二维数据进行分析。

4.切块:多个切片。

5.旋转:主统计维度的切换,行列转换等

OLAP数据库的设计上也是主要为了高性能的进行以上操作。

ClickHouse架构

什么是ClickHouse? | ClickHouse Docs

ClickStream&WareHouse:基于数据流面向数仓进行OLAP分析。基于MPP架构,使用多主对等网络结构实现高可用,基于关系模型(ROLAP)的列式存储数据库。具有完成的DBMS、列式存储、不需要数据预处理、支持批量更新、拥有完整的SQL支持与函数、支出高可用、不依赖Hadoop生态、开箱即用;不支持事务、不擅长主键查询、不擅长按行删除数据。

1.核心特性:

1.列式存储与数据压缩:

压缩算法(LZ4 标准压缩比8:1)的本质是按照一定的步长进行数据匹配扫描,对重复部分进行转码如:abcdefghi_bcdefghi-->abcdefghi_(9,8)

提升查询性能的优化方式:1.减少数据的扫描范围 2.减少数据的传输大小 无意这两点列式存储具有基础设计上的优势。

2.向量化执行引擎

传统OLTP数据库通常以点查询为主,SQL的计算量很小, 实现这些技术的收益不够明显,但是在分析场景下单条SQL涉及的计算量可能极大,为每行作为一个基本单元进行数据处理可能带来严重的性能损耗:

  • 每行数据都要调用相应的函数,函数调用开销占比高
  • 存储层按列存储数据,在内存中按列组织数据,但是计算层按行计算无法充分利用cpu的cache预读能力,造成cpu cache miss严重
  • 按行处理无法高效利用simd

3.多样化表引擎

把存储引擎作为一层独立的接口:拥有合并树、内存、文件、接口和其他六大类20多种表引擎。

表引擎决定了一张数据表的最终“性格”

  • 数据拥有何种特性
  • 数据以何种形式被存储
  • 数据如何被加载

4.数据分区、分片and多线程与分布式

ClickHouse在数据存取方面,及支持分区partition(纵向扩展,利用多线程原理),也支持分片shard(水平拓展,利用分布式原理)。

向量化执行通过数据级并行的方式提升了性能,多线程则通过线程及并行提升性能。向量化基于底层硬件的能力,多线程由更高的软件层面控制发挥多核CPU的能力。

ClickHose并不像其他分布式系统那样拥有高度的自动化分片能力,ClickHouse提供了本地表(local table)& 分布式表(Distribute table)的概念,一张本地表等同于一份数据分片。而分布式表本身不存储任何数据,历史TDDL作为分库中间件提供访问代理的能力。

5.多主架构

master-slave 与multi-master

数据写入:

replicate-系列表引擎会在ZK中创建一系列监听节点,并以此实现多实例间的通行。在整个通信过程中zk并不涉及数据的传输。

2.合并树表引擎家族

合并树系列索引支持主键索引、数据分区、数据副本、数据采样这些特性。

1.mergeTree

MergeTree在写入一批数据时,数据总会以数据片段的形式写入磁盘,且数据片段不可修改。为了避免片段过多,ClickHouse会通过后台线程定期合并这些数据片段,属于相同分区的数据片段会被合成一个新的片段。这种数据片段往复合并的特点也正是合并树的名称由来。

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2],
    ...
    INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1,
    INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2
) ENGINE = MergeTree()
ORDER BY expr
[PARTITION BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[TTL expr [DELETE|TO DISK 'xxx'|TO VOLUME 'xxx'], ...]
[SETTINGS name=value, ...]

存储结构:

2.ReplacingMergeTree

MergeTree拥有主键,该主键没有唯一约束的语义。ReplacingMergeTree在一定程度上(在同一个分区内进行数据去重,不同分区的重复数据不会被剔除)解决了数据重复的问题,以order by 排序键作为去重依据,去重策略有两种1.依据ver版本,保留最大值2.保留重复数据的最后一行。

3.SummingMergeTree

终端用户只关心查询数据的汇总结果(列值SUM运算结果),不关心明细数据的,且数据大河汇总条件预先明确(group by条件明确,且不会随意改变)。

clickhouse的实践中,通常指定以order by(primary ke默认使用order by表达式);在summingMergerTree&AggregatingMergeTree场景会同时定义两个声明主要是为了满足:1.主键与聚合条件定义的分离。2.为修改聚合条件留下空间。

如:

primary key A

order by A,B, C, D

4.AggregatingMergeTree

SummingMergeTree的升级版,对每列定义aggregateFunction

实践1:

5.CollapsingMergeTree

支持修改的MergeTree

6.VersionedCollapsingMergeTree

CollapsingMergeTree基础上基于版本折叠

3.副本、数据分片shard&集群、数据分区(PARTITION)

副本

  1. 表级别的副本,而不是服务器级别的
  2. 多主架构
  3. Block数据块,insert命令写入数据时会依据max_insert_block_size的大小(default 1048576行)将数据切分成若干block,block是数据写入的基本单元既有原子性和唯一性(hash).

数据分片&数据分区

通过引入副本可以有效降低数据丢失的风险,并提升查询性能,但是有一个问题没有解决那就是数据表的容量问题。进一步数据水平切分即数据分片。ClickHouseshiyong Distributed表引擎作物分布式表的一层透明代理,在集群内部自动开展数据的写入、分发、查询、路由等工作。

数据分区-允许查询在指定了分区键的条件下,尽可能的少读取数据
数据分片-允许多台机器/节点同并行执行查询,实现了分布式并行计算

集群

4.数据查询

1.开源版本主键索引与跳数索引

以默认的索引粒度(8192)为例,MergeTree只需要12208行索引标记就能为1亿行数据记录索引。

3.关键点

  1. 线上SQL预计不要使用通用模板,基于if生成条件。
  2. 每个在线查询场景上线前检查执行计划是否满足预期。

5.其他概念

UPDATE in CK

这类操作被称为mutation查询,可以看做alter语句的变种,虽然update和delete操作最终实现了数据的修改和删除但是这是一个非常重的操作,不支持事务,distributed表引擎不支持。其实际执行过程是以分区目录为单位进行的分区重写操作。

吾辈今日苟有所见,而欲为行远之计,又可不早具坚车乎哉!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值