浅谈ChickHouse架构设计

Posted 数据之其然

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈ChickHouse架构设计相关的知识,希望对你有一定的参考价值。

整体架构设计主要有:Column与Field、DataType、、BloCK与BloCK流、Table、Parser与Interpreter、分片与副本等


1、Column与Field

1.1、概述:   

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


1.2、Column对象:

(1)IColumn接口,定义了对数据进行各种关系运算的方法。比如:插入数据的insertRangeFrom和insertFrom方法、用于分页的cut、用于过滤的filter方法等

(2)这些方法的具体实现对象则根据数据类型的不同,由相应的对象实现,比如:ColumnString、ColumnArray、ColumnTuple


1.3、ClickHouse如何操作?若想操作单个值呢?

(1)ClickHouse都会以整列的方式操作数据

(2)如果需要操作单个具体的数值 ( 也就是单列中的一行数据 ),则需要使用Field对象

(3)Field对象代表一个单值


1.4、Field对象的泛化设计思路是怎样的?

(1)使用了聚合的设计模式

(2)在Field对象内部聚合了Null、UInt64、String和Array等13种数据类型注意:  一个列中的数据一般是以文件单独存储的及相应的处理逻辑



2、DataType

2.1、DataType负责哪一块?

数据的序列化、反序列化


2.2、IDataType接口有哪些方法、类型?

DataType接口定义了许多正反序列化的方法,比如:serializeBinary、deserializeBinary、serializeTextJSON、deserializeTextJSON等

类型有:常用的二进制、文本、JSON、XML、CSV、Protobuf等


2.3、IDataType会运用到设计模式的哪些方法?

(1)IDataType也使用了泛化的设计模式

(2)具体方法的实现逻辑由对应数据类型的实例承载

比如:DataTypeString、DataTypeArray、DataTypeTuple



3、BloCK与BloCK流

3.1、ClickHouse内部的数据是如何操作?

是面向BloCK对象进行的,并且采用了流的形式


3.2、Block对象与Column、Field对象的区别?

Column、Field对象:

(1)Column和Filed组成了数据的基本映射单元

(2)但对应到实际操作,它们还缺少了一些必要的信息,比如数据的类型及列的名称


Block对象(弥补Column、Field对象的不足):

(1)ClickHouse设计了BloCK对象,BloCK对象可以看作数据表的子集

(2)BloCK对象的本质是由三元组组成的,分别是:

元组名称
解释
说明
数据对象(Column) Column提供了数据的读取能力



数据类型(DataType) DataType知道如何正反序列化,所以BloCK在这些对象的基础之上实现了进一步的抽象和封装,从而简化了整个使用的过程, 仅通过BloCK对象就能完成一系列的数据操作



列名称(列名称字符串)


3.2、具体实现过程?

(1)BloCK并没有直接聚合Column和DataType对象,而是通过ColumnWithTypeAndName对象进行间接引用

(2)有了BloCK对象这一层封装之后,对BloCK流的设计就是水到渠成的事情了



3.3、BloCK流操作有两组顶层接口

IBloCKInputStream:负责数据的读取和关系运算

IBloCKOutputStream:负责将数据输出到下一环节


3.4、BloCK流为什么要使用了泛化的设计模式?如何定义?

(1)BloCK流使用了泛化的设计模式,对数据的各种操作最终都会转换成其中一种流的实现

(2)IBloCKInputStream接口定义了读取数据的若干个read虚方法,而具体的实现逻辑则交由它的实现类来填充

说明:IBloCKInputStream接口总共有60多个实现类,它们涵盖了ClickHouse数据摄取的方方面面


3.5、IBloCKInputStream接口实现类大致可以分为三类

类型
举例
第一类用于处理数据定义的DDL操作 例如DDLQueryStatusInputStream等


第二类用于处理关系运算的相关操作 例如LimitBloCKInput-Stream、JoinBloCKInputStream、AggregatingBloCKInputStream


第三类则是与表引擎呼应,每一种表引擎都拥有与之对应的BloCKInputStream实现 例如MergeTreeBaseSelect-BloCKInputStream ( MergeTree表引擎 )、TinyLogBloCKInputStream ( TinyLog表引擎 ) 、TinyLogBloCKInputStream ( TinyLog表引擎 ) 



3.6、IBloCKOutputStream的设计与IBloCKInputStream的区别?

接口名称
解释说明
IBloCKInputStream接口: 定义了若干写入数据的write虚方法


IBloCKOutputStream接口: 定义了若干写入数据的write虚方法

它的实现类比IBloCKInputStream要少许多,一共只有20多种

这些实现类基本用于表引擎的相关处理,负责将数据写入下一环节或者最终目的地


例如MergeTreeBloCKOutputStream 、TinyLogBloCKOutputStream、StorageFileBloCK-OutputStream等【IBloCKOutputStream接口】



4、Table

4.1、数据表的底层如何设计的?

数据表的底层设计中并没有所谓的Table对象,它直接使用IStorage接口指代数据表


4.2、ClickHouse表引擎的特性

不同的表引擎由不同的子类实现,比如:IStorageSystemOneBloCK ( 系统表 )、StorageMergeTree ( 合并树表引擎 )、StorageTinyLog ( 日志表引擎 ) 等


4.3、IStorage接口定义哪些方法?主要做哪一块?

IStorage接口定义的方法有:

ALTER、RENAME、OPTIMIZE、DROP、read方法、write方法


担任角色:负责数据的定义、查询、写入;比如查询:

(1)在数据查询时,IStorage负责根据AST查询语句的指示要求,返回指定列的原始数据

(2)后续对数据的进一步加工、计算和过滤,则会统一交由Interpreter解释器对象处理

注意:对Table发起的一次操作通常都会经历这样的过程,接收AST查询语句,根据AST返回指定列的数据,之后再将数据交由Interpreter做进一步处理




5、Parser与Interpreter

5.1、概述

Parser和Interpreter是非常重要的两组接口


5.2、Parser和Interpreter负责哪一块?

Parser分析器: 负责创建AST对象
Interpreter解释器: 负责解释AST,并进一步创建查询的执行管道

说明:它们与IStorage一起,串联起了整个数据查询的过程


5.3、Parser分析器与Interpreter解释器的作用?

Parser分析器的作用:

(1)可以将一条SQL语句以递归下降的方法解析成AST语法树的形式;

(2)不同的SQL语句,会经由不同的Parser实现类解析;

例如,如下表:

有负责解析DDL查询语句 ParserRenameQuery

ParserDropQuery

ParserAlterQuery解析器


有负责解析INSERT语句 ParserInsertQuery解析器


有负责SELECT语句 ParserSelectQuery


Interpreter解释器的作用:

官网解释:

就像Service服务层一样,起到串联整个查询过程的作用,它会根据解释器的类型,聚合它所需要的资源

个人理解:

(1)首先它会解析AST对象

(2)然后执行'业务逻辑' ( 例如分支判断、设置参数、调用接口等 )

(3)最终返回IBloCK对象,以线程的形式建立起一个查询执行管道


6、分片与副本

6.1、如何理解分片与副本概念?

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

比如:在Elasticsearch的概念中,一个索引由分片和副本组成,副本可以看作一种特殊的分片。

如果一个索引由5个分片组成,副本的基数是1,那么这个索引一共会拥有10个分片 ( 每1个分片对应1个副本 );

如果你用同样的思路来理解ClickHouse的分片,那么很可能会在这里栽个跟头;

ClickHouse的某些设计总是显得独树一帜,而集群与分片就是其中之一


6.2、分片与副本的特性

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

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



知其所以然、知其所以必然,知其然而不知其所以然;蒙惠者虽知其然,而未必知其所以然;也这是我们从学习实践中得出的深切体会!分享完毕,谢谢!



以上是关于浅谈ChickHouse架构设计的主要内容,如果未能解决你的问题,请参考以下文章

浅谈敏捷开发中的架构设计!(干货)

阿里架构师:浅谈大型项目前端架构设计

浅谈大型项目前端架构设计

浅谈微服务架构设计

Mongodb架构设计浅谈

浅谈一下可扩展性网站架构设计