ClickHouse全称是Click Stream,Data Warehouse,简称ClickHouse就是基于页面的点击事件流,面向数据仓库进行OLAP分析。ClickHouse是一款开源的数据分析数据库,由战斗民族俄罗斯Yandex公司研发的,Yandex是做搜索引擎的,就类似与Google,百度等。
我们都知道搜索引擎的营收主要来源与流量和广告业务,所以搜索引擎公司会着重分析用户网路流量,像Google有Anlytics,百度有百度统计,那么Yandex就对应于Yandex.Metrica。ClickHouse就式在Yandex.Metrica下产生的技术
根据官网介绍,我们看看和其他数据库的性能比较
在相同的服务器配置与数据量下,平均响应速度:
详情可在以下网址看到:
https://clickhouse.tech/benchmark/dbms/
支持大规模并行计算,每个节点存有对应的分区数据
DDL,DML,权限控制,数据备份与恢复,分布式管理
某些面向列的DBMS不使用数据压缩。但是,数据压缩在实现出色性能方面确实起着关键作用,除了在磁盘空间和CPU消耗之间权衡取舍的高效通用压缩编解码器之外,ClickHouse还为特定类型的数据提供了专门的编解码器,这使ClickHouse可以与时序数据库等可以一起相提并论,并且表现出色。
编解码器详情见此链接:https://clickhouse.tech/docs/en/sql-reference/statements/create/table/#create-query-specialized-codecs
向量化执行就是利用CPU的SIMD命令,即用单条指令操作多条数据,通过数据并行来提高性能,原理就是在CPU寄存器层面实现数据的并行操作。
提供传统数据库的概念,如数据库、表、视图和函数等。ClickHouse完全可以使用SQL作为查询语言,让每个人都可以轻松用上大数据。
表引擎是ClickHouse其中一个重要的特性,拥有合并树、内存、文件、接口和其他6大类等20多种引擎,满足我们生产中的不同场景,选择合适的引擎。
Hadoop生态,如HDFS,YARN都采用了Master-Slabe主从架构,由一个主节点统筹全局。而ClickHouse则采用Multi-Master多主架构,集群中每个角色对等,客户端访问任意一个节点都能得到相同的效果
复杂查询能做到极快响应,可能有人说ElasticSearch表示不服,但是要知道,在处理亿级数据时,ElasticSearch会显得力不从心
支持分片,将数据横向切分,解决存储和查询的瓶颈。每个集群由1到多个分片组成,而每个分片则对应ClickHouse 的1太服务器节点。
ClickHouse提供本地表(Local Table)和分布式表(Distribute Table)的概念:
一张本地表等同于一份数据分片,而分布式表只是一个逻辑概念,它不存储任何数据,它是本地表的访问代理,作用类似分库中间件。
ClickHouse的数据流架构由几个部分组成
下面就给大家一个一个介绍一下
Column和Field是ClickHouse数据最基础的映射单元。ClickHouse按列存储数据,内存中的一列数据由一个Column对象表示。在大多数情况下,ClickHouse都会以整列的方式操作数据,但如果需要操作某列的单值,这时候就要用到Field对象,Filed对象代表一个单值。
Filed会有不同的聚合方式,如UInt64,String和Array等,这些聚合方式都是ClickHouse实现高性能的重要细节,在后面我们会专门讲解ClickHouse聚合的原理。
前面讲了Column和Filed是ClickHouse数据最基础的映射单元。但它们仅仅负责数据的读取操作,并不包含数据的类型和列名。因此在Column和Field上层又做了一层封装,叫做Block对象。因此我们可以说ClickHouse内部的数据操作是面向Block对象进行的,Block对象可以看作是数据表的子集。
数据的类型是由DataType负责,包括数据的序列化与反序列化,数据从Column或者Field获取。
总的来说Block对象的本质是由数据对象(Column)、数据类型(DataType)和列名称组成的三元组。Column提供数据的读取能力,DataType提供序列化和反序列化,Block在这些对象的基础上实现了进一步的抽象和封装,从而简化了整个使用的过程,仅通过Block就可完成一系列数据操作。
ClickHouse主要提供两类函数:普通函数和聚合函数
普通函数由IFunction接口定义,内部由很多的函数实现,如FunctionFormatDateTime,FunctionSubstring等。普通函数是没有状态的,从执行效果上看,我们看到的是每行作用的效果,但是在执行的过程中,是采用向量化的方式直接作用到一整列数据中。
聚合函数是有状态的,由IAggregateFunction接口定义,聚合函数是有状态的。聚合函数的状态支持序列化和反序列化,所以能够在分布式节点之间进行传输,从而实现增量计算。
ClickHouse底层由不同的表引擎组成,不同的表引擎由不同的子类实现,例如IStorageSystemOneBlock(系统表引擎),StorageMergeTree(合并树表引擎)和StorageTinyLog(日志表引擎)等。
IStorage接口定了DDL(如alter、rename、drop等)、read和write方法,分别负责数据的定义、查询与写入。在数据查询时,IStorage负责根据AST(抽象语法树)查询语句的要求,返回指定列的原始数据。
Parser和Intercepter是非常重要的两组接口。Parser分析器负责创建AST对象;
Intercepter解释器负责解释AST,并进一步创建查询的执行管道。它们与IStorage一起串联了整个数据查询过程。
服务器实现了多个不同的接口:
ClickHouse会让硬件的功效最大化,例如group by操作直接在内存中进行,并且使用HashTable装在数据,充分利用CPU的L3级别缓存。
出色查询性能当然离不开出色的算法,ClickHouse的底层实现中,经常面对一些应用场景,如字符串查询、数组排序等,选择合适的算法,才是实现性能最大化。
在字符串搜索方面,ClickHouse针对不同的应用场景,选择不同的算法:
针对同一应用场景的不同情况下,可以选择不同的实现方式,尽可能将性能最大化。例如去重计树函数uniqCombined函数,会根据数据量的不同选择不同的数据结构:
可以看出ClickHouse为了做到高性能是从很多方面去考虑的,如存储方式、压缩方式、向量化执行引擎、表引擎、算法等等,要想充分的掌握它就必须理解它实现的方式及原理,今天的介绍就到这里,下一篇将带大家一起动手搭ClickHouse集群。