ClickHouse调研与架构介绍

1. ClickHouse是啥?

是用于联机分析(OLAP)的列式数据库管理系统(DBMS)

2. 啥是列式数据库?

常见的行式数据库系统有: MySQL、Postgres和MS SQL Server。将同一列的数据存储在一起,不同列的数据也总是分开存储的数据库是列式数据库。常见的列式数据库有: Vertica、 Paraccel (Actian Matrix,Amazon Redshift)、 Sybase IQ、 Exasol、 Infobright、 InfiniDB、 MonetDB (VectorWise, Actian Vector)、 LucidDB、 SAP HANA、 Google Dremel、 Google PowerDrill、 Druid、 kdb+。

3.olap有啥关键特征?应用于哪些场景

  • 大多数是读请求
  • 数据总是以相当大的批(> 1000 rows)进行写入
  • 不修改已添加的数据
  • 每次查询都从数据库中读取大量的行,但是同时又仅需要少量的列
  • 宽表,即每个表包含着大量的列
  • 较少的查询(通常每台服务器每秒数百个查询或更少)
  • 对于简单查询,允许延迟大约50毫秒
  • 列中的数据相对较小: 数字和短字符串(例如,每个URL 60个字节)
  • 处理单个查询时需要高吞吐量(每个服务器每秒高达数十亿行)
  • 事务不是必须的
  • 对数据一致性要求低
  • 每一个查询除了一个大表外都很小
  • 查询结果明显小于源数据,换句话说,数据被过滤或聚合后能够被盛放在单台服务器的内存中

4.为啥列式数据库更适合OLAP?

输入输出方面:

  1. 针对分析类查询,通常只需要读取表的一小部分列。在列式数据库中你可以只读取你需要的数据。例如,如果只需要读取100列中的5列,这将帮助你最少减少20倍的I/O消耗。
  2. 由于数据总是打包成批量读取的,所以压缩是非常容易的。同时数据按列分别存储这也更容易压缩。这进一步降低了I/O的体积。
  3. 由于I/O的降低,这将帮助更多的数据被系统缓存。

cpu方面:

      由于执行一个查询需要处理大量的行,因此在整个向量上执行所有操作将比在每一行上执行所有操作更加高效。同时这将有助于实现一个几乎没有调用成本的查询引擎。如果你不这样做,使用任何一个机械硬盘,查询引擎都不可避免的停止CPU进行等待。所以,在数据按列存储并且按列执行是很有意义的。

5.clickhouse有哪些特性?

  1. 真正的列式数据库管理系统
  2. 使用了数据压缩
  3. 除了内存还可以存储在传统磁盘上
  4. 可以多核心并行
  5. 可以支持分布式查询
  6. 与SQL标准兼容,支持的查询包括 GROUP BY,ORDER BY,IN,JOIN以及非相关子查询
  7. 向量引擎。数据不仅仅按列存储,同时还按向量(列的一部分)进行处理,更加高效地使用CPU。
  8. 实时数据更新,数据增量有序存储,写入不加锁
  9. 支持索引,按照主键排序
  10. 支持在线查询,不需要预处理
  11. 支持近似计算,ClickHouse提供各种各样在允许牺牲数据精度的情况下对查询进行加速的方法:
    • 用于近似计算的各类聚合函数,如:distinct values, medians, quantiles
    • 基于数据的部分样本进行近似查询。这时,仅会从磁盘检索少部分比例的数据。
    • 不使用全部的聚合条件,通过随机选择有限个数据聚合条件进行聚合。这在数据聚合条件满足某些分布条件下,在提供相当准确的聚合结果的同时降低了计算资源的使用。
  12. 支持数据复制和完整性,采用异步复制,将某一副本的数据赋值给其他副本,保证和数据相同,大多数情况下ClickHouse能在故障后自动恢复,在一些少数的复杂情况下需要手动恢复。

6.clickhouse的限制?

  1. 没有事务支持
  2. 不支持高频率低延迟修改和删除,仅能用于批量删除或修改数据
  3. 稀疏索引使得ClickHouse不适合通过其键检索单行的点查询

7.clickhouse的性能如何?

从clickhouse给的结果来看,clickhouse非常优秀,但是不能从一方的来看,clickhouse的sql兼容性没有Greenplum或tidb好,clickhouse有独有的SQL标准,特别是一些方便olap的查询函数。很多团队,在做老job迁移时,需要对SQL进行一定程度的改造。

单个大查询吞吐量 数据在page cache中 简单查询 单服务器30GB/s
不太复杂查询 单服务器2-10GB/s
数据在磁盘中

磁盘读:400MB/s

压缩率:3

单服务器1.2GB/s
查询延迟时间 使用主键并且数据被缓存 小于50毫秒(在最佳的情况下应该小于10毫秒)
其他情况

查找时间(10 ms) * 查询的列的数量 * 查询的数据块的数量

查询的吞吐量 ClickHouse可以在单个服务器上每秒处理数百个查询(在最佳的情况下最多可以处理数千个)。但是由于这不适用于分析型场景。因此我们建议每秒最多查询100次。
数据写入性能 建议不少于1000行的批量写入,或每秒不超过一个写入请求

写入速度大约为50到200MB/s,可以使用多个INSERT进行并行写入

8.clickhouse为啥这么快??

(回答来自:https://blog.csdn.net/wenyusuran/article/details/107832079)

着眼硬件,先想后做

基于将硬件功效最大化的目的,ClickHouse会在内存中进行GROUP BY,并且使用HashTable装载数据。与此同时,他们非常在意CPU L3级别的缓存,因为一次L3的缓存失效会带来70~100ns的延迟。这意味着在单核CPU上,它会浪费4000万次/秒的运算;而在一个32线程的CPU上,则可能会浪费5亿次/秒的运算。所以别小看这些细节,一点一滴地将它们累加起来,数据是非常可观的。正因为注意了这些细节,所以ClickHouse在基准查询中能做到1.75亿次/秒的数据扫描性能。

算法在前,抽象在后

性能是ClickHouse算法选择的首要考量指标。

勇于尝鲜,不行就换

如果世面上出现了号称性能强大的新算法,ClickHouse团队会立即将其纳入并进行验证。行就用,不行就不用。

特定场景,特殊优化

ClickHouse会针对不同场景使用最合适、最快的算法。针对同一个场景的不同状况,选择使用不同的实现方式,尽可能将性能最大化。

持续测试,持续改进

由于Yandex的天然优势,ClickHouse经常会使用真实的数据进行测试,这一点很好地保证了测试场景的真实性。ClickHouse差不多每个月都能发布一个版本。

9.ClickHouse 架构设计

(回答来自:https://blog.csdn.net/wenyusuran/article/details/107832079)

ClickHouse公开的资料相对匮乏,比如在架构设计层面就很难找到完整的资料,甚至连一张整体的架构图都没有。

ClickHouse调研与架构介绍_第1张图片

(这张彩的不是官方的,是我自己根据他的描述画的)

1.Column与Field

Column和Field是ClickHouse数据最基础的映射单元。内存中的一列数据由一个Column对象表示。

Column对象分为接口和实现两个部分,在IColumn接口对象中,定义了对数据进行各种关系运算的方法。

在大多数场合,ClickHouse都会以整列的方式操作数据,但凡事也有例外。如果需要操作单个具体的数值 ( 也就是单列中的一行数据 ),则需要使用Field对象,Field对象代表一个单值。

与Column对象的泛化设计思路不同,Field对象使用了聚合的设计模式。在Field对象内部聚合了Null、UInt64、String和Array等13种数据类型及相应的处理逻辑。

2.DataType

数据的序列化和反序列化工作由DataType负责。IDataType接口定义了许多正反序列化的方法,它们成对出现。IDataType也使用了泛化的设计模式,具体方法的实现逻辑由对应数据类型的实例承载。

DataType虽然负责序列化相关工作,但它并不直接负责数据的读取,而是转由从Column或Field对象获取。

3.Block与Block流

ClickHouse内部的数据操作是面向Block对象进行的,并且采用了流的形式。Block对象可以看作数据表的子集。

Block对象的本质是由数据对象、数据类型和列名称组成的三元组,即Column、DataType及列名称字符串。仅通过Block对象就能完成一系列的数据操作。

Block并没有直接聚合Column和DataType对象,而是通过ColumnWithTypeAndName对象进行间接引用。

Block流操作有两组顶层接口:IBlockInputStream负责数据的读取和关系运算,IBlockOutputStream负责将数据输出到下一环节。

IBlockInputStream接口定义了读取数据的若干个read虚方法,而具体的实现逻辑则交由它的实现类来填充。IBlockInputStream接口总共有60多个实现类,这些实现类大致可以分为三类:

  • 第一类用于处理数据定义的DDL操作
  • 第二类用于处理关系运算的相关操作
  • 第三类则是与表引擎呼应,每一种表引擎都拥有与之对应的BlockInputStream实现

IBlockOutputStream的设计与IBlockInputStream如出一辙。这些实现类基本用于表引擎的相关处理,负责将数据写入下一环节或者最终目的地。

4.Table

在数据表的底层设计中并没有所谓的Table对象,它直接使用IStorage接口指代数据表。表引擎是ClickHouse的一个显著特性,不同的表引擎由不同的子类实现。

IStorage接口负责数据的定义、查询与写入。IStorage负责根据AST查询语句的指示要求,返回指定列的原始数据。后续的加工、计算和过滤则由下面介绍的部分进行。

5.Parser与Interpreter

Parser分析器负责创建AST对象;而Interpreter解释器则负责解释AST,并进一步创建查询的执行管道。它们与IStorage一起,串联起了整个数据查询的过程。

Parser分析器可以将一条SQL语句以递归下降的方法解析成AST语法树的形式。不同的SQL语句,会经由不同的Parser实现类解析。

Interpreter解释器的作用就像Service服务层一样,起到串联整个查询过程的作用,它会根据解释器的类型,聚合它所需要的资源。首先它会解析AST对象;然后执行"业务逻辑" ( 例如分支判断、设置参数、调用接口等 );最终返回IBlock对象,以线程的形式建立起一个查询执行管道。

6.Functions 与Aggregate Functions

ClickHouse主要提供两类函数—普通函数(Functions)和聚合函数(Aggregate Functions)。

普通函数由IFunction接口定义,拥有数十种函数实现,采用向量化的方式直接作用于一整列数据。

聚合函数由IAggregateFunction接口定义,相比无状态的普通函数,聚合函数是有状态的。以COUNT聚合函数为例,其AggregateFunctionCount的状态使用整型UInt64记录。聚合函数的状态支持序列化与反序列化,所以能够在分布式节点之间进行传输,以实现增量计算。

7.Cluster与Replication

ClickHouse的集群由分片 ( Shard ) 组成,而每个分片又通过副本 ( Replica ) 组成。这种分层的概念,在一些流行的分布式系统中十分普遍。这里有几个与众不同的特性。

  • ClickHouse的1个节点只能拥有1个分片,也就是说如果要实现1分片、1副本,则至少需要部署2个服务节点。

  • 分片只是一个逻辑概念,其物理承载还是由副本承担的。

你可能感兴趣的:(数据库架构,数据库,olap)