1. MPP架构
2. 完备的DBMS功能
3. 列式存储和数据压缩
同一个列的数据类型相同,相似度较高,相比行式存储压缩效率更高。
4. 向量化执行引擎
向量化执行,就是利用寄存器硬件层面的特性,为上层应用程序的性能带来指数级的提升。为了实现向量化执行,需要利用CPU的SIMD(Single Instruction Multiple Data,即单挑指令操作多条数据)命令,它通过数据并行来提高性能,原理就是CPU寄存器层面实现数据的并行操作。
5. 支持sql查询
使用关系型模型描述数据,类似传统数据库概念,如数据库、表、视图、函数等。
6. 支持多种表引擎(类似MySql)
将存储引擎部分进行抽象,把存储引擎作为一层独立的接口,与MySql类似。
目前有合并树、内存、日志、接口、外部存储和其他 6大类20多种表引擎,可以根据实际场景进行选择
7. 多线程、分布式
向量化执行是通过数据级并行的方式提升性能,多线程处理是通过线程并行的方式实现性能提升。
ClickHouse在数据存取方面,既支持分区(纵向扩展,增加分区,利用多线程技术),也支持分片(横向扩展,增加节点,利用分布式技术)。
8. 多主架构
Hadoop生态系统技术都采用了Master-Slave主从架构,而ClickHouse则采用Multi-Master多主架构,集群中每个节点角色对等,客户端访问任意一个节点都能达到相同的效果。
9. 支持实时查询
即使是复杂查询的场景,也能做到极快响应,且无需对数据进行预加工处理,ClickHouse优势明显:
10. 支持分布式查询
Column和Field是ClickHouse数据最基础的映射单元。ClickHouse按列存储数据,内存中一列数据由一个Column对象表示。大多数情况下,ClickHouse都会以整列的方式操作数据,如果操作某列具体的数值,则需要使用Field对象,即Field对象代表一个值。
Column对象采用泛华设计思路,对象分为接口和实现两部分。接口定义对数据进行各种运算的方法;在IColumn接口对象中,定义了对数据进行各种关系运算的方法,如插入数据、分页、过滤等。
Field对象使用聚合的设计模式,在Field对象内部聚合了Null、UInt64、String和Array等13种数据类型及相应的处理逻辑。
DataType负责数据的序列化和反序列化,但是不负责数据的读取,数据通过Column和Field对象读取。IDataType接口定义的方法,及相应的接口对象,其中序列化和反序列化接口成对出现,可以覆盖二进制、文本、JSON、XML、CSV、Protobuf等多种格式类型。
虽然Column和Field组成了数据的基本映射单元,但是实际操作中,还缺少了一些必要信息,如数据的类型和列名称,于是ClockHouse设计了Block对象,Block对象可以看作是数据表的子集。
Block对象的本质是由数据对象(Column)、数据类型(DataType)和列名称组成,Column提供数据的读取能力,DataType提供数据的序列化和反序列化的能力,Block在他们的基础上做进一步的抽象和封装,仅通过Block对象就可以完成一系列的操作。
Block流基于Block,其操作有两组顶层接口:
底层设计中并没有所谓的Table对象,它直接使用IStorage接口指代数据表。
IStorage接口定义了DDL、read、write方法,分别负责数据的定义、查询和写入。在数据查询时,IStorage负责根据AST(抽象语法树)查询语句的要求,返回指定列的原始数据,然后交给Interpreter做进一步处理。
表引擎是ClickHouse的一个显著特性,IStorage接口指代数据表,因此不同的表引擎对应的有不同的IStorage子类实现,如IStorageSystemOneBlock、StorageMergeTree等。
Parser - 分析器,负责创建AST抽象语法树对象;
Interpreter - 解释器,负责解释AST,并创建下一步查询的执行管道。
它们与IStorage一起串联整个数据查询过程。IStorage负责根据AST的指示要求,返回指定的原始数据,通过Block对象完成一系列的操作。
ClickHouse主要提供两类函数:普通函数和聚合函数。
普通函数由IFunction接口定义,主要做一些数据转换之类的操作;
聚合函数由IAggregateFunction接口定义,聚合函数有状态,而且其状态支持序列化和反序列化,能够在分布式节点之间传输,从而实现增量运算。