首页  

clickhouse核心知识点     所属分类 clickhouse 浏览量 415
OLAP
大宽表,读大量行但是少量列,结果集较小
数据批量写入,且数据不更新或少更新
无需事务,数据一致性要求低

列式存储 有序存储、主键索引、稀疏索引、数据Sharding、数据Partitioning、TTL、主备复制


数据按照某些列有序存储
主键索引,将每列数据按照index granularity(默认8192行)进行划分,每个index granularity的开头第一行被称为一个mark行。
主键索引存储该mark行对应的primary key的值。

where条件中含有primary key的查询,通过对主键索引进行二分查找,
能够直接定位到对应的index granularity,避免了全表扫描从而加速查询

主键索引与MySQL等不同,没有唯一性

要实现去重效果,可使用表引擎 ReplacingMergeTree、CollapsingMergeTree、VersionedCollapsingMergeTree

sharding策略
random随机分片 
constant固定分片 
column value分片 按照某一列的值进行hash分片
自定义表达式分片


数据Partitioning
PARTITION BY子句 
toYYYYMM()将数据按月进行分区
toMonday()将数据按照周几进行分区
对Enum类型的列直接每种取值作为一个分区


数据Partition 作用

在partition key上进行分区裁剪,只查询必要的数据
灵活的partition expression设置,使得可以根据SQL Pattern进行分区设置,最大化的贴合业务特点

对partition进行TTL管理,淘汰过期的分区数据

:
TTL提供数据生命周期管理

列级别TTL
当一列中的部分数据过期后,会被替换成默认值 ,当全列数据都过期后,会删除该列
行级别TTL 当某一行过期后,直接删除该行
分区级别TTL  当分区过期后,直接删除该分区


高吞吐写入能力
采用类LSM Tree的结构,数据写入后定期在后台Compaction

官方公开benchmark测试显示能够达到50MB-200MB/s的写入吞吐能力
按照每行100Byte估算,大约相当于50W-200W条/s的写入速度

有限支持delete update
在分析场景中,删除、更新操作并不是核心需求
ClickHouse没有直接支持delete、update操作,而是变相支持了mutation操作,
语法为alter table delete where filter_expr,alter table update col=val where filter_expr

目前主要限制为删除、更新操作为异步操作,需要后台compation之后才能生效


主备同步

默认配置下,任何副本都处于active模式,可以对外提供查询服务
可以任意配置副本个数,副本数量可以从0个到任意多个
不同shard可以配置不提供副本个数,用于解决单个shard的查询热点问题


计算层
单机多核并行、分布式计算、向量化执行与SIMD指令、代码生成

将数据划分为多个partition,每个partition再进一步划分为多个index granularity,
通过多个CPU核心分别处理其中的一部分来实现并行数据处理
单条Query就能利用整机所有CPU

多种query下发策略
随机下发 在多个replica中随机选择一个

最近hostname原则
选择与当前下发机器最相近的hostname节点,进行query下发
在特定的网络拓扑下,可以降低网络延时。而且能够确保query下发到固定的replica机器,充分利用系统cache。

in order
按照特定顺序逐个尝试下发,当前一个replica不可用时,顺延到下一个replica

first or random
在In Order模式下,当第一个replica不可用时,所有workload都会积压到第二个Replica,导致负载不均衡。
first or random解决了这个问题
当第一个replica不可用时,随机选择一个其他replica,从而保证其余replica间负载均衡
另外在跨region复制场景下,通过设置第一个replica为本region内的副本,可以显著降低网络延时


按列存储,按列进行计算

向量执行引擎(Vectorized execution engine)
对内存中的列式数据,一个batch调用一次SIMD指令(而非每一行调用一次),
不仅减少了函数调用次数、降低了cache miss,而且可以充分发挥SIMD指令的并行能力,大幅缩短了计算耗时

动态代码生成Runtime Codegen


在经典的数据库实现中,通常对表达式计算采用火山模型,将查询转换成一个个operator,
比如HashJoin、Scan、IndexScan、Aggregation等
为了连接不同算子,operator之间采用统一的接口,比如open/next/close
在每个算子内部都实现了父类的这些虚函数,在分析场景中单条SQL要处理数据通常高达数亿行,虚函数的调用开销不再可以忽略不计。
另外,在每个算子内部都要考虑多种变量,比如列类型、列的size、列的个数等,存在着大量的if-else分支判断导致CPU分支预测失效。

ClickHouse实现了Expression级别的runtime codegen,动态地根据当前SQL直接生成代码,然后编译执行。
对于Expression直接生成代码,不仅消除了大量的虚函数调用(即图中多个function pointer的调用),
而且由于在运行时表达式的参数类型、个数等都是已知的,也消除了不必要的if-else分支判断。

近似计算
损失一定结果精度为代价,极大地提升查询性能

近似估算distinct values、中位数,分位数等多种聚合函数;
建表DDL支持SAMPLE BY子句,支持对于数据进行抽样处理

复杂数据类型支持
提供 array、json、tuple、set等复合数据类型,支持业务schema的灵活变更

上一篇     下一篇
clickhouse ReplacingMergeTree

clickhouse MergeTree 写入与查询

clickhouse MergeTree 存储结构

OLAP和OLTP的本质区别

Clickhouse基本使用

花半开 酒微醺 凡事留余地