Clickhouse架构及应用

内容大纲:node

  1. 背景;
  2. Clickhouse介绍;
  3. Clickhouse架构及性能;
  4. Clickhouse在好将来的实践;
  5. 建设与规划;
  6. 参考文献。

背景

在日志中心发展早期,日志检索分析主要基于elasticsearch进行,随着日志中心接入的业务愈来愈多,数据量也逐渐增加,基于日志进行分析和监控告警的需求变得愈来愈复杂,很难用elasticsearch来知足,因此须要根据需求场景来选择合适数据库。咱们须要的:mysql

  • 数据量会很大,所以须要分布式;
  • 支持实时写入,支持快速计算,在较短期内能完成计算;
  • 强大的sql能力,实时指标sql化;
  • 人力有限,运维须要简单;
  • 高效的压缩比存储,服务器有限,能够用更少的服务器存储更多的数据;

基于以上特色,咱们选择了Clickhouse,接下来会介绍Clickhouse的特色、系统架构以及使用状况。sql

Clickhouse介绍

一、Clickhouse特色

图2-1 Clickhouse特色图数据库

能够看到,Clickhouse的特色恰是咱们所须要的。接下来详细的介绍一下核心特性:设计模式

1)完备的DBMS功能:数组

ClickHouse拥有完备的管理功能,因此它称得上是一个DBMS ( Database Management System,数据库管理系统 ),而不只是一个数据库。缓存

做为一个DBMS,它具有了一些基本功能,如:安全

  • DDL ( 数据定义语言 ):能够动态地建立、修改或删除数据库、表和视图,而无须重启服务;
  • DML ( 数据操做语言 ):能够动态查询、插入、修改或删除数据;
  • 权限控制:能够按照用户粒度设置数据库或者表的操做权限,保障数据的安全性;
  • 数据备份与恢复:提供了数据备份导出与导入恢复机制,知足生产环境的要求;
  • 分布式管理:提供集群模式,可以自动管理多个数据库节点。

2) 列式存储与数据压缩服务器

列式存储和数据压缩,对于一款高性能数据库来讲是必不可少的特性。想让查询变得更快,最简单且有效的方法是减小数据扫描范围和数据传输时的大小,而列式存储和数据压缩就能够帮助咱们实现上述两点。因为Clickhouse是真正意义上的列式存储,每一列都在不一样的文件下,因此该文件数据类型一致,能够更有效的压缩。网络

3) 向量化执行引擎

向量化执行以列存为前提,主要思想是每次从磁盘上读取一批列,这些列以数组形式组织。每次next都经过for循环处理列数组。这么作能够大幅减小next的调用次数。相应的CPU的利用率获得了提升,另外数据被组织在一块儿。

能够进一步利用CPU硬件的特性,如SIMD,将全部数据加载到CPU的缓存当中去,提升缓存命中率,提高效率。在列存储与向量化执行引擎的双重优化下,查询执行的速度会有一个很是巨大的飞跃。

4) 关系模型与SQL查询

ClickHouse是一个关系型数据库。它几乎能够支持近百分之九十的sql做为查询语句,好比group by,order by等。

5) 多样化的表引擎

ClickHouse和mysql同样,也将存储部分进行了抽象,把存储引擎做为一层独立的接口。因此说Clickhouse实现了不少种表引擎,好比mergetree,log,memory等类型的引擎,每一种表引擎都有着各自的特色,用户能够根据实际业务场景的要求,选择合适的表引擎使用。

6) 多线程与分布式
ClickHouse几乎具有现代化高性能数据库的全部典型特征,对于能够提高性能的手段可谓是一一用尽,对于多线程和分布式这类被普遍使用的技术,天然更是不在话下。

7) 多主架构

HDFS、Spark、HBase和Elasticsearch这类分布式系统,都采用了Master-Slave主从架构,由一个管控节点做为Leader统筹全局。而ClickHouse则因为它的集群架构和其余数据库不一样,这种架构使得它是一个多主架构。

8) 在线查询

ClickHouse采用了LSM树结构,因此使得Clickhouse的插入量能够很大。同时,Clickhouse的内部优化,使得在复杂查询的场景下,它也可以作到极快响应,且无须对数据进行任何预处理加工。达到了实时数仓的效果

9) 数据分片与分布式查询

Clickhouse拥有分布式能力,天然支持数据分片,数据分片是将数据进行横向切分,这是一种在面对海量数据的场景下,解决存储和查询瓶颈的有效手段。ClickHouse并不像其余分布式系统那样,拥有高度自动化的分片功能。ClickHouse提供了本地表 ( Local Table ) 与分布式表 ( Distributed Table ) 的概念。一张本地表等同于一份数据的分片。而分布式表自己不存储任何数据,它是本地表的访问代理,其做用相似分库中间件。借助分布式表,可以代理访问多个数据分片,从而实现分布式查询。

二、C****lickhouse常见应用场景

  • 电信行业用于存储数据和统计数据使用;
  • 新浪微博用于用户行为数据记录和分析工做;
  • 用于广告网络和RTB,电子商务的用户行为分析;
  • 日志分析;
  • 检测和遥感信息的挖掘;
  • 商业智能;
  • 网络游戏以及物联网的数据处理和价值数据分析;
  • 最大的应用来自于Yandex的统计分析服务Yandex.Metri ca。

Clickhouse架构及性能

Clickhouse的集群架构是和其余的数据集群有必定的区别,他的集群能力是表级别的,而咱们熟知的大数据体系,好比hadoop系列的集群都是服务级别的。例如,一个hdfs集群,全部文件都会切片、备份;而Clickhouse集群中,建表时也能够本身决定用不用,也就是说其实Clickhouse单节点就能存活。可能有其余的大数据经验的人对这种设计会有点奇怪,后面会从单机架构到集群架构,详细的去介绍。

=======================================================================================================================================================================================================

一、Clickhouse单机架构设计

官方介绍Clickhouse架构的资料比较匮乏,依据已有的经验结合外部资料,根据本身的理解还原Clickhouse的架构以下:


图3-1 clickhouse单机架构图

1)Parser与Interpreter

Parser和Interpreter是很是重要的两组接口:Parser分析器是将sql语句已递归的方式造成AST语法树的形式,而且不一样类型的sql都会调用不一样的parse实现类。而Interpreter解释器则负责解释AST,并进一步建立查询的执行管道。Interpreter解释器的做用就像Service服务层同样,起到串联整个查询过程的做用,它会根据解释器的类型,聚合它所须要的资源。首先它会解析AST对象;而后执行"业务逻辑" ( 例如分支判断、设置参数、调用接口等 );最终返回IBlock对象,以线程的形式创建起一个查询执行管道。

2)表引擎

表引擎是ClickHouse的一个显著特性,上文也有提到,clickhouse有不少种表引擎。不一样的表引擎由不一样的子类实现。表引擎是使用IStorage接口的,该接口定义了DDL ( 如ALTER、RENAME、OPTIMIZE和DROP等 ) 、read和write方法,它们分别负责数据的定义、查询与写入。

3)DataType

数据的序列化和反序列化工做由DataType负责。根据不一样的数据类型,IDataType接口会有不一样的实现类。DataType虽然会对数据进行正反序列化,可是它不会直接和内存或者磁盘作交互,而是转交给Column和Filed处理。

4)Column与Field

Column和Field是ClickHouse数据最基础的映射单元。做为一款百分之百的列式存储数据库,ClickHouse按列存储数据,内存中的一列数据由一个Column对象表示。Column对象分为接口和实现两个部分,在IColumn接口对象中,定义了对数据进行各类关系运算的方法,例如插入数据的insertRangeFrom和insertFrom方法、用于分页的cut,以及用于过滤的filter方法等。而这些方法的具体实现对象则根据数据类型的不一样,由相应的对象实现,例如ColumnString、ColumnArray和ColumnTuple等。在大多数场合,ClickHouse都会以整列的方式操做数据,但凡事也有例外。若是须要操做单个具体的数值 ( 也就是单列中的一行数据 ),则须要使用Field对象,Field对象表明一个单值。与Column对象的泛化设计思路不一样,Field对象使用了聚合的设计模式。在Field对象内部聚合了Null、UInt6四、String和Array等13种数据类型及相应的处理逻辑。

5)Block

ClickHouse内部的数据操做是面向Block对象进行的,而且采用了流的形式。虽然Column和Filed组成了数据的基本映射单元,但对应到实际操做,它们还缺乏了一些必要的信息,好比数据的类型及列的名称。因而ClickHouse设计了Block对象,Block对象能够看做数据表的子集。Block对象的本质是由数据对象、数据类型和列名称组成的三元组,即Column、DataType及列名称字符串。Column提供了数据的读取能力,而DataType知道如何正反序列化,因此Block在这些对象的基础之上实现了进一步的抽象和封装,从而简化了整个使用的过程,仅经过Block对象就能完成一系列的数据操做。在具体的实现过程当中,Block并无直接聚合Column和DataType对象,而是经过ColumnWith TypeAndName对象进行间接引用。

二、Clickhouse集群架构设计

Clickhouse是集群是经过配置clickhouse_remote_servers来管理集群的。在配置中,能够配置集群名字,集群所须要节点的信息,经过这些节点能够配置分片和副本机制。

简单的配置为例:

<yandex>
 <clickhouse_remote_servers>
 <cluster1>
 <shard>
 <internal_replication>true</internal_replication>
 <replica>
 <host>clickhouse-node1</host>
 <port>9000</port>
 </replica>
 <replica>
 <host>clickhouse-node2</host>
 <port>9001</port>
 </replica>
 </shard>
 <shard>
 <internal_replication>true</internal_replication>
 <replica>
 <host>clickhouse-node3</host>
 <port>9000</port>
 </replica>
 <replica>
 <host>clickhouse-node4</host>
 <port>9001</port>
 </replica>
 </shard>
 ...
 </cluster1>
 ...
 </clickhouse_remote_servers>
 ...
</yandex>

以上集群配置完以后,想要用到Clickhouse的集群能力,还须要使用Replicated_MergeTree+Distributed引擎,该引擎是"本地表 + 分布式表"的方式,所以能够实现多分片多副本;下面具体介绍下Replicated_MergeTree引擎和Distributed引擎。

1)Replicated*MergeTree引擎

首先须要介绍下MergeTree引擎,这也是Clickhouse存储数据的最核心引擎,以前所说的特色主要就是针对该引擎所描述的。MergeTree引擎则是在MergeTree基础上中扩展了一些功能引擎,包括支持ReplacingMergeTree,SummingMergeTree等等MergeTree家族引擎,详细了解可看官网mergetree引擎介绍,不带replication的MergeTree引擎均可以当作单机引擎,也就是说它们是在单节点上存在的。

而使用Replicated_MergeTree就是将MergeTree引擎的数据经过Zookeeper调节,达到副本的效果。好比上述配置中,咱们首先能够在cluster1中的每一个节点上建立Replicated_MergeTr ee表,经过配置文件,能够看到Clickhouse-node1和Clickho use-node2是在同一个shard里的,每一个shard标签里的replica就表明复制节点。这时咱们建立表时将两个副本指定在同一个zo okeeper目录下,那么写入到node1的数据会复制到node2,写入node2的数据会同步到node1,达到预计的复制效果。

到这里,每一个节点上的本地表已经完成,可是多个分片的数据如何进行汇总,则须要下面的Distributed引擎。

**2)**Distributed引擎

使用Distributed引擎的表自己不存储任何数据,但容许在多个服务器上进行分布式查询处理,读取是自动并行的。在读取期间,会使用远程服务器上的表索引(也就是咱们上述使用的Replicate d*MergeTree引擎)。

在读写数据时,若是使用Distributed表,能够按照配置文件配置的分片方案,从不一样分片(shard)中读写数据,作到数据分片的效果。好比咱们读取数据时,是经过Distributed引擎表读取,这个时候它会读取集群中的每一个分片的数据作汇总计算。注意,这一块会有深度分页的状况,有些sql能够先分散在每一个节点上执行完再在查询节点作结果聚合,而有些则没法作结果聚合,必须将全部数据同步到查询节点,由查询节点统一汇总,这种状况就须要根据具体的数据状况进行优化。


图3-2 本地表加分布式表的查询流程图

图3-2是一个2分片2副本的架构,使用的是Replicated*Merge Tree + Distributed引擎模式。红色的数字表明节点的话,也就是节点1和2互为副本,3和4互为副本。

图中events为Distributed引擎表,也叫分布式表;events_loc al为Replicated*MergeTree引擎表,也叫本地表。该图中,分布式表只在节点3中建立,线上环境通常会在每一个节点上都建立一个分布式表(不会消耗资源,由于分布式表不会存储数据)。

执行查询时,会访问一个节点的分布式表,该图中访问的是节点3中分布式表。而后分布式表会分别的读取2个分片的数据,在这里,它读取了节点3和节点2的本地表数据,这两个节点加在一块就是完整的数据。汇总查询后将结果(Result Set)返回。

三、Clickhouse性能

**1)插入:**单机100-150M/s的插入速度;

**2)查询:**单字段groupby没有索引,1亿数据查询须要2.324s。有索引下,查询时间为0.101秒。能够看到Clickhouse的查询速度是及其快的,市面上常见的数据库基本都达不到这种性能;

**3)其余:**并发,官网默认配置为100。因为是大数据分析数据库主要适用于olap场景,对并发支持略差多个大数据查询可能会直接将cpu等资源占满,故并发实际达不到100。

Clickhouse在好将来的实践


图4-1 clickhouse线上架构图

一、业务场景

目前在好将来除了咱们部门,在其余部门也已经有了多个业务方。

1) 本部门

使用平台:日志中心,猫头鹰,土拨鼠,grafana等。

使用方式:咱们将须要的数据经过flink,spark,gohangout等工具消费kakfa,写入clickhouse,而后经过clickhouse作聚合查询,将数据展现出来。

好比,土拨鼠主要是经过网关数据作的聚合,能够看到各个域名,url或者服务器的调用次数,请求耗时等状况。再好比直播数据则是消费直播上报日志,用grafana将数据展现出来。

2) 其余部门

除了在本部门,还有其余业务方,数据研发部,数据中台等也都在使用,数据研发部主要会将hive中的热点数据经过spark/dataX同步至Clickhouse。而后将数据经过天枢天璇等平台展现给分析师使用,提升了查询速度。


图4-2:clickhouse使用图

二、存储现状


图4-3 单节点数据存储状况

以上数据第一列为库名,第二列为行数,第三列为压缩前大小,第四列为压缩后大小。

能够看到单个节点已有多个达到TB级别和百亿级别行数的数据库。目前数据节点是6个,也就是说在集群中,数据量须要再乘以6,表明有个别库库行数已达到千亿行,容量达到百T级别。

建设与规划

一、监控

Clickhouse官方目前没有提供直接的监控界面,可是所须要的监控数据在system库中都会记录下来,网上已有人经过grafana展现出来,目前的监控图如图5-1所示。

图5-1 clickhouse监控图

除此以外,还写了脚本,按期的对每一个节点的探活及故障重启。同时也使用神树平台查看各个节点的硬件信息及告警。

二、遇到的问题

Clickhouse做为olap数据库,在使用过程当中或多或少会出现一些问题,例如版本bug,使用不规范,混部出现的问题等,如今主要介绍几个须要持续优化或者业务配合的问题。其余遇到的一些问题也会在wiki上持续更新:

1) 大量查询致使服务器负载高状况,影响业务查询

**分析:**多个复杂查询,而且命中数据量极大的状况下。每一个查询都会占用大量的cpu和内存。会致使服务器负载被打满的状况。尤为是内存被打满,会形成节点挂掉的现象。
解决:

  • 用户限制,避免内存被打满,能够配置max_memory_us age_ for_all_queries,使其低于服务器实际内存。而且还能够限制用户的并发,每次查询的数据量等;
  • 某些业务下没法限制查询数据量,能够添加缓存机制,避免大量大数据查询。

2) ddl语句卡死

分析:Clickhouse主要支持的是追加及查询,可是使用mergetr ee引擎的表,是能够作update和delete的。更新和删除操做是用alter table语句的,也就是说其实这是须要ddl的权限的。每一次这种操做,数据库都会发生加锁,更新表等操做,而且数据量大的状况下,作更新操做,整个数据都会根据索引状况从新排序,这是一个漫长的过程。Clickhouse的ddl语句底层应该是个队列,一个没执行完,也会致使其余ddl卡住。

**解决:**尽可能减小ddl语句的执行频率以及增长执行间隔,或者尽可能不要执行。

3) zookeeper失联

**分析:**Clickhouse集群方案很依赖zk,副本同步机制都是依赖zk的,致使每次插入数据都会和zk作交互,而且在zk中作写操做,插入并发高的状况下,可能会致使zk暂时失联。

**解决:**以前zookeeper是和Clickhouse混部,后期作了拆分,状况有一部分好转。可是目前依然会偶尔出现问题,后续会继续对这块优化,zookeeper的服务器性能也会去尽可能完善,申请高配服务器,提升zookeeper的性能,使得不会由于zookeeper性能而影响到Clickhouse。

三、将来规划

想要打造一个高性能高稳定的大数据场景数据库,须要的是持续不断地学习以及和业务方的配合。

  • 深刻了解业务,根据业务场景建表;
  • 持续学习clickhouse,根据clickhouse特性优化sql;
  • 同时也须要业务方配合,若是大查询频率较高,能够考虑使用缓存等机制,或者特定场景可使用近似计算。同时特殊场景特殊对待,实现合适的sql;
  • 数据持续增加,查询压力也是愈来愈大,进行集群之间的隔离,使其重要业务之间不会互相影响;
  • 持续完善监控和告警机制;
  • clickhouse还有不少强大的功能,将来也会去尝试使用。

参考文献

[1]https://clickhouse.tech/docs
[2]https://blog.csdn.net/tzs_104...
[3]https://www.jianshu.com/p/ab8..

相关文章
相关标签/搜索