概述OLAP场景与列式数据库特征,以及Clickhouse这数据库的各个特性(各个特性的组合实现了clickhouse的高性能)

Clickhouse 详解

一、概述

ClickHouse® is a column-oriented database management system (DBMS) for online analytical processing of queries (OLAP).

根据官方文档说法,它是列式数据库,应用于OLAP场景。

OLAP

OLAP(OnLine Analysis Processing ,联机分析处理 ),是数据仓库系统的主要应用,从多维度,多层次的角度,针对特定问题进行数据的汇总分析。

特征

OLAP场景的关键特征

  • 绝大多数是读请求
  • 数据以相当大的批次(> 1000行)更新,而不是单行更新;或者根本没有更新。
  • 已添加到数据库的数据不能修改。
  • 对于读取,从数据库中提取相当多的行,但只提取列的一小部分。
  • 宽表,即每个表包含着大量的列
  • 查询相对较少(通常每台服务器每秒查询数百次或更少)
  • 对于简单查询,允许延迟大约50毫秒
  • 列中的数据相对较小:数字和短字符串(例如,每个URL 60个字节)
  • 处理单个查询时需要高吞吐量(每台服务器每秒可达数十亿行)
  • 事务不是必须的
  • 对数据一致性要求低
  • 每个查询有一个大表。除了他以外,其他的都很小。
  • 查询结果明显小于源数据。换句话说,数据经过过滤或聚合,因此结果适合于单个服务器的RAM中

列式数据库

传统关系数据库的数据一般在按行存储,即一行数据在物理存储上位置是连续的,而列式数据库则是按列存储。值得注意的是,这里列式或者行式只是指数据库的存储模型(storage model),并不影响上层的数据模型(data model),列式存储的数据库可能是SQL数据库或者NOSQL数据库。

特征与优点:

  • 数据库按列存储
  • 数据即是索引
  • 只访问查询涉及的列 - 大量降低系统IO
  • 每列可单独线程处理 - 通过并发提高查询速度
  • 数据类型一致,数据特征相似 - 高效压缩

优点:

  • 更快的IO:对指定列查询统计分析时,因为只涉及指定列,不像行式会查询到其他列数据,减少IO,并且一定程度上随机读取变成顺序读取
  • 更低的存储(成本更低):同一列数据更好压缩(比如字典表压缩)
  • 更低的内存和CPU:查询涉及的数据量低时(无论是因为只读了相关列或者是列的压缩),占用计算内存更少。

缺点:

  • 组装消耗:select完成后需要组装各个列数据
  • 插入更新更麻烦:比如一次插入,需要对多列操作,比如不同列在不同page,需要进行多次IO(行式可能只需一次)

Clickhouse Features(官方文档说法)

  • 列式存储:In a real column-oriented DBMS, no extra data is stored with the values. 即数据不会有额外数据(比如记录数据长度)

  • 数据压缩:除了高效通用压缩codec(编解码器)之外,clickhouse还对特定类型的数据提供专门的codec

  • 磁盘存储:因为数据在物理存储上就是按主键排序了的,可以以低延迟(不到几十毫秒)提取特定值或者范围数据。Clickhouse设计是用于常规硬盘,成本更低,但如果允许,SSD或者更多RAM可以进一步提高性能

  • 多核并行处理:Clickhouse实际应用是可以跑满CPU内存资源的。

  • 多服务器上的分布式查询:数据多分片存储,各分片也可以有多个副本

  • SQL支持:大部分情况满足ANSI SQL标准

  • 向量计算引擎(可见参考描述):

    • SIMD即single instruction, multiple data"(单指令流多数据流),本质上是采用一个控制器来控制多个处理器,同时对一组数据中的每一条分别执行相同的操作,从而实现空间上的并行性的技术。
    • CPU通过SSE指令集实现SIMD
    • clickhouse充分应用SSE指令集:filter(批量处理128位)或者大小写转换(一次加载16个字段转换)
  • 实时数据更新:支持主键表,为了快速执行基于主键的范围查询,Clickhouse会使用合并树对数据进行增量排序,数据可以实时不断添加。(不过要特别注意clickhouse对于各个数据part的合并,合并的时机不定,实际业务也要有意识控制part大小)

  • 主键索引:查询主键的特定值或者特定范围的延迟非常低(不到几十毫秒),顺序读写

  • 二级索引:与其他数据库不同,clickhouse的二级索引不指向特定行或者行范围。相反,它们让数据库提前知道某些数据部分中的所有行都不会匹配查询过滤条件并且根本不读取它们,因此它们被称为 data skipping indexes.。比如:记录这个data part的年龄最小值是30岁,那么查询30岁以下数据时,就直接跳过整个data part,加快查询。

  • 支持在线查询:简而言之,就是查询太快了,所以允许在线实时查询,不需要像其他OLAP场景下跑离线任务。

  • 支持近似值的计算:ClickHouse提供各种各样在允许牺牲数据精度的情况下对查询进行加速的方法:

    • 用于近似计算的各类聚合函数,如:distinct values, medians, quantiles

    • 基于数据的部分样本进行近似查询。这时,仅会从磁盘检索少部分比例的数据。

    • 不使用全部的聚合条件,通过随机选择有限个数据聚合条件进行聚合。这在数据聚合条件满足某些分布条件下,在提供相当准确的聚合结果的同时降低了计算资源的使用。

  • 自适应的Join算法

  • 数据复制和完整性支持:ClickHouse使用异步的多主复制技术。当数据被写入任何一个可用副本后,系统会在后台将数据分发给其他副本,以保证系统在不同副本上保持相同的数据。在大多数情况下ClickHouse能在故障后自动恢复,在一些少数的复杂情况下需要手动恢复。

  • 基于角色的访问控制

  • 可视为缺点的feature

    • 没有完整的事务支持。
    • 缺少高频率,低延迟的修改或删除已存在数据的能力。仅能用于批量删除或修改数据,但这符合 GDPR
    • 稀疏索引使得ClickHouse不适合通过其键检索单行的点查询。

二、性能

描述

根据官方文档说法

  • 单个查询的吞吐量,提取一个10字节的列,处理速度大概是1-2亿行每秒
  • 普通短查询正常小于50ms

另外值得注意的是

  • 写入性能最好是批量写入,每次不少于1000行或者一秒一次插入。
  • 写入的数据每行为1Kb,那么写入的速度为50,000到200,000行每秒(我实际业务测试时,单机十四万行插入为2秒多)
  • 并发查询不要超过100/s

为啥这么快

看列式数据库的特征和clickhouse本身feature就大概知道了,列式存储加上压缩,减少读取数据,更少的IO,相同查询占用更少内存(成本也更低)。同时支持并发处理,clickhouse本身对于压缩和数据向量并行处理又做了优化,能更好地利用CPU,多核并行处理。

三、备注

以上基本就是自己扫一遍clickhouse官方文档的特性,理解一下列式数据库和clickhouse特性实际上大概做了什么事情。有啥问题欢迎指正~

参考