ClickHouse| 青训营笔记(二)

64 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天。

📜📜📜今天学习的是ClickHouse——第二部分。昨天我们了解了clickhouse使用了列式存储。接下来我们继续学习clickhouse的存储设计

三、clickhouse存储设计

3.1 表定义和结构

  • 分布式表:不存储数据,用于将查询路由到集群的各个节点
  • cluster:逻辑集群,由多个节点组成
  • shard_key:指导数据写入分布式表时的分布方式
  • 本地表:实际存储数据的表
create table t_name [on cluster cluster]——这里是选择集群,将表格建在该集群上。
{
    name1 [type] [default|]materialized|alias expr1] [ttl expr1],
    ……
    index index_name1 expr1 type type1(...) granularity value1,——这里是建立索引
    ……
}engine = MergeTree()——引擎选择
order by expr——按照什么排序
[partition by expr]——数据如何在单节点分布
[primary key expr]
[sample by expr]
[ttl expr [delete |to disk 'xxx'|to volume 'xxx'], ...]
……

3.2 集群架构

image.png

3.3 引擎架构

image.png

3.4 存储架构

image.png 表名下面还有很多目录,每一个目录名字叫part,part下面还有很多目录或者是文件,我们在表里定义的每一个字段,都是单独存储成一个数据文件。例如:

image.png

下面是文件组织:

image.png

不同的partition是不会写到同一个文件夹里面的

part和partition:

  • part是物理文件夹的名字
  • partition是逻辑结构

image.png

3.5 索引设计

hash index:其实就是通过一个hashfunction映射到buckets表里面去(buckets表里面存的是每个key所在文件的地址) image.png 只能等值比较,不适合聚合的大范围的查询。

  • B tree

image.png

image.png

  • B+ tree

image.png 注意:数据都存在叶子节点,叶子节点是双向列表

image.png

image.png

log-structured merge-tree (LSM tree)是一种为大吞吐写入场景而设计的数据结构

  • 着重优化顺序写入
  • 主要数据结构
  1. SSTables 2.Memtable

image.png

image.png

image.png

3.6 索引实现

主键查询

image.png

数据按照主键顺序依次做排序

  • 首先按照UserlD做排序
  • 再按照URL排序
  • 最后是EventTime

image.png 数据被划分为granules(力度)

  1. granules是最小的数据读取单元 2.不同的granulas可以并行读取 (每个granules都对应primary.idx里面的一行)

image.png

默认每8192行记录主键的一行值,primary.idx需要被全部加载到内存里面

image.png

每个列都有这样一个mark文件

  1. mark文件保存的是每个granules的物理地址
  2. 每—列都有一个自己的mark文件

mark文件里面的每一行保存两个地址:

  1. block_offset:用于定位一个granule的压缩数据在物理文件中的位置,压缩数据会以一个block为单位解压到内存中。
  2. granule_offset,用于定位一个granule在解压之后的block中的位置。

缺陷:数据按照key的顺序做排序,因此只有第一个key的过滤效果好,后面的key过滤效果依赖第一个key的基数大小

3.7 查询优化

secondary index(二级索引):在URL列上构建二级索引。

构建多个主键索引 – 再建一个表,使用需要优化的字段做主键第一位

  • 建一个物化视图
  • 使用Projection

3.8 数据合并

将多个part合并成一个。 数据的可见性:

  1. 数据合并过程中,未被合并的数据对查询可见
  2. 数据合并完成后,新part可见,被合并的part被标记删除

image.png

四、clickhouse典型应用场景

大宽表存储和查询: 1.大宽表查询

  • 可以建非常多的列
  • 可以增加,删除,清空每一列的数据
  • 查询的时候引擎可以快速选择需要的列
  • 可以将列涉及到的过滤条件下推到存储层从而加速查询

大宽表存储和查询:2动态表结构

  • map中的每个key都是一列
  • map中的每一列都可以单独的查询
  • 使用方式同普通列,可以做任何计算

离线数据分析 1.数据导入

  • 数据可以通过spark生成clickhouse格式的文件
  • 导入到hdfs上由 hive2ch导入工具完成数据导入
  • 数据直接导入到各个物理节点

2.数据按列导入

  • 保证查询可以及时访问已有数据
  • 可以按需加载需要的列

实时数据分析 使用memory table减少parts数量

  1. 数据先缓存在内存中
  2. 到达一定阈值再写到磁盘